# HG changeset patch # User eldar_ins@eldar-laptop # Date 1261759712 -18000 # Node ID 894d40eb89b6fdc4d0b99de6da4d7b9bc38af56f # Parent ce07227f00c1724a911dec67f505073ba76062b2 new signals and slots syntax. have to use prefixes now: signal_fooed and slot_onFooed diff -r ce07227f00c1 -r 894d40eb89b6 build/core.txt --- a/build/core.txt Thu Dec 24 05:19:40 2009 +0500 +++ b/build/core.txt Fri Dec 25 21:48:32 2009 +0500 @@ -24,6 +24,7 @@ qtd/Atomic qtd/MetaMarshall qtd/MOC + qtd/Meta qtd/util/Tuple qtd/ctfe/Integer qtd/ctfe/String diff -r ce07227f00c1 -r 894d40eb89b6 qt/d2/qt/Signal.d --- a/qt/d2/qt/Signal.d Thu Dec 24 05:19:40 2009 +0500 +++ b/qt/d2/qt/Signal.d Fri Dec 25 21:48:32 2009 +0500 @@ -13,6 +13,7 @@ public import qt.QGlobal; import qt.qtd.MetaMarshall; +import qt.qtd.Meta; import core.stdc.stdlib : crealloc = realloc, cfree = free; import core.stdc.string : memmove; @@ -29,7 +30,12 @@ std.metastrings; -// returns name, arguments or tuple of the function depending on type parameter +/* returns name, arguments or tuple of the function depending on type parameter + foo(int, float) + _Name: "foo" + _Tuple: "(int, float)" + _Args: "int, float" +*/ enum {_Name, _Tuple, _Args} string getFunc(int type)(string fullName) { @@ -38,10 +44,10 @@ if (c == '(') static if (type == _Tuple) return fullName[i..$]; - else if (type == _Name) + else static if (type == _Name) return fullName[0..i]; - else if (type == _Args) - for(int j = fullName.length-1;; j--) + else static if (type == _Args) + for(int j = fullName.length-1; ; j--) if(fullName[j] == ')') return fullName[i+1 .. j]; return null; @@ -136,7 +142,7 @@ template MetaEntryArgs(source...) { - alias source[3 .. $] MetaEntryArgs; // arguments-tuple starts from the fourth position + alias ParameterTypeTuple!(source[1]) MetaEntryArgs; // arguments-tuple starts from the fourth position } template TupleWrapper(A...) { alias A at; } @@ -491,4 +497,116 @@ enum lastSignalIndexImpl = lastSignalIndexImpl!(T, index + 1); else enum lastSignalIndexImpl = index - 1; +} + +// ------------------------------------------------------------------ + +string[] getSymbols(C)(string prefix) +{ + string[] result; + auto allSymbols = __traits(derivedMembers, C); + foreach(s; allSymbols) + if(ctfeStartsWith(s, prefix)) + result ~= s; + return result; +} + +string removePrefix(string source) +{ + foreach (i, c; source) + if (c == '_') + return source[i+1..$]; + return source; +} + +template Alias(T...) +{ + alias T Alias; +} + +// recursive search in the static meta-information +template findSymbolsImpl2(C, alias signals, int id) +{ + alias Alias!(__traits(getOverloads, C, signals[id])) current; + static if (signals.length - id - 1 > 0) + alias TypeTuple!(current, findSymbolsImpl2!(C, signals, id + 1).result) result; + else + alias current result; +} + +template findSymbols2(C, string prefix) +{ + enum signals = getSymbols!(C)(prefix); + static if (signals) + alias findSymbolsImpl2!(C, signals, 0).result result; + else + alias TypeTuple!() result; +} + +template findSignals(C) +{ + alias findSymbols2!(C, "signal_").result findSignals; +} + +template findSlots(C) +{ + alias findSymbols2!(C, "slot_").result findSlots; +} + + +template metaMethods(alias func, int index, int defValsCount) +{ + static if(defValsCount >= 0) { + alias TupleWrapper!(func, index) current; +// pragma(msg, __traits(identifier, (current.at)[0]) ~ " " ~ typeof(&(current.at)[0]).stringof); + alias metaMethods!(func, index+1, defValsCount-1).result next; + alias TypeTuple!(current, next) result; + } + else + { + alias TypeTuple!() result; + } +} + +template toMetaEntriesImpl(int id, Methods...) +{ + static if (Methods.length > id) + { + alias typeof(&Methods[id]) Fn; +// enum defValsLength = 0; //ParameterTypeTuple!(Fn).length - requiredArgCount!(Methods[id])(); +// pragma(msg, __traits(identifier, Methods[id]) ~ " " ~ typeof(&Methods[id]).stringof); +// alias metaMethods!(Methods[id], 0, defValsLength).result subres; + alias TupleWrapper!(removePrefix(__traits(identifier, Methods[id])), typeof(&Methods[id])) subres; + alias TypeTuple!(subres, toMetaEntriesImpl!(id+1, Methods).result) result; + } + else + { + alias TypeTuple!() result; + } +} + +template toMetaEntries(Methods...) +{ + alias TupleWrapper!(toMetaEntriesImpl!(0, Methods).result) toMetaEntries; +} + + +bool printRawFuncs(T...)() +{ + pragma(msg, "---Raw---"); + foreach(i, _; T) + pragma(msg, __traits(identifier, T[i]) ~ " " ~ typeof(&T[i]).stringof); + return true; +} + + +bool printFuncs(alias T)() +{ + pragma(msg, "---MetaEntries---"); + alias T.at tuple; + enum num = tuple.length; + foreach(i, _; Repeat!(void, num)) + pragma(msg, tuple[i].at[0] ~ " " ~ tuple[i].at[1].stringof); +// pragma(msg, typeof(&tuple[i].at[0]).stringof ~ " " ~ __toString(tuple[i].at[1])); + return true; } \ No newline at end of file diff -r ce07227f00c1 -r 894d40eb89b6 qt/qtd/MOC.d --- a/qt/qtd/MOC.d Thu Dec 24 05:19:40 2009 +0500 +++ b/qt/qtd/MOC.d Fri Dec 25 21:48:32 2009 +0500 @@ -6,6 +6,8 @@ import qt.Signal; import qt.qtd.MetaMarshall; +import qt.qtd.Meta; + public import qt.core.QString; public import std.traits; @@ -83,12 +85,6 @@ return cast(string)ret; } -template Repeat(T, int I) -{ - static if (!I) alias TypeTuple!() Repeat; - else alias TypeTuple!(T, Repeat!(T, I - 1)) Repeat; -} - /** CTFE MOC port. */ @@ -409,7 +405,7 @@ res ~= " if (_c == QMetaObject.Call.InvokeMetaMethod) { switch (_id) {"; - foreach(i, bogus; Repeat!(void, methodCount)) { + foreach(i, _; Repeat!(void, methodCount)) { res ~= " case " ~ __toString(i) ~ ": " ~ MetaEntryName!(Methods[i].at) ~ "(" ~ metaCallArgs!(MetaEntryArgs!(Methods[i].at))() ~ "); break;"; } @@ -506,23 +502,11 @@ return res; } -string generateMetaInfo(string className, alias Signals, alias Slots)() -{ - string res = ""; - auto signalList = genFuncDefs!(Signals, newSignal)(); - auto slotList = genFuncDefs!(Slots, newSlot)(); - res ~= generateCode(className, signalList, slotList); - res ~= generate_qt_metacall!(Signals, Slots); - res ~= generateMetaObjectConstruction!(Signals, Slots); - res ~= generateQMetaObject(className); - return res; -} - template Q_OBJECT_BIND() { mixin ("enum lastSignalIndex_" ~ typeof(this).stringof ~ " = " ~ toStringNow!(lastSignalIndex!(typeof(this))) ~ ";"); } - +/* template Q_OBJECT() { // pragma(msg, toStringNow!(lastSignalIndex!(typeof(this)))); @@ -533,3 +517,54 @@ pragma(msg, generateMetaInfo!((typeof(this)).stringof, Signals, Slots)()); mixin(generateMetaInfo!((typeof(this)).stringof, Signals, Slots)()); } +*/ +// ------------------------------------------------------------------------------------------ + +string generateSignalEmitters(alias Funcs)() +{ + string res; + enum funcsCount = Funcs.at.length; + foreach(i, bogus; Repeat!(void, funcsCount)) + { + res ~= SignalEmitter!(MetaEntryArgs!(Funcs.at[i].at))(SignalType.NewSignal, MetaEntryName!(Funcs.at[i].at), [], i); + } + return res; +} + +string generateSlotAliases(alias Funcs)() +{ + string res; + enum funcsCount = Funcs.at.length; + foreach(i, bogus; Repeat!(void, funcsCount)) + { + string name = MetaEntryName!(Funcs.at[i].at); + res ~= format_ctfe(" alias slot_${} ${};\n", name, name); + } + return res; +} + + +string generateMetaInfo(T, alias Signals, alias Slots)() +{ + string res = ""; + auto signalList = genFuncDefs!(Signals, newSignal)(); + auto slotList = genFuncDefs!(Slots, newSlot)(); + res ~= generateSignalEmitters!(Signals)(); + res ~= generateSlotAliases!(Slots)(); + res ~= generateCode(T.stringof, signalList, slotList); + res ~= generate_qt_metacall!(Signals, Slots); + res ~= generateMetaObjectConstruction!(Signals, Slots); + res ~= generateQMetaObject(T.stringof); + return res; +} + +template Q_OBJECT() +{ + alias findSignals!(typeof(this)) SignalFuncs; + alias toMetaEntries!(SignalFuncs) SignalMetaEntries; + alias findSlots!(typeof(this)) SlotFuncs; + alias toMetaEntries!(SlotFuncs) SlotMetaEntries; + + mixin(generateMetaInfo!(typeof(this), SignalMetaEntries, SlotMetaEntries)()); + pragma(msg, generateMetaInfo!(typeof(this), SignalMetaEntries, SlotMetaEntries)()); +} \ No newline at end of file diff -r ce07227f00c1 -r 894d40eb89b6 qt/qtd/Meta.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qt/qtd/Meta.d Fri Dec 25 21:48:32 2009 +0500 @@ -0,0 +1,68 @@ +module qt.qtd.Meta; + +import std.traits; +import std.typetuple; + +// Various compile time utilities + +public bool ctfeStartsWith(T)(T[] source, T[] pattern) +{ + return source.length >= pattern.length && source[0 .. pattern.length] == pattern[]; +} + +// compile-time toString, maybe to!string is already working in CT +string __toString(long v) +{ + if (v == 0) + return "0"; + + string ret; + + bool neg; + if (v < 0) + { + neg = true; + v = -v; + } + + while (v != 0) + { + ret = cast(char)(v % 10 + '0') ~ ret; + v = cast(long)(v / 10); + } + + if (neg) + ret = "-" ~ ret; + + return ret; +} + +// returns the type of a template parameter if there is one +template templateParam(U : V!(U), alias V) +{ + alias U templateParam; +} + +// to workaround buggy foreach, returns a tuple of Ts of size I +template Repeat(T, int I) +{ + static if (!I) alias TypeTuple!() Repeat; + else alias TypeTuple!(T, Repeat!(T, I - 1)) Repeat; +} + +//returns number of required function arguments, optional arguments excluded +int requiredArgCount(alias fn)() { + alias ParameterTypeTuple!(typeof(&fn)) P; + P p; + static if (P.length == 0) + return 0; + + foreach(i, _; P) + { + static if (!__traits(compiles, fn(p[0..$-i-1]))) + { + return p.length - i; + } + } + return 0; +} \ No newline at end of file diff -r ce07227f00c1 -r 894d40eb89b6 qt/qtd/MetaMarshall.d --- a/qt/qtd/MetaMarshall.d Thu Dec 24 05:19:40 2009 +0500 +++ b/qt/qtd/MetaMarshall.d Fri Dec 25 21:48:32 2009 +0500 @@ -2,49 +2,7 @@ import std.traits; -// utilities -// shouldn't be here - -public bool startsWith(T)(T[] source, T[] pattern) -{ - return source.length >= pattern.length && source[0 .. pattern.length] == pattern[]; -} - -string __toString(long v) -{ - if (v == 0) - return "0"; - - string ret; - - bool neg; - if (v < 0) - { - neg = true; - v = -v; - } - - while (v != 0) - { - ret = cast(char)(v % 10 + '0') ~ ret; - v = cast(long)(v / 10); - } - - if (neg) - ret = "-" ~ ret; - - return ret; -} - -template templateParam(U : V!(U), alias V) -{ - alias U templateParam; -} - - -/* - * actual stuff - */ +import qt.qtd.Meta; template isQObjectType(T) // is a QObject type that belongs to the library { @@ -73,7 +31,7 @@ template isQList(T) { - enum isQList = startsWith(Unqual!(T).stringof, "QList!"); + enum isQList = ctfeStartsWith(Unqual!(T).stringof, "QList!"); } // converts an argumnent from C++ to D in qt_metacall