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