Make dynamic-bindings for each class.
[commonqt:commonqt.git] / commonqt.cpp
1 // -*- c-basic-offset: 8; indent-tabs: nil -*-
2 //
3 // See LICENSE for details.
4 //
5 #include <smoke.h>
6 #include <smoke/qtcore_smoke.h>
7 #include <QtCore>
8 #include <QtGui>
9 #include "commonqt.h"
10
11 // #define DEBUG 1
12
13 #include <iostream>
14 #include <string>
15 #include <stdlib.h>
16
17 using namespace std;
18
19 typedef void (*t_deletion_callback)(void*, void*);
20 typedef bool (*t_callmethod_callback)(void*, short, void*, void*, bool);
21 typedef void (*t_child_callback)(void*, bool, void*);
22
23 class Binding : public SmokeBinding
24 {
25 public:
26         Binding(Smoke* s) : SmokeBinding(s) {}
27
28         t_deletion_callback deletion_callback;
29         t_callmethod_callback callmethod_callback;
30         t_child_callback child_callback;
31
32         void deleted(Smoke::Index, void* obj) {
33                 deletion_callback(smoke, obj);
34         }
35
36         bool callMethod(Smoke::Index method, void* obj,
37                 Smoke::Stack args, bool isAbstract)
38         {
39                 Smoke::Method* m = &smoke->methods[method];
40                 const char* name = smoke->methodNames[m->name];
41                 Smoke::Class* c = &smoke->classes[m->classId];
42
43                 if (*name == '~')
44                         callmethod_callback(smoke, method, obj, args, isAbstract);
45                 else if (!strcmp(name, "notify")
46                          && (!strcmp(c->className, "QApplication")
47                             || !strcmp(c->className, "QCoreApplication")))
48                 {
49                         QEvent* e = (QEvent*) args[2].s_voidp;
50                         if (e->type() == QEvent::ChildAdded
51                             || e->type() == QEvent::ChildRemoved)
52                         {
53                                 QChildEvent* f = (QChildEvent*) e;
54                                 child_callback(smoke, f->added(), f->child());
55                         }
56                 }
57                 return false;
58         }
59
60         char* className(Smoke::Index classId) {
61                 return (char*) smoke->classes[classId].className;
62         }
63 };
64
65 class DynamicBinding : public Binding
66 {
67 public:
68         DynamicBinding(Smoke* s) : Binding(s) {}
69
70         QHash<short, bool> overridenMethods;
71         QMetaObject* metaObject;
72         short metaObjectIndex;
73
74         bool callMethod(Smoke::Index method, void* obj,
75                 Smoke::Stack args, bool isAbstract)
76         {
77                 if (method == metaObjectIndex) {
78                         args[0].s_voidp = (void*)metaObject;
79                         return true;
80                 }
81                 else if (overridenMethods[method]) {
82                         return callmethod_callback(smoke, method, obj, args, isAbstract);
83                 }
84                 else {
85                         return false;
86                 }
87         }
88 };
89
90 void
91 sw_smoke(Smoke* smoke,
92          SmokeData* data,
93          void* deletion_callback,
94          void* method_callback,
95          void* child_callback)
96 {
97         Binding* binding = new Binding(smoke);
98
99         data->name = smoke->moduleName();
100
101         data->classes = smoke->classes;
102         data->numClasses = smoke->numClasses;
103
104         data->methods = smoke->methods;
105         data->numMethods = smoke->numMethods;
106
107         data->methodMaps = smoke->methodMaps;
108         data->numMethodMaps = smoke->numMethodMaps;
109
110         data->methodNames = smoke->methodNames;
111         data->numMethodNames = smoke->numMethodNames;
112
113         data->types = smoke->types;
114         data->numTypes = smoke->numTypes;
115
116         data->inheritanceList = smoke->inheritanceList;
117         data->argumentList = smoke->argumentList;
118         data->ambiguousMethodList = smoke->ambiguousMethodList;
119         data->castFn = (void *) smoke->castFn;
120
121         binding->deletion_callback
122                 = (t_deletion_callback) deletion_callback;
123
124         binding->callmethod_callback
125                 = (t_callmethod_callback) method_callback;
126
127         binding->child_callback
128                 = (t_child_callback) child_callback;
129
130         data->binding = binding;
131 }
132
133 void sw_override(DynamicBinding* dynamicBinding, short method, bool override)
134 {
135         dynamicBinding->overridenMethods[method] = override;
136 }
137
138 void* sw_make_dynamic_binding(Smoke* smoke,
139                               QMetaObject* metaObject,
140                               short metaObjectIndex,
141                               void* deletion_callback,
142                               void* method_callback,
143                               void* child_callback) {
144         DynamicBinding* dynamicBinding = new DynamicBinding(smoke);
145
146         dynamicBinding->deletion_callback
147                 = (t_deletion_callback) deletion_callback;
148
149         dynamicBinding->callmethod_callback
150                 = (t_callmethod_callback) method_callback;
151
152         dynamicBinding->child_callback
153                 = (t_child_callback) child_callback;
154
155         dynamicBinding->metaObject = metaObject;
156         dynamicBinding->metaObjectIndex = metaObjectIndex;
157         return dynamicBinding;
158 }
159
160 int
161 sw_windows_version()
162 {
163 #ifdef WINDOWS
164         return QSysInfo::windowsVersion();
165 #else
166         return -1;
167 #endif
168 }
169
170 // void*
171 // sw_make_qstring(char *str)
172 // {
173 //         QString* qstr = new QString();
174 //         *qstr = QString::fromUtf8(str);
175 //         return qstr;
176 // }
177
178 void*
179 sw_make_qbytearray(char* str)
180 {
181         return new QByteArray(str);
182 }
183
184 void
185 sw_delete_qbytearray(void *q)
186 {
187         delete (QByteArray*) q;
188 }
189
190 void*
191 sw_make_qstring(char *str)
192 {
193         return new QString(QString::fromUtf8(str));
194 }
195
196 void*
197 sw_qstring_to_utf8(void* s)
198 {
199         QString* str = (QString*) s;
200         return new QByteArray(str->toUtf8());
201 }
202
203 const void*
204 sw_qstring_to_utf16(void* s)
205 {
206         QString* str = static_cast<QString*>(s);
207         return str->utf16();
208 }
209
210 void
211 sw_delete_qstring(void *q)
212 {
213         delete (QString*) q;
214 }
215
216 void*
217 sw_make_metaobject(void *p, char *strings, int *d)
218 {
219         QMetaObject* parent = (QMetaObject*) p;
220         const uint* data = (const uint*) d;
221
222         QMetaObject tmp = { { parent, strings, data, 0 } };
223         QMetaObject* ptr = new QMetaObject;
224         *ptr = tmp;
225         return ptr;
226 }
227
228 void
229 sw_delete(void *p)
230 {
231         QObject* q = (QObject*) p;
232         delete q;
233 }
234
235 typedef void (*t_ptr_callback)(void *);
236
237 void
238 sw_find_class(char *name, Smoke **smoke, short *index)
239 {
240         Smoke::ModuleIndex mi = qtcore_Smoke->findClass(name);
241         *smoke = mi.smoke;
242         *index = mi.index;
243 }
244
245 void
246 sw_id_instance_class(void *ptr, Smoke **smoke, short *index)
247 {
248         Smoke::ModuleIndex mi = qtcore_Smoke->findClass(((QObject*)ptr)->metaObject()->className());
249         *smoke = mi.smoke;
250         *index = mi.index;
251 }
252
253 short
254 sw_find_name(Smoke *smoke, char *name)
255 {
256         Smoke::ModuleIndex mi = smoke->idMethodName(name);
257         return mi.index;
258 }
259
260 short
261 sw_id_method(Smoke *smoke, short classIndex, short name)
262 {
263         Smoke::ModuleIndex mi = smoke->idMethod(classIndex, name);
264         return mi.index;
265 }
266
267 short
268 sw_id_type(Smoke *smoke, char *name)
269 {
270         return smoke->idType(name);
271 }
272
273 short
274 sw_id_class(Smoke *smoke, char *name, bool external)
275 {
276         return smoke->idClass(name, external).index;
277 }
278
279 // QStringList marshalling
280
281 void*
282 sw_qstringlist_new()
283 {
284         return new QStringList();
285 }
286
287 int
288 sw_qstringlist_size(void* q)
289 {
290         return static_cast<QStringList*>(q)->size();
291 }
292
293 void
294 sw_qstringlist_delete(void *q)
295 {
296         delete static_cast<QStringList*>(q);
297 }
298
299 const void*
300 sw_qstringlist_at(void* q, int index)
301 {
302         return static_cast<QStringList*>(q)->at(index).utf16();
303 }
304
305 void
306 sw_qstringlist_append(void *q, char *x)
307 {
308         static_cast<QStringList*>(q)->append(QString(QString::fromUtf8(x)));
309 }
310
311 // QList<Something*> marshalling
312
313 void*
314 sw_qlist_void_new()
315 {
316         return new QList<void*>;
317 }
318
319 int
320 sw_qlist_void_size(void *ptr)
321 {
322         QList<void*>* qlist = static_cast<QList<void*>*>(ptr);
323         return qlist->size();
324 }
325
326 void
327 sw_qlist_void_delete(void *ptr)
328 {
329         QList<void*>* qlist = static_cast<QList<void*>*>(ptr);
330         delete qlist;
331 }
332
333 const void*
334 sw_qlist_void_at(void *ptr, int index)
335 {
336         QList<void*>* qlist = static_cast<QList<void*>*>(ptr);
337         return qlist->at(index);
338 }
339
340 void
341 sw_qlist_void_append(void *ptr, void *whatptr)
342 {
343         QList<void*>* qlist = static_cast<QList<void*>*>(ptr);
344         qlist->append(whatptr);
345 }
346
347 // QList<scalar> marshalling
348
349 #define DEFINE_QLIST_SCALAR_MARSHALLER(ELEMENT_TYPE, NAME) \
350   void* \
351   sw_qlist_##NAME##_new() \
352   { \
353           return new QList<ELEMENT_TYPE>; \
354   } \
355   int \
356   sw_qlist_##NAME##_size(void *ptr) \
357   { \
358         QList<ELEMENT_TYPE>* qlist = static_cast<QList<ELEMENT_TYPE>*>(ptr); \
359         return qlist->size(); \
360   } \
361   void \
362   sw_qlist_##NAME##_delete(void *ptr) \
363   { \
364         QList<ELEMENT_TYPE>* qlist = static_cast<QList<ELEMENT_TYPE>*>(ptr); \
365         delete qlist; \
366   } \
367   const void* \
368   sw_qlist_##NAME##_at(void *ptr, int index) \
369   { \
370         QList<ELEMENT_TYPE>* qlist = static_cast<QList<ELEMENT_TYPE>*>(ptr); \
371         return &qlist->at(index); \
372   } \
373   void \
374   sw_qlist_##NAME##_append(void *ptr, void *whatptr) \
375   { \
376         QList<ELEMENT_TYPE>* qlist = static_cast<QList<ELEMENT_TYPE>*>(ptr); \
377         qlist->append(*static_cast<ELEMENT_TYPE*>(whatptr)); \
378   }
379
380 DEFINE_QLIST_SCALAR_MARSHALLER(int, int)
381 DEFINE_QLIST_SCALAR_MARSHALLER(QVariant, qvariant)
382 DEFINE_QLIST_SCALAR_MARSHALLER(QByteArray, qbytearray)
383 DEFINE_QLIST_SCALAR_MARSHALLER(QModelIndex, qmodelindex)
384 DEFINE_QLIST_SCALAR_MARSHALLER(QKeySequence, qkeysequence)