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);