comparison qt/core/QMetaObject.d @ 248:7664de4a55e5

Fixed #23. QtD_QObjectEntity is not created dynamically for shell classes any more. Class initialization is now performed by static constructors. When wrapping QObjects returned from functions, their run-time types are now taken into account. QObjects are allocated on GC heap, a doubly-linked list is used to prevent them from been collected (arguably a better solution than allocating on C heap and adding GC ranges) Minor changes (including unnecessary).
author maxter
date Thu, 20 Aug 2009 14:47:17 +0000
parents
children
comparison
equal deleted inserted replaced
247:27497bbe62a1 248:7664de4a55e5
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 static QObject createWrapper(void* nativeId)
43 {
44 T obj = new Concrete(nativeId, QtdObjectFlags.nativeOwnership);
45 // TODO: this probably should be moved to QObject constructor
46 qtd_create_qobject_entity(nativeId, cast(void*)obj);
47 return obj;
48 }
49
50 _createWrapper = &createWrapper;
51 }
52
53 /++
54 +/
55 QMetaObject base()
56 {
57 return _base;
58 }
59
60 /++
61 +/
62 void* nativeId()
63 {
64 return _nativeId;
65 }
66
67 /++
68 +/
69 ClassInfo classInfo()
70 {
71 return _classInfo;
72 }
73
74 private QObject lookupDerived(void*[] moIds, void* nativeObjId)
75 {
76 assert (moIds.length >= 1);
77
78 for (auto mo = _firstDerived; mo !is null; mo = mo._next)
79 {
80 if (mo._nativeId == moIds[0])
81 {
82 if (moIds.length == 1) // exact match found
83 return mo._createWrapper(nativeObjId);
84 else // look deeper
85 return mo.lookupDerived(moIds[1..$], nativeObjId);
86 }
87 }
88
89 // no initialized wrapper that matches the native object.
90 // use the base class wrapper
91 return _createWrapper(nativeObjId);
92 }
93
94 QObject getObject(void* nativeObjId)
95 {
96 QObject result;
97
98 if (nativeObjId)
99 {
100 result = cast(QObject)qtd_get_d_qobject(nativeObjId);
101 if (!result)
102 {
103 auto moId = qtd_QObject_metaObject(nativeObjId);
104 if (_nativeId == moId)
105 result = _createWrapper(nativeObjId);
106 else
107 {
108 // get native metaobjects for the entire derivation lattice
109 // up to, but not including, the current metaobject.
110 size_t moCount = 1;
111
112 for (void* tmp = moId;;)
113 {
114 tmp = qtd_QMetaObject_superClass(tmp);
115 assert(tmp);
116 if (tmp == _nativeId)
117 break;
118 moCount++;
119 }
120
121 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount];
122
123 moIds[--moCount] = moId;
124 while (moCount > 0)
125 moIds[--moCount] = moId = qtd_QMetaObject_superClass(moId);
126
127 result = lookupDerived(moIds, nativeObjId);
128 }
129 }
130 }
131
132 return result;
133 }
134 }
135
136 extern(C) void* qtd_QMetaObject_superClass(void* nativeId);