Mercurial > projects > qtd
comparison qt/core/QMetaObject.d @ 253:073b9153ed8a
Rev. 264 done right.
Problems:
- classwizard segfaults on exit due to a bug in signals/slots or runtime.
- hellogl doesn't compile with dmd2 due to a bug in the compiler backend
author | maxter |
---|---|
date | Sun, 30 Aug 2009 09:59:12 +0000 |
parents | |
children | 515d6e1c7b10 f9559a957be9 |
comparison
equal
deleted
inserted
replaced
252:37eed70de029 | 253:073b9153ed8a |
---|---|
1 module qt.core.QMetaObject; | |
2 | |
3 import qt.QGlobal; | |
4 import qt.core.QObject; | |
5 import qt.QtdObject; | |
6 | |
7 final class QMetaObject | |
8 { | |
9 private | |
10 { | |
11 void* _nativeId; | |
12 QMetaObject _base; // super class | |
13 QMetaObject _firstDerived; // head of the linked list of derived classes | |
14 QMetaObject _next; // next sibling on this derivation level | |
15 ClassInfo _classInfo; | |
16 | |
17 QObject function(void* nativeId) _createWrapper; | |
18 } | |
19 | |
20 private void addDerived(QMetaObject mo) | |
21 { | |
22 mo._next = _firstDerived; | |
23 _firstDerived = mo; | |
24 } | |
25 | |
26 // NOTE: construction is split between this non-templated constructor and 'construct' function below. | |
27 this(void* nativeId, QMetaObject base) | |
28 { | |
29 _nativeId = nativeId; | |
30 if (base) | |
31 { | |
32 base.addDerived(this); | |
33 _base = base; | |
34 } | |
35 } | |
36 | |
37 // TODO: remove when D acquires templated constructors | |
38 void construct(T : QObject, Concrete = T)() | |
39 { | |
40 _classInfo = T.classinfo; | |
41 | |
42 _createWrapper = function QObject(void* nativeId) { | |
43 // COMPILER BUG: cast is should not be needed | |
44 auto obj = new Concrete(nativeId, cast(QtdObjectFlags)(QtdObjectFlags.nativeOwnership | QtdObjectFlags.dynamicEntity)); | |
45 // TODO: Probably this should be a virtual call from T's constructor | |
46 T.__createEntity(nativeId, cast(void*)obj); | |
47 return obj; | |
48 }; | |
49 } | |
50 | |
51 /++ | |
52 +/ | |
53 QMetaObject base() | |
54 { | |
55 return _base; | |
56 } | |
57 | |
58 /++ | |
59 +/ | |
60 void* nativeId() | |
61 { | |
62 return _nativeId; | |
63 } | |
64 | |
65 /++ | |
66 +/ | |
67 ClassInfo classInfo() | |
68 { | |
69 return _classInfo; | |
70 } | |
71 | |
72 private QMetaObject lookupDerived(void*[] moIds) | |
73 { | |
74 assert (moIds.length >= 1); | |
75 | |
76 for (auto mo = _firstDerived; mo !is null; mo = mo._next) | |
77 { | |
78 if (mo._nativeId == moIds[0]) | |
79 { | |
80 if (moIds.length == 1) // exact match found | |
81 return mo; | |
82 else // look deeper | |
83 return mo.lookupDerived(moIds[1..$]); | |
84 } | |
85 } | |
86 | |
87 // no initialized wrapper that matches the native object. | |
88 // use the base class wrapper | |
89 return this; | |
90 } | |
91 | |
92 QObject getObject(void* nativeObjId) | |
93 { | |
94 QObject result; | |
95 | |
96 if (nativeObjId) | |
97 { | |
98 result = cast(QObject)qtd_get_d_qobject(nativeObjId); | |
99 if (!result) | |
100 { | |
101 auto moId = qtd_QObject_metaObject(nativeObjId); | |
102 if (_nativeId == moId) | |
103 result = _createWrapper(nativeObjId); | |
104 else | |
105 { | |
106 // get native metaobjects for the entire derivation lattice | |
107 // up to, but not including, the current metaobject. | |
108 size_t moCount = 1; | |
109 | |
110 for (void* tmp = moId;;) | |
111 { | |
112 tmp = qtd_QMetaObject_superClass(tmp); | |
113 assert(tmp); | |
114 if (tmp == _nativeId) | |
115 break; | |
116 moCount++; | |
117 } | |
118 | |
119 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount]; | |
120 | |
121 moIds[--moCount] = moId; | |
122 while (moCount > 0) | |
123 moIds[--moCount] = moId = qtd_QMetaObject_superClass(moId); | |
124 | |
125 result = lookupDerived(moIds)._createWrapper(nativeObjId); | |
126 } | |
127 } | |
128 } | |
129 | |
130 return result; | |
131 } | |
132 } | |
133 | |
134 extern(C) void* qtd_QMetaObject_superClass(void* nativeId); |