Mercurial > projects > qtd
comparison d2/qt/core/QMetaObject.d @ 364:a084e2df3776
Preparing for non-QObject meta-objects. Now meta-objects for static types can be uniformly accessed using meta!T
author | Max Samukha <maxter@maxter.com> |
---|---|
date | Fri, 11 Jun 2010 12:16:09 +0300 |
parents | 9784459f0750 |
children | 958e8b9a89bd |
comparison
equal
deleted
inserted
replaced
363:3b0545d4d479 | 364:a084e2df3776 |
---|---|
11 qtd.MOC, | 11 qtd.MOC, |
12 std.string, | 12 std.string, |
13 std.typetuple, | 13 std.typetuple, |
14 std.c.stdlib; | 14 std.c.stdlib; |
15 | 15 |
16 class QMetaArgument : Meta | 16 class QMetaArgument : MetaBase |
17 { | 17 { |
18 } | 18 } |
19 | 19 |
20 class QMetaMethod : Meta | 20 class QMetaMethod : MetaBase |
21 { | 21 { |
22 alias typeof(this) This; | 22 alias typeof(this) This; |
23 | 23 |
24 // QMetaArgument[] arguments; | 24 // QMetaArgument[] arguments; |
25 string signature; | 25 string signature; |
82 { | 82 { |
83 return typeof(super).create!(method, This)(index); | 83 return typeof(super).create!(method, This)(index); |
84 } | 84 } |
85 } | 85 } |
86 | 86 |
87 class MetaObject : MetaType | 87 /** |
88 { | 88 Base class for QtD meta-classes. |
89 MetaObject _base; | 89 */ |
90 abstract class QtdMetaClass : MetaClass | |
91 { | |
92 private: | |
93 void* nativeId_; | |
94 | |
95 this() {} | |
96 | |
97 public: | |
98 | |
99 /** | |
100 */ | |
101 @property | |
102 void* nativeId() | |
103 { | |
104 return nativeId_; | |
105 } | |
106 | |
107 /* internal */ void construct(T)() | |
108 { | |
109 super.construct!T(); | |
110 nativeId_ = T.qtd_nativeMetaObject; | |
111 } | |
90 } | 112 } |
91 | 113 |
92 struct QMetaObjectNative | 114 struct QMetaObjectNative |
93 { | 115 { |
94 QMetaObjectNative *superdata; | 116 QMetaObjectNative *superdata; |
97 void *extradata; | 119 void *extradata; |
98 } | 120 } |
99 | 121 |
100 class QMetaException : Exception { this(string msg) { super(msg); } } | 122 class QMetaException : Exception { this(string msg) { super(msg); } } |
101 | 123 |
102 final class QMetaObject | 124 final class QMetaObject : QtdMetaClass |
103 { | 125 { |
104 alias typeof(this) This; | 126 alias typeof(this) This; |
105 | |
106 private this() {} | |
107 | 127 |
108 enum Call | 128 enum Call |
109 { | 129 { |
110 InvokeMetaMethod, | 130 InvokeMetaMethod, |
111 ReadProperty, | 131 ReadProperty, |
119 CreateInstance | 139 CreateInstance |
120 } | 140 } |
121 | 141 |
122 private | 142 private |
123 { | 143 { |
124 QMetaObjectNative* _nativeId; | |
125 QMetaObject _base; // super class | |
126 QMetaObject _firstDerived; // head of the linked list of derived classes | |
127 QMetaObject _next; // next sibling on this derivation level | |
128 QMetaMethod[] _methods; | 144 QMetaMethod[] _methods; |
129 ClassInfo _classInfo; | |
130 | |
131 QObject function(void* nativeId) _createWrapper; | 145 QObject function(void* nativeId) _createWrapper; |
132 } | 146 } |
133 | 147 |
134 private void addDerived(QMetaObject mo) | 148 void construct(T : QObject)() |
135 { | 149 { |
136 mo._next = _firstDerived; | 150 super.construct!T(); |
137 _firstDerived = mo; | |
138 } | |
139 | |
140 // ctor | |
141 void construct(T : QObject)(void* nativeId) | |
142 { | |
143 alias BaseClassesTuple!(T)[0] Base; | |
144 This base; | |
145 static if (is(Base : QObject)) | |
146 base = Base.staticMetaObject; | |
147 | |
148 _nativeId = cast(QMetaObjectNative*)nativeId; | |
149 T.setStaticMetaObject(this); | |
150 | |
151 if (base) | |
152 { | |
153 base.addDerived(this); | |
154 _base = base; | |
155 } | |
156 _classInfo = T.classinfo; | |
157 | |
158 | 151 |
159 static if (isQtType!T) | 152 static if (isQtType!T) |
160 { | 153 { |
161 static if (is(T.ConcreteType)) | 154 static if (is(T.ConcreteType)) |
162 alias T.ConcreteType Concrete; | 155 alias T.ConcreteType Concrete; |
169 return obj; | 162 return obj; |
170 }; | 163 }; |
171 | 164 |
172 T._populateMetaInfo; | 165 T._populateMetaInfo; |
173 } | 166 } |
167 | |
174 // create run time meta-objects for user-defined signals and slots | 168 // create run time meta-objects for user-defined signals and slots |
175 else static if (is(typeof(T.methods))) | 169 else static if (is(typeof(T.methods))) |
176 { | 170 { |
171 alias BaseClassesTuple!(T)[0] Base; | |
177 int index = Base.staticMetaObject().methodCount(); | 172 int index = Base.staticMetaObject().methodCount(); |
178 | 173 |
179 static if (T.signals.length) | 174 static if (T.signals.length) |
180 { | 175 { |
181 foreach (signal; T.signals) | 176 foreach (signal; T.signals) |
194 } | 189 } |
195 } | 190 } |
196 } | 191 } |
197 } | 192 } |
198 | 193 |
199 // new | 194 /* internal */ alias createImpl!This create; |
200 static This create(T : QObject)(void* nativeId) | 195 |
201 { | 196 /** |
202 auto m = new This(); | 197 */ |
203 m.construct!T(nativeId); | 198 @property |
204 return m; | 199 override This base() |
205 } | 200 { |
206 | 201 return super.base; |
207 /++ | 202 } |
208 +/ | 203 |
209 QMetaObject base() | 204 /** |
210 { | 205 */ |
211 return _base; | 206 @property |
212 } | 207 override This firstDerived() |
213 | 208 { |
214 /++ | 209 return super.firstDerived; |
215 +/ | 210 } |
216 QMetaObjectNative* nativeId() | 211 |
217 { | 212 /** |
218 return _nativeId; | 213 */ |
219 } | 214 @property |
220 | 215 override This next() |
221 /++ | 216 { |
222 +/ | 217 return super.next; |
223 ClassInfo classInfo() | 218 } |
224 { | 219 |
225 return _classInfo; | 220 /** |
226 } | 221 */ |
227 | 222 @property |
223 override QMetaObjectNative* nativeId() | |
224 { | |
225 return cast(QMetaObjectNative*)super.nativeId; | |
226 } | |
227 | |
228 @property | |
228 const (QMetaMethod[]) methods() | 229 const (QMetaMethod[]) methods() |
229 { | 230 { |
230 return _methods; | 231 return _methods; |
231 } | 232 } |
232 | 233 |
238 QMetaMethod lookUpMethod(string slot) | 239 QMetaMethod lookUpMethod(string slot) |
239 { | 240 { |
240 foreach (method; _methods) | 241 foreach (method; _methods) |
241 if (method.signature == slot) | 242 if (method.signature == slot) |
242 return method; | 243 return method; |
243 if (_base) | 244 if (base) |
244 return _base.lookUpMethod(slot); | 245 return base.lookUpMethod(slot); |
245 else | 246 else |
246 return null; | 247 return null; |
247 } | 248 } |
248 | 249 |
249 QMetaSignal lookUpSignal(string signal) | 250 QMetaSignal lookUpSignal(string signal) |
250 { | 251 { |
251 foreach (method; _methods) | 252 foreach (method; _methods) |
252 if (method.signature == signal && cast(QMetaSignal)method) | 253 if (method.signature == signal && cast(QMetaSignal)method) |
253 return cast(QMetaSignal)method; | 254 return cast(QMetaSignal)method; |
254 if (_base) | 255 if (base) |
255 return _base.lookUpSignal(signal); | 256 return base.lookUpSignal(signal); |
256 else | 257 else |
257 return null; | 258 return null; |
258 } | 259 } |
259 | 260 |
260 QMetaMethod[] lookUpMethodOverloads(string methodName) | 261 QMetaMethod[] lookUpMethodOverloads(string methodName) |
261 { | 262 { |
262 typeof(return) result; | 263 typeof(return) result; |
263 foreach (method; _methods) | 264 foreach (method; _methods) |
264 if (method.name == methodName) | 265 if (method.name == methodName) |
265 result ~= method; | 266 result ~= method; |
266 if (_base) | 267 if (base) |
267 result ~= _base.lookUpMethodOverloads(methodName); | 268 result ~= base.lookUpMethodOverloads(methodName); |
268 return result; | 269 return result; |
269 } | 270 } |
270 | 271 |
271 QMetaSignal[] lookUpSignalOverloads(string signalName) | 272 QMetaSignal[] lookUpSignalOverloads(string signalName) |
272 { | 273 { |
273 typeof(return) result; | 274 typeof(return) result; |
274 foreach (method; _methods) | 275 foreach (method; _methods) |
275 if (method.name == signalName && cast(QMetaSignal)method) | 276 if (method.name == signalName && cast(QMetaSignal)method) |
276 result ~= cast(QMetaSignal)method; | 277 result ~= cast(QMetaSignal)method; |
277 if (_base) | 278 if (base) |
278 result ~= _base.lookUpSignalOverloads(signalName); | 279 result ~= base.lookUpSignalOverloads(signalName); |
279 return result; | 280 return result; |
280 } | 281 } |
281 | 282 |
282 private QMetaObject lookupDerived(void*[] moIds) | 283 private QMetaObject lookupDerived(void*[] moIds) |
283 { | 284 { |
284 assert (moIds.length >= 1); | 285 assert (moIds.length >= 1); |
285 | 286 |
286 for (auto mo = _firstDerived; mo !is null; mo = mo._next) | 287 for (auto mo = firstDerived; mo !is null; mo = mo.next) |
287 { | 288 { |
288 if (mo._nativeId == moIds[0]) | 289 if (mo.nativeId == moIds[0]) |
289 { | 290 { |
290 if (moIds.length == 1) // exact match found | 291 if (moIds.length == 1) // exact match found |
291 return mo; | 292 return mo; |
292 else // look deeper | 293 else // look deeper |
293 return mo.lookupDerived(moIds[1..$]); | 294 return mo.lookupDerived(moIds[1..$]); |
306 if (nativeObjId) | 307 if (nativeObjId) |
307 { | 308 { |
308 result = cast(QObject)qtd_get_d_qobject(nativeObjId); | 309 result = cast(QObject)qtd_get_d_qobject(nativeObjId); |
309 if (!result) | 310 if (!result) |
310 { | 311 { |
312 auto nId = nativeId; | |
311 auto moId = qtd_QObject_metaObject(nativeObjId); | 313 auto moId = qtd_QObject_metaObject(nativeObjId); |
312 if (_nativeId == moId) | 314 if (nId == moId) |
313 result = _createWrapper(nativeObjId); | 315 result = _createWrapper(nativeObjId); |
314 else | 316 else |
315 { | 317 { |
316 // get native metaobjects for the entire derivation lattice | 318 // get native metaobjects for the entire derivation lattice |
317 // up to, but not including, the current metaobject. | 319 // up to, but not including, the current metaobject. |
319 | 321 |
320 for (void* tmp = moId;;) | 322 for (void* tmp = moId;;) |
321 { | 323 { |
322 tmp = qtd_QMetaObject_superClass(tmp); | 324 tmp = qtd_QMetaObject_superClass(tmp); |
323 assert(tmp); | 325 assert(tmp); |
324 if (tmp == _nativeId) | 326 if (tmp == nId) |
325 break; | 327 break; |
326 moCount++; | 328 moCount++; |
327 } | 329 } |
328 | 330 |
329 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount]; | 331 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount]; |
357 return qtd_QMetaObject_connect(sender.__nativeId, signal_index, receiver.__nativeId, method_index, type, types); | 359 return qtd_QMetaObject_connect(sender.__nativeId, signal_index, receiver.__nativeId, method_index, type, types); |
358 } | 360 } |
359 | 361 |
360 int indexOfMethod_Cpp(string method) | 362 int indexOfMethod_Cpp(string method) |
361 { | 363 { |
362 return qtd_QMetaObject_indexOfMethod(_nativeId, toStringz(method)); | 364 return qtd_QMetaObject_indexOfMethod(nativeId, toStringz(method)); |
363 } | 365 } |
364 | 366 |
365 int methodCount() | 367 int methodCount() |
366 { | 368 { |
367 return qtd_QMetaObject_methodCount(_nativeId); | 369 return qtd_QMetaObject_methodCount(nativeId); |
368 } | 370 } |
369 | 371 |
370 static void connectImpl(QObject sender, string signalString, QObject receiver, string methodString, int type) | 372 static void connectImpl(QObject sender, string signalString, QObject receiver, string methodString, int type) |
371 { | 373 { |
372 QMetaSignal[] signals; | 374 QMetaSignal[] signals; |