Mercurial > projects > qtd
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); |