comparison d2/qt/core/QMetaObject.d @ 372:a032df77b6ab

Simple debug helper. Unittests. Meta-object for polymorphic non-QObjects
author Max Samukha <maxter@spambox.com>
date Thu, 08 Jul 2010 17:19:05 +0300
parents 6e1857c521af
children e67ce7c21758
comparison
equal deleted inserted replaced
370:7fd4b69378bf 372:a032df77b6ab
7 qtd.meta.Runtime, 7 qtd.meta.Runtime,
8 qtd.meta.Compiletime, 8 qtd.meta.Compiletime,
9 qtd.Marshal, 9 qtd.Marshal,
10 qtd.MOC, 10 qtd.MOC,
11 qtd.String, 11 qtd.String,
12 qtd.Signal,
12 std.typetuple, 13 std.typetuple,
13 std.traits, 14 std.traits,
14 std.c.stdlib; 15 std.c.stdlib;
15 16
16 import std.string : indexOf; 17 import std.string : indexOf;
83 { 84 {
84 return typeof(super).create!(method, This)(index); 85 return typeof(super).create!(method, This)(index);
85 } 86 }
86 } 87 }
87 88
88 /** 89
89 Base class for QtD meta-classes.
90 */
91 abstract class QtdMetaClass : MetaClass
92 {
93 private:
94 void* nativeId_;
95
96 public:
97
98 this() {}
99
100 /**
101 */
102 @property
103 void* nativeId()
104 {
105 return nativeId_;
106 }
107
108 void construct(T)()
109 {
110 super.construct!T();
111 nativeId_ = T.qtd_nativeStaticMetaObject();
112 }
113 }
114 90
115 struct QMetaObjectNative 91 struct QMetaObjectNative
116 { 92 {
117 QMetaObjectNative *superdata; 93 QMetaObjectNative *superdata;
118 immutable(char) *stringdata; 94 immutable(char) *stringdata;
119 const(uint) *data; 95 const(uint) *data;
120 void *extradata; 96 void *extradata;
121 } 97 }
122 98
99 // COMPILER BUG: causes a forward reference error if placed inside QMetaObject
100 enum MetaCall
101 {
102 InvokeMetaMethod,
103 ReadProperty,
104 WriteProperty,
105 ResetProperty,
106 QueryPropertyDesignable,
107 QueryPropertyScriptable,
108 QueryPropertyStored,
109 QueryPropertyEditable,
110 QueryPropertyUser,
111 CreateInstance
112 }
123 113
124 /** 114 /**
125 */ 115 */
126 final class QMetaObject : QtdMetaClass 116 final class QMetaObject : QtdMetaClass
127 { 117 {
128 alias typeof(this) This; 118 alias typeof(this) This;
129 119
130 private QObject function(void* nativeId) _createWrapper;
131
132 this() {} 120 this() {}
133
134 enum Call
135 {
136 InvokeMetaMethod,
137 ReadProperty,
138 WriteProperty,
139 ResetProperty,
140 QueryPropertyDesignable,
141 QueryPropertyScriptable,
142 QueryPropertyStored,
143 QueryPropertyEditable,
144 QueryPropertyUser,
145 CreateInstance
146 }
147 121
148 alias createImpl!This create; 122 alias createImpl!This create;
149 123
150 void construct(T : QObject)() 124 void construct(T : QObject)()
151 { 125 {
156 static if (is(T.ConcreteType)) 130 static if (is(T.ConcreteType))
157 alias T.ConcreteType Concrete; 131 alias T.ConcreteType Concrete;
158 else 132 else
159 alias T Concrete; 133 alias T Concrete;
160 134
161 _createWrapper = function QObject(void* nativeId) {
162 auto obj = new Concrete(nativeId, cast(QtdObjectFlags)(QtdObjectFlags.nativeOwnership | QtdObjectFlags.dynamicEntity));
163 T.__createEntity(nativeId, cast(void*)obj);
164 return obj;
165 };
166
167 T._populateMetaInfo(this); 135 T._populateMetaInfo(this);
168 } 136 }
169 // create run time meta-objects for user-defined signals and slots 137 // create run time meta-objects for user-defined signals and slots
170 else static if (is(typeof(T.methods))) 138 else static if (is(typeof(T.methods)))
171 { 139 {
275 // no initialized wrapper that matches the native object. 243 // no initialized wrapper that matches the native object.
276 // use the base class wrapper 244 // use the base class wrapper
277 return this; 245 return this;
278 } 246 }
279 247
280 QObject getObject(void* nativeObjId) 248 override QObject getWrapper(void* nativeObjId, QtdObjectInitFlags initFlags = QtdObjectInitFlags.none)
281 { 249 {
282 QObject result; 250 QObject result;
283 251
284 if (nativeObjId) 252 if (nativeObjId)
285 { 253 {
287 if (!result) 255 if (!result)
288 { 256 {
289 auto moId = qtd_QObject_metaObject(nativeObjId); 257 auto moId = qtd_QObject_metaObject(nativeObjId);
290 auto nId = nativeId; 258 auto nId = nativeId;
291 if (nId == moId) 259 if (nId == moId)
292 result = _createWrapper(nativeObjId); 260 result = static_cast!QObject(_createWrapper(nativeObjId, initFlags));
293 else 261 else
294 { 262 {
295 // get native metaobjects for the entire derivation lattice 263 // get native metaobjects for the entire derivation lattice
296 // up to, but not including, the current metaobject. 264 // up to, but not including, the current metaobject.
297 size_t moCount = 1; 265 size_t moCount = 1;
309 277
310 moIds[--moCount] = moId; 278 moIds[--moCount] = moId;
311 while (moCount > 0) 279 while (moCount > 0)
312 moIds[--moCount] = moId = qtd_QMetaObject_superClass(moId); 280 moIds[--moCount] = moId = qtd_QMetaObject_superClass(moId);
313 281
314 result = lookUpDerived(moIds)._createWrapper(nativeObjId); 282 auto mo = lookUpDerived(moIds);
283 result = static_cast!QObject(mo._createWrapper(nativeObjId, initFlags));
315 } 284 }
316 } 285 }
317 } 286 }
318 287
319 return result; 288 return result;
320 } 289 }
321 290
322 static void activate(QObject sender, QMetaObject m, int local_signal_index, void **argv) 291 static void activate(QObject sender, QMetaObject m, int local_signal_index, void **argv)
323 { 292 {
324 qtd_QMetaObject_activate_3(sender.__nativeId, m.nativeId, local_signal_index, argv); 293 qtd_QMetaObject_activate_3(sender.qtdNativeId, m.nativeId, local_signal_index, argv);
325 } 294 }
326 295
327 static void activate(QObject sender, QMetaObject m, int from_local_signal_index, int to_local_signal_index, void **argv) 296 static void activate(QObject sender, QMetaObject m, int from_local_signal_index, int to_local_signal_index, void **argv)
328 { 297 {
329 qtd_QMetaObject_activate_4(sender.__nativeId, m.nativeId, from_local_signal_index, to_local_signal_index, argv); 298 qtd_QMetaObject_activate_4(sender.qtdNativeId, m.nativeId, from_local_signal_index, to_local_signal_index, argv);
330 } 299 }
331 300
332 static bool connect(const QObject sender, int signal_index, 301 static bool connect(const QObject sender, int signal_index,
333 const QObject receiver, int method_index, 302 const QObject receiver, int method_index,
334 int type = 0, int *types = null) 303 int type = 0, int *types = null)
335 { 304 {
336 return qtd_QMetaObject_connect(sender.__nativeId, signal_index, receiver.__nativeId, method_index, type, types); 305 return qtd_QMetaObject_connect(sender.qtdNativeId, signal_index, receiver.qtdNativeId, method_index, type, types);
337 } 306 }
338 307
339 int indexOfMethod_Cpp(string method) 308 int indexOfMethod_Cpp(string method)
340 { 309 {
341 return qtd_QMetaObject_indexOfMethod(nativeId, toStringz(method)); 310 return qtd_QMetaObject_indexOfMethod(nativeId, toStringz(method));
423 392
424 /** 393 /**
425 */ 394 */
426 mixin template Q_CLASSINFO(string name, string value) 395 mixin template Q_CLASSINFO(string name, string value)
427 { 396 {
397 import qtd.meta.Compiletime;
428 mixin InnerAttribute!("Q_CLASSINFO", AttributeOptions.allowMultiple, name, value); 398 mixin InnerAttribute!("Q_CLASSINFO", AttributeOptions.allowMultiple, name, value);
429 } 399 }
430 400
431 /** 401 /**
432 */ 402 */
433 mixin template Q_PROPERTY(T, string params) 403 mixin template Q_PROPERTY(T, string params)
434 { 404 {
435 static assert(false, "not implemented"); 405 static assert(false, "not implemented");
436 } 406 }
437
438 version (QtdUnittest)
439 {
440 // COMPILER BUG: cannot put this inside the unittest block as static class.
441 class QMetaObject_A : QObject
442 {
443 mixin Q_CLASSINFO!("author", "Sabrina Schweinsteiger");
444 mixin Q_CLASSINFO!("url", "http://doc.moosesoft.co.uk/1.0/");
445
446 static int slot1Called;
447
448 final
449 {
450 void signal_signal1();
451 void signal_signal2(int);
452 }
453
454
455 void slot_slot1()
456 {
457 slot1Called++;
458 }
459
460 mixin Q_OBJECT;
461 }
462
463 unittest
464 {
465 scope a = new QMetaObject_A;
466 QObject.connect(a, "signal1", a, "slot1");
467 a.signal1();
468 assert(QMetaObject_A.slot1Called == 1);
469
470 QObject.connect(a, "signal2", a, "slot1");
471 a.signal2(42);
472 assert(QMetaObject_A.slot1Called == 2);
473 }
474 }
475 407
476 extern(C) void qtd_QMetaObject_activate_3(void* sender, void* m, int local_signal_index, void **argv); 408 extern(C) void qtd_QMetaObject_activate_3(void* sender, void* m, int local_signal_index, void **argv);
477 extern(C) void qtd_QMetaObject_activate_4(void *sender, void* m, int from_local_signal_index, int to_local_signal_index, void **argv); 409 extern(C) void qtd_QMetaObject_activate_4(void *sender, void* m, int from_local_signal_index, int to_local_signal_index, void **argv);
478 extern(C) bool qtd_QMetaObject_connect(const void* sender, int signal_index, 410 extern(C) bool qtd_QMetaObject_connect(const void* sender, int signal_index,
479 const void* receiver, int method_index, 411 const void* receiver, int method_index,