Mercurial > projects > qtd
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, |