comparison d2/qt/core/QMetaObject.d @ 357:9784459f0750

An attempt (failed due to optlink) to improve locality of declarations exported from QtD executables Q_CLASSINFO implementation Now Qtd can be built on Windows
author Max Samukha <maxter@spambox.com>
date Wed, 02 Jun 2010 19:38:05 +0300
parents 31520b2c0b3c
children a084e2df3776
comparison
equal deleted inserted replaced
356:12cec2d14e1c 357:9784459f0750
1 module qt.core.QMetaObject; 1 module qt.core.QMetaObject;
2 2
3 import qt.QGlobal; 3 import
4 import qt.core.QObject; 4 qt.QGlobal,
5 import qtd.QtdObject; 5 qt.core.QObject,
6 6 qtd.QtdObject,
7 import std.algorithm; 7 std.algorithm,
8 import std.string; 8 qtd.meta.Runtime,
9 import std.stdio; 9 qtd.meta.Compiletime,
10 10 qtd.Marshal,
11 import qtd.meta.Runtime; 11 qtd.MOC,
12 import qtd.Marshal; 12 std.string,
13 std.typetuple,
14 std.c.stdlib;
13 15
14 class QMetaArgument : Meta 16 class QMetaArgument : Meta
15 { 17 {
16 } 18 }
17 19
20 alias typeof(this) This; 22 alias typeof(this) This;
21 23
22 // QMetaArgument[] arguments; 24 // QMetaArgument[] arguments;
23 string signature; 25 string signature;
24 int indexOfMethod; 26 int indexOfMethod;
25 27
26 this(string signature_, int indexOfMethod_) 28 this(string signature_, int indexOfMethod_)
27 { 29 {
28 signature = signature_; 30 signature = signature_;
29 indexOfMethod = indexOfMethod_; 31 indexOfMethod = indexOfMethod_;
30 } 32 }
31 33
32 string args() const 34 string args() const
33 { 35 {
34 int openBracket = indexOf(signature, '('); 36 int openBracket = indexOf(signature, '(');
35 if(signature.length - openBracket - 2 > 0) 37 if(signature.length - openBracket - 2 > 0)
36 return signature[openBracket + 1 .. $-1]; 38 return signature[openBracket + 1 .. $-1];
37 else 39 else
38 return ""; 40 return "";
39 } 41 }
40 42
41 string name() const 43 string name() const
42 { 44 {
43 int openBracket = indexOf(signature, '('); 45 int openBracket = indexOf(signature, '(');
44 return signature[0..openBracket]; 46 return signature[0..openBracket];
45 } 47 }
53 } 55 }
54 56
55 class QMetaSignal : QMetaMethod 57 class QMetaSignal : QMetaMethod
56 { 58 {
57 alias typeof(this) This; 59 alias typeof(this) This;
58 60
59 this(string signature_, int indexOfMethod_) 61 this(string signature_, int indexOfMethod_)
60 { 62 {
61 super(signature_, indexOfMethod_); 63 super(signature_, indexOfMethod_);
62 } 64 }
63 65
68 } 70 }
69 71
70 class QMetaSlot : QMetaMethod 72 class QMetaSlot : QMetaMethod
71 { 73 {
72 alias typeof(this) This; 74 alias typeof(this) This;
73 75
74 this(string signature_, int indexOfMethod_) 76 this(string signature_, int indexOfMethod_)
75 { 77 {
76 super(signature_, indexOfMethod_); 78 super(signature_, indexOfMethod_);
77 } 79 }
78 80
100 final class QMetaObject 102 final class QMetaObject
101 { 103 {
102 alias typeof(this) This; 104 alias typeof(this) This;
103 105
104 private this() {} 106 private this() {}
105 107
106 enum Call 108 enum Call
107 { 109 {
108 InvokeMetaMethod, 110 InvokeMetaMethod,
109 ReadProperty, 111 ReadProperty,
110 WriteProperty, 112 WriteProperty,
114 QueryPropertyStored, 116 QueryPropertyStored,
115 QueryPropertyEditable, 117 QueryPropertyEditable,
116 QueryPropertyUser, 118 QueryPropertyUser,
117 CreateInstance 119 CreateInstance
118 } 120 }
119 121
120 private 122 private
121 { 123 {
122 QMetaObjectNative* _nativeId; 124 QMetaObjectNative* _nativeId;
123 QMetaObject _base; // super class 125 QMetaObject _base; // super class
124 QMetaObject _firstDerived; // head of the linked list of derived classes 126 QMetaObject _firstDerived; // head of the linked list of derived classes
206 +/ 208 +/
207 QMetaObject base() 209 QMetaObject base()
208 { 210 {
209 return _base; 211 return _base;
210 } 212 }
211 213
212 /++ 214 /++
213 +/ 215 +/
214 QMetaObjectNative* nativeId() 216 QMetaObjectNative* nativeId()
215 { 217 {
216 return _nativeId; 218 return _nativeId;
220 +/ 222 +/
221 ClassInfo classInfo() 223 ClassInfo classInfo()
222 { 224 {
223 return _classInfo; 225 return _classInfo;
224 } 226 }
225 227
226 const (QMetaMethod[]) methods() 228 const (QMetaMethod[]) methods()
227 { 229 {
228 return _methods; 230 return _methods;
229 } 231 }
230 232
231 void addMethod(QMetaMethod method_) 233 void addMethod(QMetaMethod method_)
232 { 234 {
233 _methods ~= method_; 235 _methods ~= method_;
234 } 236 }
235 237
236 QMetaMethod lookUpMethod(string slot) 238 QMetaMethod lookUpMethod(string slot)
237 { 239 {
238 foreach (method; _methods) 240 foreach (method; _methods)
239 if (method.signature == slot) 241 if (method.signature == slot)
240 return method; 242 return method;
241 if (_base) 243 if (_base)
242 return _base.lookUpMethod(slot); 244 return _base.lookUpMethod(slot);
243 else 245 else
244 return null; 246 return null;
245 } 247 }
246 248
247 QMetaSignal lookUpSignal(string signal) 249 QMetaSignal lookUpSignal(string signal)
248 { 250 {
249 foreach (method; _methods) 251 foreach (method; _methods)
250 if (method.signature == signal && cast(QMetaSignal)method) 252 if (method.signature == signal && cast(QMetaSignal)method)
251 return cast(QMetaSignal)method; 253 return cast(QMetaSignal)method;
274 result ~= cast(QMetaSignal)method; 276 result ~= cast(QMetaSignal)method;
275 if (_base) 277 if (_base)
276 result ~= _base.lookUpSignalOverloads(signalName); 278 result ~= _base.lookUpSignalOverloads(signalName);
277 return result; 279 return result;
278 } 280 }
279 281
280 private QMetaObject lookupDerived(void*[] moIds) 282 private QMetaObject lookupDerived(void*[] moIds)
281 { 283 {
282 assert (moIds.length >= 1); 284 assert (moIds.length >= 1);
283 285
284 for (auto mo = _firstDerived; mo !is null; mo = mo._next) 286 for (auto mo = _firstDerived; mo !is null; mo = mo._next)
285 { 287 {
286 if (mo._nativeId == moIds[0]) 288 if (mo._nativeId == moIds[0])
287 { 289 {
288 if (moIds.length == 1) // exact match found 290 if (moIds.length == 1) // exact match found
289 return mo; 291 return mo;
290 else // look deeper 292 else // look deeper
291 return mo.lookupDerived(moIds[1..$]); 293 return mo.lookupDerived(moIds[1..$]);
292 } 294 }
293 } 295 }
294 296
295 // no initialized wrapper that matches the native object. 297 // no initialized wrapper that matches the native object.
296 // use the base class wrapper 298 // use the base class wrapper
297 return this; 299 return this;
298 } 300 }
299 301
300 QObject getObject(void* nativeObjId) 302 QObject getObject(void* nativeObjId)
301 { 303 {
302 QObject result; 304 QObject result;
303 305
304 if (nativeObjId) 306 if (nativeObjId)
305 { 307 {
306 result = cast(QObject)qtd_get_d_qobject(nativeObjId); 308 result = cast(QObject)qtd_get_d_qobject(nativeObjId);
307 if (!result) 309 if (!result)
308 { 310 {
309 auto moId = qtd_QObject_metaObject(nativeObjId); 311 auto moId = qtd_QObject_metaObject(nativeObjId);
310 if (_nativeId == moId) 312 if (_nativeId == moId)
311 result = _createWrapper(nativeObjId); 313 result = _createWrapper(nativeObjId);
315 // up to, but not including, the current metaobject. 317 // up to, but not including, the current metaobject.
316 size_t moCount = 1; 318 size_t moCount = 1;
317 319
318 for (void* tmp = moId;;) 320 for (void* tmp = moId;;)
319 { 321 {
320 tmp = qtd_QMetaObject_superClass(tmp); 322 tmp = qtd_QMetaObject_superClass(tmp);
321 assert(tmp); 323 assert(tmp);
322 if (tmp == _nativeId) 324 if (tmp == _nativeId)
323 break; 325 break;
324 moCount++; 326 moCount++;
325 } 327 }
326 328
327 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount]; 329 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount];
335 } 337 }
336 } 338 }
337 339
338 return result; 340 return result;
339 } 341 }
340 342
341 static void activate(QObject sender, QMetaObject m, int local_signal_index, void **argv) 343 static void activate(QObject sender, QMetaObject m, int local_signal_index, void **argv)
342 { 344 {
343 qtd_QMetaObject_activate_3(sender.__nativeId, m.nativeId, local_signal_index, argv); 345 qtd_QMetaObject_activate_3(sender.__nativeId, m.nativeId, local_signal_index, argv);
344 } 346 }
345 347
346 static void activate(QObject sender, QMetaObject m, int from_local_signal_index, int to_local_signal_index, void **argv) 348 static void activate(QObject sender, QMetaObject m, int from_local_signal_index, int to_local_signal_index, void **argv)
347 { 349 {
348 qtd_QMetaObject_activate_4(sender.__nativeId, m.nativeId, from_local_signal_index, to_local_signal_index, argv); 350 qtd_QMetaObject_activate_4(sender.__nativeId, m.nativeId, from_local_signal_index, to_local_signal_index, argv);
349 } 351 }
350 352
352 const QObject receiver, int method_index, 354 const QObject receiver, int method_index,
353 int type = 0, int *types = null) 355 int type = 0, int *types = null)
354 { 356 {
355 return qtd_QMetaObject_connect(sender.__nativeId, signal_index, receiver.__nativeId, method_index, type, types); 357 return qtd_QMetaObject_connect(sender.__nativeId, signal_index, receiver.__nativeId, method_index, type, types);
356 } 358 }
357 359
358 int indexOfMethod_Cpp(string method) 360 int indexOfMethod_Cpp(string method)
359 { 361 {
360 return qtd_QMetaObject_indexOfMethod(_nativeId, toStringz(method)); 362 return qtd_QMetaObject_indexOfMethod(_nativeId, toStringz(method));
361 } 363 }
362 364
421 } 423 }
422 else 424 else
423 { 425 {
424 int signalIndex = signal.indexOfMethod; 426 int signalIndex = signal.indexOfMethod;
425 int methodIndex = method.indexOfMethod; 427 int methodIndex = method.indexOfMethod;
428
426 success = QMetaObject.connect(sender, signalIndex, receiver, methodIndex, type); 429 success = QMetaObject.connect(sender, signalIndex, receiver, methodIndex, type);
427 } 430 }
428 431
429 if(!success) 432 if(!success)
430 throw new QMetaException("QMetaObject: Signal " ~ signalString ~ " and slot " ~ methodString ~ " cannot be found"); 433 throw new QMetaException("QMetaObject: Signal " ~ signalString ~ " cannot be connected to slot " ~ methodString);
434 }
435 }
436
437 /**
438 */
439 mixin template Q_CLASSINFO(string name, string value)
440 {
441 mixin InnerAttribute!("Q_CLASSINFO", AttributeOptions.allowMultiple, name, value);
442 }
443
444 version (QtdUnittest)
445 {
446 unittest
447 {
448 static class Test : QObject
449 {
450 mixin Q_CLASSINFO!("author", "Sabrina Schweinsteiger");
451 mixin Q_CLASSINFO!("url", "http://doc.moosesoft.co.uk/1.0/");
452
453 mixin Q_OBJECT;
454 }
431 } 455 }
432 } 456 }
433 457
434 extern(C) void qtd_QMetaObject_activate_3(void* sender, void* m, int local_signal_index, void **argv); 458 extern(C) void qtd_QMetaObject_activate_3(void* sender, void* m, int 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); 459 extern(C) void qtd_QMetaObject_activate_4(void *sender, void* m, int from_local_signal_index, int to_local_signal_index, void **argv);