comparison d2/qtd/MOC.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 970332a88b72
children 12cec2d14e1c
comparison
equal deleted inserted replaced
349:925386e0e780 350:31520b2c0b3c
1 module qtd.MOC; 1 module qtd.MOC;
2 2
3 import std.typetuple; 3 import
4 4 std.typetuple,
5 import qt.QGlobal; 5 std.traits,
6 import qtd.Signal; 6 std.typetuple,
7 import qtd.Marshal; 7 std.conv,
8 import qtd.Meta; 8 qt.QGlobal,
9 import qtd.ctfe.Format; 9 qtd.Signal,
10 10 qtd.Marshal,
11 public import qt.core.QString; 11 qtd.Array,
12 12 qtd.Str,
13 public import std.traits; 13 qtd.meta.Compiletime,
14 qtd.ctfe.Format;
15
16 import qt.core.QString;
17
14 /** 18 /**
15 Utils. 19 Utils.
16 */ 20 */
17
18 bool is_digit_char(const char s)
19 {
20 return (s >= '0' && s <= '9');
21 }
22
23 bool is_octal_char(const char s)
24 {
25 return (s >= '0' && s <= '7');
26 }
27
28 bool is_hex_char(const char s)
29 {
30 return ((s >= 'a' && s <= 'f')
31 || (s >= 'A' && s <= 'F')
32 || (s >= '0' && s <= '9')
33 );
34 }
35
36 int lastIndexOf(T)(T[] haystack, T[] needle, int from = -1) 21 int lastIndexOf(T)(T[] haystack, T[] needle, int from = -1)
37 { 22 {
38 auto l = haystack.length; 23 auto l = haystack.length;
39 auto ol = needle.length; 24 auto ol = needle.length;
40 int delta = l - ol; 25 int delta = l - ol;
42 from = delta; 27 from = delta;
43 if (from < 0 || from > l) 28 if (from < 0 || from > l)
44 return -1; 29 return -1;
45 if (from > delta) 30 if (from > delta)
46 from = delta; 31 from = delta;
47 32
48 while(from >= 0) 33 while(from >= 0)
49 { 34 {
50 if (haystack[from..from+ol] == needle) 35 if (haystack[from..from+ol] == needle)
51 return from; 36 return from;
52 from--; 37 from--;
53 } 38 }
54 return -1; 39 return -1;
55 }
56
57
58 T[] newArray(T)(size_t len, T[] from = [])
59 {
60 if (len == from.length)
61 return from;
62
63 if (!from.length)
64 from = [T.init];
65
66 if (from.length < len)
67 return newArray!T(len, from ~ from);
68
69 return from[0..len];
70 } 40 }
71 41
72 string replicate(int n, char value) 42 string replicate(int n, char value)
73 { 43 {
74 char[] ret = "".dup; 44 char[] ret = "".dup;
111 // string normalizedType; 81 // string normalizedType;
112 // string tag; 82 // string tag;
113 // string name; 83 // string name;
114 string sig; 84 string sig;
115 string arguments; 85 string arguments;
116 Access access; 86 Access access;
117 /* bool returnTypeIsVolatile; 87 /* bool returnTypeIsVolatile;
118 88
119 QList<ArgumentDef> arguments; 89 QList<ArgumentDef> arguments;
120 90
121 enum Access { Private, Protected, Public }; 91 enum Access { Private, Protected, Public };
161 const int startPos = i; 131 const int startPos = i;
162 ++i; 132 ++i;
163 auto ch = s[i]; 133 auto ch = s[i];
164 if (ch == 'x') { 134 if (ch == 'x') {
165 ++i; 135 ++i;
166 while (i < s.length && is_hex_char(s[i])) 136 while (i < s.length && isHexChar(s[i]))
167 ++i; 137 ++i;
168 } else if (is_octal_char(ch)) { 138 } else if (isOctalChar(ch)) {
169 while (i < startPos + 4 139 while (i < startPos + 4
170 && i < s.length 140 && i < s.length
171 && is_octal_char(s[i])) { 141 && isOctalChar(s[i])) {
172 ++i; 142 ++i;
173 } 143 }
174 } else { // single character escape sequence 144 } else { // single character escape sequence
175 i = qMin(i + 1, s.length); 145 i = qMin(i + 1, s.length);
176 } 146 }
251 221
252 QByteArray qualifiedClassNameIdentifier = cdef->qualified; 222 QByteArray qualifiedClassNameIdentifier = cdef->qualified;
253 qualifiedClassNameIdentifier.replace(':', '_'); 223 qualifiedClassNameIdentifier.replace(':', '_');
254 */ 224 */
255 bool isConstructible = false; 225 bool isConstructible = false;
256 226
257 FunctionDef[] propertyList, enumList, constructorList; 227 FunctionDef[] propertyList, enumList, constructorList;
258 int index = 12; 228 int index = 12;
259 gen.output ~= format_ctfe("static const uint[] qt_meta_data_${} = [\n", className); 229 gen.output ~= "private static const uint[] qt_meta_data = [\n";
260 gen.output ~= format_ctfe("\n // content:\n"); 230 gen.output ~= format_ctfe("\n // content:\n");
261 gen.output ~= format_ctfe(" ${}, // revision\n", 2); 231 gen.output ~= format_ctfe(" ${}, // revision\n", 2);
262 gen.output ~= format_ctfe(" ${}, // classname\n", strreg(gen, className)); 232 gen.output ~= format_ctfe(" ${}, // classname\n", strreg(gen, className));
263 gen.output ~= format_ctfe(" ${}, ${}, // classinfo\n", 0, 0); 233 gen.output ~= format_ctfe(" ${}, ${}, // classinfo\n", 0, 0);
264 // index += cdef->classInfoList.count() * 2; 234 // index += cdef->classInfoList.count() * 2;
321 gen.output ~= format_ctfe("\n 0 // eod\n];\n\n"); 291 gen.output ~= format_ctfe("\n 0 // eod\n];\n\n");
322 292
323 // 293 //
324 // Build stringdata array 294 // Build stringdata array
325 // 295 //
326 gen.output ~= format_ctfe("static const string qt_meta_stringdata_${} = \n", className); 296 gen.output ~= "private static const string qt_meta_stringdata = \n";
327 gen.output ~= format_ctfe(" \""); 297 gen.output ~= format_ctfe(" \"");
328 int col = 0; 298 int col = 0;
329 int len = 0; 299 int len = 0;
330 foreach (i, s; gen.strings) { 300 foreach (i, s; gen.strings) {
331 len = s.length; 301 len = s.length;
356 326
357 gen.output ~= "\\0"; 327 gen.output ~= "\\0";
358 col += len + 2; 328 col += len + 2;
359 } 329 }
360 gen.output ~= "\";\n\n"; 330 gen.output ~= "\";\n\n";
361 331
362 return gen.output; 332 return gen.output;
363 }
364
365 string metaCallArgs(Args...)()
366 {
367 string res;
368 foreach(i, _; Args) {
369 if (i > 0)
370 res ~= ",";
371 res ~= metaCallArgument!(Args[i])("_a[" ~ __toString(i+1) ~ "]");
372 }
373 return res;
374 } 333 }
375 334
376 string qtDeclArgs(Args...)() 335 string qtDeclArgs(Args...)()
377 { 336 {
378 string ret; 337 string ret;
383 ret ~= qtDeclArg!(Args[i]); 342 ret ~= qtDeclArg!(Args[i]);
384 } 343 }
385 return ret; 344 return ret;
386 } 345 }
387 346
388 string generate_qt_metacall(alias Signals, alias Slots)()
389 {
390 string res = "
391 protected int qt_metacall(QMetaObject.Call _c, int _id, void **_a)
392 {
393 _id = super.qt_metacall(_c, _id, _a);
394 if (_id < 0)
395 return _id;\n";
396
397 alias TypeTuple!(Signals.at, Slots.at) Methods;
398 enum methodCount = Methods.length;
399 if(methodCount)
400 {
401 res ~= "
402 if (_c == QMetaObject.Call.InvokeMetaMethod) {
403 switch (_id) {";
404 foreach(i, _; Repeat!(void, methodCount)) {
405 res ~= "
406 case " ~ __toString(i) ~ ": " ~ MetaEntryName!(Methods[i].at) ~ "(" ~ metaCallArgs!(MetaEntryArgs!(Methods[i].at))() ~ "); break;";
407 }
408 res ~= "\n default: ;\n }\n";
409 res ~= " _id -= " ~ __toString(methodCount) ~ ";";
410 res ~= "\n }";
411 }
412
413 res ~= "\n return _id;
414 }";
415 return res;
416 }
417
418 string dDeclArgs(Args...)() 347 string dDeclArgs(Args...)()
419 { 348 {
420 string ret; 349 string ret;
421 foreach(i, _; Args) 350 foreach(i, _; Args)
422 { 351 {
423 if (i > 0) 352 if (i > 0)
424 ret ~= ", "; 353 ret ~= ", ";
425 ret ~= fullDName!(Args[i]); 354 ret ~= fullName!(Args[i]);
426 } 355 }
427 return ret; 356 return ret;
428 }
429 string genMetaMethodsConstr(alias Funcs)(string className)
430 {
431 string res;
432 enum funcsCount = Funcs.at.length;
433 foreach(i, bogus; Repeat!(void, funcsCount))
434 {
435 res ~= " index++;\n" ~
436 " _staticMetaObject.addMethod(new " ~ className ~ "(signature!(" ~ dDeclArgs!(MetaEntryArgs!(Funcs.at[i].at))()~ ")(\"" ~ MetaEntryName!(Funcs.at[i].at) ~ "\"), index));\n\n";
437 }
438 return res;
439 }
440 string generateMetaObjectConstruction(alias Signals, alias Slots)()
441 {
442 string res;
443 res ~= "\n
444 private static void _populateMetaInfo() {
445 alias BaseClassesTuple!(typeof(this))[0] BaseClass;
446 int index = BaseClass.staticMetaObject().methodCount() - 1;\n\n";
447
448 res ~= genMetaMethodsConstr!(Signals)("QMetaSignal");
449 res ~= genMetaMethodsConstr!(Slots)("QMetaSlot");
450
451 res ~= "
452 }\n";
453 return res;
454 }
455
456 string generateQMetaObject(string className)
457 {
458 string res;
459 res ~= "
460 public QMetaObject metaObject() { return staticMetaObject(); }
461 private static __gshared QMetaObject _staticMetaObject;
462 private static __gshared QMetaObjectNative _nativeStaticMetaObject;
463 public static QMetaObject staticMetaObject()
464 {
465 if(!_staticMetaObject)
466 createStaticMetaObject();
467 return _staticMetaObject;
468 }
469 protected static void createStaticMetaObject() {
470 assert(!_staticMetaObject);
471 alias BaseClassesTuple!(typeof(this))[0] BaseClass;
472 if (!BaseClass._staticMetaObject)
473 BaseClass.createStaticMetaObject;
474 auto base = BaseClass._staticMetaObject;
475 _nativeStaticMetaObject = QMetaObjectNative(base.nativeId, qt_meta_stringdata_" ~ className ~ ".ptr,
476 qt_meta_data_" ~ className ~ ".ptr, null );
477
478 _staticMetaObject = new QMetaObject(&_nativeStaticMetaObject, base);
479 // _staticMetaObject.construct!(typeof(this));
480 _populateMetaInfo();
481 }\n\n";
482 return res;
483 } 357 }
484 358
485 size_t commaCount(int argCount) 359 size_t commaCount(int argCount)
486 { 360 {
487 size_t ret = 0; 361 size_t ret = 0;
488 if(argCount > 1) 362 if(argCount > 1)
489 ret = argCount - 1; 363 ret = argCount - 1;
490 return ret; 364 return ret;
491 } 365 }
492 366
493 FunctionDef[] genFuncDefs(alias Funcs, alias newFunc)() 367 FunctionDef[] generateFuncDefs(alias newFunc, Funcs...)()
494 { 368 {
495 typeof(return) res; 369 typeof(return) res;
496 enum funcsCount = Funcs.at.length; 370 enum funcsCount = Funcs.length;
497 foreach(i, bogus; Repeat!(void, funcsCount)) 371 foreach(i, bogus; Repeat!(void, funcsCount))
498 { 372 {
499 string args = replicate(commaCount((MetaEntryArgs!(Funcs.at[i].at)).length), ','); 373 alias ParameterTypeTuple!(Funcs[i]) Args;
500 string funcSig = MetaEntryName!(Funcs.at[i].at) ~ "(" ~ qtDeclArgs!(MetaEntryArgs!(Funcs.at[i].at))() ~ ")"; 374 string args = replicate(commaCount(Args.length), ',');
375 string funcSig = methodName!(Funcs[i]) ~ "(" ~ qtDeclArgs!(Args)() ~ ")";
501 res ~= newFunc(funcSig, args); 376 res ~= newFunc(funcSig, args);
502 } 377 }
503 return res; 378 return res;
504 } 379 }
505 380
507 { 382 {
508 } 383 }
509 384
510 // ------------------------------------------------------------------------------------------ 385 // ------------------------------------------------------------------------------------------
511 386
512 string generateSignalEmitters(alias Funcs)() 387 string generateSignalEmitters(uint signalCount)
513 { 388 {
514 string res; 389 string res = "";
515 enum funcsCount = Funcs.at.length; 390 foreach (i; 0..signalCount)
516 foreach(i, bogus; Repeat!(void, funcsCount)) 391 {
517 { 392 auto iStr = to!string(i);
518 res ~= SignalEmitter!(MetaEntryArgs!(Funcs.at[i].at))(SignalType.NewSignal, MetaEntryName!(Funcs.at[i].at), cast(string[])[], i); 393 res ~= "mixin SignalEmitter!(SignalKind.NewSignal, " ~ iStr ~ ");\n";
519 } 394 }
520 return res; 395 return res;
521 } 396 }
522 397
523 string generateSlotAliases(alias Funcs)() 398 private mixin template SlotAlias(alias slot)
524 { 399 {
525 string res; 400 mixin ("alias slot " ~ methodName!slot ~ ";");
526 enum funcsCount = Funcs.at.length; 401 }
527 foreach(i, bogus; Repeat!(void, funcsCount)) 402
528 { 403 string generateSlotAliases(uint slotCount)
529 string name = MetaEntryName!(Funcs.at[i].at); 404 {
530 res ~= format_ctfe(" alias slot_${} ${};\n", name, name); 405 string res = "";
406 foreach(i; 0..slotCount)
407 {
408 auto iStr = to!string(i);
409 res ~= "mixin SlotAlias!(slots[" ~ iStr ~ "]);\n";
531 } 410 }
532 return res; 411 return res;
533 } 412 }
534 413
535 414 string generateMetaCall(string methodName, size_t argCount)
536 string generateMetaInfo(T, alias Signals, alias Slots)()
537 { 415 {
538 string res = ""; 416 string res = "";
539 auto signalList = genFuncDefs!(Signals, newSignal)(); 417 foreach (i; 1..argCount)
540 auto slotList = genFuncDefs!(Slots, newSlot)(); 418 res ~= generateConvToD(i);
541 res ~= generateSignalEmitters!(Signals)(); 419
542 res ~= generateSlotAliases!(Slots)(); 420 res ~= methodName ~ "(";
543 res ~= generateCode(T.stringof, signalList, slotList); 421 foreach (i; 1..argCount)
544 res ~= generate_qt_metacall!(Signals, Slots); 422 {
545 res ~= generateMetaObjectConstruction!(Signals, Slots); 423 if (i > 1)
546 res ~= generateQMetaObject(T.stringof); 424 res ~= ", ";
547 return res; 425 res ~= "_out" ~ to!string(i);
548 } 426 }
549 427 return res ~ ");\n";
550 template Q_OBJECT() 428 }
551 { 429
552 alias findSignals!(typeof(this)) SignalFuncs; 430 string generateDispatchSwitch(size_t methodCount)
553 alias toMetaEntries!(SignalFuncs) SignalMetaEntries; 431 {
554 alias findSlots!(typeof(this)) SlotFuncs; 432 string res = "switch(_id) {\n";
555 alias toMetaEntries!(SlotFuncs) SlotMetaEntries; 433
556 434 foreach(i; 0..methodCount)
557 mixin(generateMetaInfo!(typeof(this), SignalMetaEntries, SlotMetaEntries)()); 435 {
558 // debug output 436 string iStr = to!string(i);
559 // pragma(msg, generateMetaInfo!(typeof(this), SignalMetaEntries, SlotMetaEntries)()); 437 res ~= " case " ~ iStr ~ ":\n";
560 } 438 res ~= " alias methods[" ~ iStr ~ "] method;\n";
439 res ~= " alias TypeTuple!(void, ParameterTypeTuple!method) Args;\n";
440 res ~= " mixin(generateMetaCall(methodName!method, Args.length));\n";
441 res ~= " break;\n";
442 }
443
444 res ~= " default:\n";
445
446 return res ~ "}\n";
447 }
448
449 mixin template Q_OBJECT()
450 {
451 import std.typetuple;
452 import qtd.Marshal;
453 import qt.core.QString; // for QStringUtil.toNative
454
455 public: // required to override the outside scope protection.
456
457 alias typeof(this) This;
458
459 alias findSignals!(This) signals;
460 alias findSlots!(This) slots;
461 alias TypeTuple!(signals, slots) methods;
462
463
464 mixin (generateSignalEmitters(signals.length));
465 mixin (generateSlotAliases(slots.length));
466
467 auto signalList = generateFuncDefs!(newSignal, signals)();
468 auto slotList = generateFuncDefs!(newSlot, slots)();
469 mixin (generateCode(typeof(this).stringof, signalList, slotList));
470
471 protected int qt_metacall(QMetaObject.Call _c, int _id, void **_a)
472 {
473 _id = super.qt_metacall(_c, _id, _a);
474
475 static if (methods.length)
476 {
477 if (_id < 0)
478 return _id;
479
480 if (_c == QMetaObject.Call.InvokeMetaMethod) {
481 //pragma(msg, generateDispatchSwitch(methods.length));
482 mixin (generateDispatchSwitch(methods.length));
483 }
484 _id -= methods.length;
485 }
486
487 return _id;
488 }
489
490 @property
491 override QMetaObject metaObject() const { return staticMetaObject(); }
492
493 private static __gshared QMetaObject _staticMetaObject;
494 private static __gshared QMetaObjectNative _nativeStaticMetaObject;
495
496 @property
497 static QMetaObject staticMetaObject()
498 {
499 // TODO: synchronize or enable static constructors in circular modules
500 if(!_staticMetaObject)
501 {
502 alias BaseClassesTuple!(This)[0] Base;
503
504 _nativeStaticMetaObject = QMetaObjectNative(
505 Base.staticMetaObject.nativeId,
506 qt_meta_stringdata.ptr,
507 qt_meta_data.ptr, null);
508
509 QMetaObject.create!This(&_nativeStaticMetaObject);
510 }
511 return _staticMetaObject;
512 }
513
514 /*internal*/ static void setStaticMetaObject(QMetaObject m)
515 {
516 _staticMetaObject = m;
517 }
518 }
519