Mercurial > projects > qtd
comparison d2/qt/core/QMetaObject.d @ 350:31520b2c0b3c
Removed dependency on parent trait and stringof
author | Max Samukha <maxter@spambox.com> |
---|---|
date | Thu, 20 May 2010 15:49:08 +0300 |
parents | 96a75b1e5b26 |
children | 9784459f0750 |
comparison
equal
deleted
inserted
replaced
349:925386e0e780 | 350:31520b2c0b3c |
---|---|
6 | 6 |
7 import std.algorithm; | 7 import std.algorithm; |
8 import std.string; | 8 import std.string; |
9 import std.stdio; | 9 import std.stdio; |
10 | 10 |
11 class Meta | 11 import qtd.meta.Runtime; |
12 { | 12 import qtd.Marshal; |
13 string name; | 13 |
14 } | 14 class QMetaArgument : Meta |
15 | 15 { |
16 class MetaType : Meta | 16 } |
17 { | 17 |
18 this() | 18 class QMetaMethod : Meta |
19 { | 19 { |
20 } | 20 alias typeof(this) This; |
21 } | 21 |
22 | 22 // QMetaArgument[] arguments; |
23 class MetaVariable : Meta | |
24 { | |
25 MetaType type; | |
26 } | |
27 | |
28 class MetaCallable : Meta { } | |
29 | |
30 class MetaMethod : Meta { } | |
31 | |
32 class QMetaArgument : MetaVariable { } | |
33 | |
34 class QMetaMethod : MetaMethod | |
35 { | |
36 // QMetaArgument[] arguments; | |
37 string signature; | 23 string signature; |
38 int indexOfMethod; | 24 int indexOfMethod; |
39 | 25 |
40 this(string signature_, int indexOfMethod_) | 26 this(string signature_, int indexOfMethod_) |
41 { | 27 { |
55 string name() const | 41 string name() const |
56 { | 42 { |
57 int openBracket = indexOf(signature, '('); | 43 int openBracket = indexOf(signature, '('); |
58 return signature[0..openBracket]; | 44 return signature[0..openBracket]; |
59 } | 45 } |
46 | |
47 // mixin(Derived) or typeof(Derived) would help a lot here | |
48 static create(alias method, M : This)(uint index) | |
49 { | |
50 alias ParameterTypeTuple!method Args; | |
51 return new M(.signature!(Args)(methodName!(method)), index); | |
52 } | |
60 } | 53 } |
61 | 54 |
62 class QMetaSignal : QMetaMethod | 55 class QMetaSignal : QMetaMethod |
63 { | 56 { |
57 alias typeof(this) This; | |
58 | |
64 this(string signature_, int indexOfMethod_) | 59 this(string signature_, int indexOfMethod_) |
65 { | 60 { |
66 super(signature_, indexOfMethod_); | 61 super(signature_, indexOfMethod_); |
67 } | 62 } |
63 | |
64 static This create(alias method)(uint index) | |
65 { | |
66 return typeof(super).create!(method, This)(index); | |
67 } | |
68 } | 68 } |
69 | 69 |
70 class QMetaSlot : QMetaMethod | 70 class QMetaSlot : QMetaMethod |
71 { | 71 { |
72 alias typeof(this) This; | |
73 | |
72 this(string signature_, int indexOfMethod_) | 74 this(string signature_, int indexOfMethod_) |
73 { | 75 { |
74 super(signature_, indexOfMethod_); | 76 super(signature_, indexOfMethod_); |
77 } | |
78 | |
79 static This create(alias method)(uint index) | |
80 { | |
81 return typeof(super).create!(method, This)(index); | |
75 } | 82 } |
76 } | 83 } |
77 | 84 |
78 class MetaObject : MetaType | 85 class MetaObject : MetaType |
79 { | 86 { |
90 | 97 |
91 class QMetaException : Exception { this(string msg) { super(msg); } } | 98 class QMetaException : Exception { this(string msg) { super(msg); } } |
92 | 99 |
93 final class QMetaObject | 100 final class QMetaObject |
94 { | 101 { |
102 alias typeof(this) This; | |
103 | |
104 private this() {} | |
105 | |
95 enum Call | 106 enum Call |
96 { | 107 { |
97 InvokeMetaMethod, | 108 InvokeMetaMethod, |
98 ReadProperty, | 109 ReadProperty, |
99 WriteProperty, | 110 WriteProperty, |
115 QMetaMethod[] _methods; | 126 QMetaMethod[] _methods; |
116 ClassInfo _classInfo; | 127 ClassInfo _classInfo; |
117 | 128 |
118 QObject function(void* nativeId) _createWrapper; | 129 QObject function(void* nativeId) _createWrapper; |
119 } | 130 } |
120 | 131 |
121 private void addDerived(QMetaObject mo) | 132 private void addDerived(QMetaObject mo) |
122 { | 133 { |
123 mo._next = _firstDerived; | 134 mo._next = _firstDerived; |
124 _firstDerived = mo; | 135 _firstDerived = mo; |
125 } | 136 } |
126 | 137 |
127 // NOTE: construction is split between this non-templated constructor and 'construct' function below. | 138 // ctor |
128 this(QMetaObjectNative* nativeId, QMetaObject base) | 139 void construct(T : QObject)(void* nativeId) |
129 { | 140 { |
130 _nativeId = nativeId; | 141 alias BaseClassesTuple!(T)[0] Base; |
142 This base; | |
143 static if (is(Base : QObject)) | |
144 base = Base.staticMetaObject; | |
145 | |
146 _nativeId = cast(QMetaObjectNative*)nativeId; | |
147 T.setStaticMetaObject(this); | |
148 | |
131 if (base) | 149 if (base) |
132 { | 150 { |
133 base.addDerived(this); | 151 base.addDerived(this); |
134 _base = base; | 152 _base = base; |
135 } | 153 } |
136 } | 154 _classInfo = T.classinfo; |
137 | 155 |
138 // TODO: remove when D acquires templated constructors | 156 |
139 void construct(T : QObject, Concrete = T)() | 157 static if (isQtType!T) |
140 { | 158 { |
141 _classInfo = T.classinfo; | 159 static if (is(T.ConcreteType)) |
142 | 160 alias T.ConcreteType Concrete; |
143 _createWrapper = function QObject(void* nativeId) { | 161 else |
144 // COMPILER BUG: cast is should not be needed | 162 alias T Concrete; |
145 auto obj = new Concrete(nativeId, cast(QtdObjectFlags)(QtdObjectFlags.nativeOwnership | QtdObjectFlags.dynamicEntity)); | 163 |
146 // TODO: Probably this should be a virtual call from T's constructor | 164 _createWrapper = function QObject(void* nativeId) { |
147 T.__createEntity(nativeId, cast(void*)obj); | 165 auto obj = new Concrete(nativeId, cast(QtdObjectFlags)(QtdObjectFlags.nativeOwnership | QtdObjectFlags.dynamicEntity)); |
148 return obj; | 166 T.__createEntity(nativeId, cast(void*)obj); |
149 }; | 167 return obj; |
150 } | 168 }; |
151 | 169 |
170 T._populateMetaInfo; | |
171 } | |
172 // create run time meta-objects for user-defined signals and slots | |
173 else static if (is(typeof(T.methods))) | |
174 { | |
175 int index = Base.staticMetaObject().methodCount(); | |
176 | |
177 static if (T.signals.length) | |
178 { | |
179 foreach (signal; T.signals) | |
180 { | |
181 addMethod(QMetaSignal.create!signal(index)); | |
182 index++; | |
183 } | |
184 } | |
185 | |
186 static if (T.slots.length) | |
187 { | |
188 foreach (slot; T.slots) | |
189 { | |
190 addMethod(QMetaSlot.create!slot(index)); | |
191 index++; | |
192 } | |
193 } | |
194 } | |
195 } | |
196 | |
197 // new | |
198 static This create(T : QObject)(void* nativeId) | |
199 { | |
200 auto m = new This(); | |
201 m.construct!T(nativeId); | |
202 return m; | |
203 } | |
204 | |
152 /++ | 205 /++ |
153 +/ | 206 +/ |
154 QMetaObject base() | 207 QMetaObject base() |
155 { | 208 { |
156 return _base; | 209 return _base; |
245 } | 298 } |
246 | 299 |
247 QObject getObject(void* nativeObjId) | 300 QObject getObject(void* nativeObjId) |
248 { | 301 { |
249 QObject result; | 302 QObject result; |
250 | 303 |
251 if (nativeObjId) | 304 if (nativeObjId) |
252 { | 305 { |
253 result = cast(QObject)qtd_get_d_qobject(nativeObjId); | 306 result = cast(QObject)qtd_get_d_qobject(nativeObjId); |
254 if (!result) | 307 if (!result) |
255 { | 308 { |
259 else | 312 else |
260 { | 313 { |
261 // get native metaobjects for the entire derivation lattice | 314 // get native metaobjects for the entire derivation lattice |
262 // up to, but not including, the current metaobject. | 315 // up to, but not including, the current metaobject. |
263 size_t moCount = 1; | 316 size_t moCount = 1; |
264 | 317 |
265 for (void* tmp = moId;;) | 318 for (void* tmp = moId;;) |
266 { | 319 { |
267 tmp = qtd_QMetaObject_superClass(tmp); | 320 tmp = qtd_QMetaObject_superClass(tmp); |
268 assert(tmp); | 321 assert(tmp); |
269 if (tmp == _nativeId) | 322 if (tmp == _nativeId) |
270 break; | 323 break; |
271 moCount++; | 324 moCount++; |
272 } | 325 } |
273 | 326 |
274 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount]; | 327 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount]; |
275 | 328 |
276 moIds[--moCount] = moId; | 329 moIds[--moCount] = moId; |
277 while (moCount > 0) | 330 while (moCount > 0) |
278 moIds[--moCount] = moId = qtd_QMetaObject_superClass(moId); | 331 moIds[--moCount] = moId = qtd_QMetaObject_superClass(moId); |
279 | 332 |
280 result = lookupDerived(moIds)._createWrapper(nativeObjId); | 333 result = lookupDerived(moIds)._createWrapper(nativeObjId); |
281 } | 334 } |
282 } | 335 } |
283 } | 336 } |
284 | 337 |
304 | 357 |
305 int indexOfMethod_Cpp(string method) | 358 int indexOfMethod_Cpp(string method) |
306 { | 359 { |
307 return qtd_QMetaObject_indexOfMethod(_nativeId, toStringz(method)); | 360 return qtd_QMetaObject_indexOfMethod(_nativeId, toStringz(method)); |
308 } | 361 } |
309 | 362 |
310 int methodCount() | 363 int methodCount() |
311 { | 364 { |
312 return qtd_QMetaObject_methodCount(_nativeId); | 365 return qtd_QMetaObject_methodCount(_nativeId); |
313 } | 366 } |
314 | 367 |
315 static void connectImpl(QObject sender, string signalString, QObject receiver, string methodString, int type) | 368 static void connectImpl(QObject sender, string signalString, QObject receiver, string methodString, int type) |
316 { | 369 { |
317 QMetaSignal[] signals; | 370 QMetaSignal[] signals; |
318 QMetaMethod[] methods; | 371 QMetaMethod[] methods; |
319 QMetaSignal signal; | 372 QMetaSignal signal; |
322 if(indexOf(signalString, '(') > 0) | 375 if(indexOf(signalString, '(') > 0) |
323 signal = sender.metaObject.lookUpSignal(signalString); | 376 signal = sender.metaObject.lookUpSignal(signalString); |
324 else | 377 else |
325 signals = sender.metaObject.lookUpSignalOverloads(signalString); // parameters not specified. Looking for a match | 378 signals = sender.metaObject.lookUpSignalOverloads(signalString); // parameters not specified. Looking for a match |
326 | 379 |
327 if(indexOf(methodString, '(') > 0) | 380 if(indexOf(methodString, '(') > 0) |
328 method = receiver.metaObject.lookUpMethod(methodString); | 381 method = receiver.metaObject.lookUpMethod(methodString); |
329 else | 382 else |
330 methods = receiver.metaObject.lookUpMethodOverloads(methodString); // parameters not specified. Looking for a match | 383 methods = receiver.metaObject.lookUpMethodOverloads(methodString); // parameters not specified. Looking for a match |
331 | 384 |
332 if(!signal && !method) | 385 if(!signal && !method) |
356 if(startsWith(signal.args, meth.args)) | 409 if(startsWith(signal.args, meth.args)) |
357 { | 410 { |
358 method = meth; | 411 method = meth; |
359 break; | 412 break; |
360 } | 413 } |
361 } | 414 } |
362 | 415 |
363 bool success = false; | 416 bool success = false; |
364 | 417 |
365 if(!signal && !method) | 418 if(!signal && !method) |
366 { | 419 { |
367 success = false; | 420 success = false; |
370 { | 423 { |
371 int signalIndex = signal.indexOfMethod; | 424 int signalIndex = signal.indexOfMethod; |
372 int methodIndex = method.indexOfMethod; | 425 int methodIndex = method.indexOfMethod; |
373 success = QMetaObject.connect(sender, signalIndex, receiver, methodIndex, type); | 426 success = QMetaObject.connect(sender, signalIndex, receiver, methodIndex, type); |
374 } | 427 } |
375 | 428 |
376 if(!success) | 429 if(!success) |
377 throw new QMetaException("QMetaObject: Signal " ~ signalString ~ " and slot " ~ methodString ~ " cannot be found"); | 430 throw new QMetaException("QMetaObject: Signal " ~ signalString ~ " and slot " ~ methodString ~ " cannot be found"); |
378 } | 431 } |
379 } | 432 } |
380 | 433 |
381 extern(C) void qtd_QMetaObject_activate_3(void* sender, void* m, int local_signal_index, void **argv); | 434 extern(C) void qtd_QMetaObject_activate_3(void* sender, void* m, int local_signal_index, void **argv); |
382 extern(C) void qtd_QMetaObject_activate_4(void *sender, void* m, int from_local_signal_index, int to_local_signal_index, void **argv); | 435 extern(C) void qtd_QMetaObject_activate_4(void *sender, void* m, int from_local_signal_index, int to_local_signal_index, void **argv); |
383 extern(C) bool qtd_QMetaObject_connect(const void* sender, int signal_index, | 436 extern(C) bool qtd_QMetaObject_connect(const void* sender, int signal_index, |
384 const void* receiver, int method_index, | 437 const void* receiver, int method_index, |
385 int type, int *types); | 438 int type, int *types); |
386 | 439 |
387 extern(C) int qtd_QMetaObject_indexOfMethod(void *nativeId, const(char) *method); | 440 extern(C) int qtd_QMetaObject_indexOfMethod(void *nativeId, const(char) *method); |
388 extern(C) int qtd_QMetaObject_methodCount(void *nativeId); | 441 extern(C) int qtd_QMetaObject_methodCount(void *nativeId); |
389 | 442 |
390 extern(C) void* qtd_QMetaObject_superClass(void* nativeId); | 443 extern(C) void* qtd_QMetaObject_superClass(void* nativeId); |