Mercurial > projects > qtd
comparison qt/d2/qt/Signal.d @ 278:5df570e79cfc
new syntax for connecting using static information
author | eldar |
---|---|
date | Sun, 04 Oct 2009 12:14:03 +0000 |
parents | 501128ac7a2c |
children | 519befd5a5d1 |
comparison
equal
deleted
inserted
replaced
277:750ea0c5fe83 | 278:5df570e79cfc |
---|---|
10 * | 10 * |
11 */ | 11 */ |
12 module qt.Signal; | 12 module qt.Signal; |
13 | 13 |
14 public import qt.QGlobal; | 14 public import qt.QGlobal; |
15 public import std.metastrings; | 15 public import |
16 std.metastrings, | |
17 std.typetuple; | |
16 import core.stdc.stdlib : crealloc = realloc, cfree = free; | 18 import core.stdc.stdlib : crealloc = realloc, cfree = free; |
17 import core.stdc.string : memmove; | 19 import core.stdc.string : memmove; |
18 import | 20 import |
19 std.traits, | 21 std.traits, |
20 core.thread, | 22 core.thread, |
832 alias ParameterTypeTuple!(Slot) SlotArgs; | 834 alias ParameterTypeTuple!(Slot) SlotArgs; |
833 static if (i < SlotArgs.length) | 835 static if (i < SlotArgs.length) |
834 { | 836 { |
835 static assert (is(SlotArgs[i] : A[i]), "Argument " ~ ToString!(i) ~ | 837 static assert (is(SlotArgs[i] : A[i]), "Argument " ~ ToString!(i) ~ |
836 ":" ~ A[i].stringof ~ " of signal " ~ A.stringof ~ " is not implicitly convertible to parameter " | 838 ":" ~ A[i].stringof ~ " of signal " ~ A.stringof ~ " is not implicitly convertible to parameter " |
837 | 839 ~ SlotArgs[i].stringof ~ " of slot " ~ SlotArgs.stringof); |
838 | |
839 | |
840 | |
841 ~ SlotArgs[i].stringof ~ " of slot " ~ SlotArgs.stringof); | |
842 alias CheckSlotImpl!(Slot, i + 1, A) next; | 840 alias CheckSlotImpl!(Slot, i + 1, A) next; |
843 } | 841 } |
844 } | 842 } |
845 | 843 |
846 public template SignalHandlerOps() | 844 public template SignalHandlerOps() |
873 | 871 |
874 final void unblockSignals() | 872 final void unblockSignals() |
875 { | 873 { |
876 signalHandler.unblockSignals(); | 874 signalHandler.unblockSignals(); |
877 } | 875 } |
878 } | 876 |
877 void connect(string signalName, this T, R, B...)(R function(B) dg, ConnectionFlags flags = ConnectionFlags.None) | |
878 { | |
879 alias findSymbol!(SignalQualifier, T, signalName) sig; | |
880 alias CheckSlot!(typeof(fn), sig[2].at) check; | |
881 auto sh = signalHandler(); | |
882 auto invoker = Dg(&sh.invokeSlot!(typeof(fn), Fn, sig[2].at)); | |
883 sh.connect(sig[1], Fn(fn), invoker, flags); | |
884 } | |
885 | |
886 void connect(string signalName, this T, R, B...)(R delegate(B) dg, ConnectionFlags flags = ConnectionFlags.None) | |
887 { | |
888 alias findSymbol!(SignalQualifier, T, signalName) sig; | |
889 alias CheckSlot!(typeof(dg), sig[2].at) check; | |
890 auto sh = signalHandler(); | |
891 auto invoker = Dg(&sh.invokeSlot!(typeof(dg), Dg, sig[2].at)); | |
892 sh.connect(sig[1], Dg(dg), invoker, flags); | |
893 } | |
894 | |
895 void disconnect(string signalName, this T, R, B...)(R function(B) fn) | |
896 { | |
897 alias findSymbol!(SignalQualifier, T, signalName) sig; | |
898 auto sh = signalHandler(); | |
899 sh.disconnect(sig[1], Fn(fn)); | |
900 } | |
901 | |
902 void disconnect(string signalName, this T, R, B...)(R delegate(B) dg) | |
903 { | |
904 alias findSymbol!(SignalQualifier, T, signalName) sig; | |
905 auto sh = signalHandler(); | |
906 sh.disconnect(sig[1], Dg(dg)); | |
907 } | |
908 | |
909 debug size_t slotCount(string signalName, this T)() | |
910 { | |
911 alias findSymbol!(SignalQualifier, T, signalName) sig; | |
912 auto sh = signalHandler(); | |
913 return sh.slotCount(sig[1]); | |
914 } | |
915 } | |
916 | |
917 /** | |
918 New implementation. | |
919 */ | |
920 | |
921 public bool startsWith(T)(T[] source, T[] pattern) | |
922 { | |
923 return source.length >= pattern.length && source[0 .. pattern.length] == pattern[]; | |
924 } | |
925 | |
926 template TupleWrapper(A...) { alias A at; } | |
927 | |
928 string joinArgs(A...)() | |
929 { | |
930 string res = ""; | |
931 static if(A.length) | |
932 { | |
933 res = A[0].stringof; | |
934 foreach(k; A[1..$]) | |
935 res ~= "," ~ k.stringof; | |
936 } | |
937 return res; | |
938 } | |
939 | |
940 struct SignalQualifier | |
941 { | |
942 const string staticSymbolPrefix = "__signal"; | |
943 const string name = "signal"; | |
944 | |
945 static bool matches(alias source, string sigName)() | |
946 { | |
947 return startsWith(source.at[0], sigName); | |
948 } | |
949 } | |
950 | |
951 template staticSymbolName(Qualifier, int id) | |
952 { | |
953 const string staticSymbolName = Qualifier.staticSymbolPrefix ~ ToString!(id); | |
954 } | |
955 | |
956 template signatureString(string name, A...) | |
957 { | |
958 const string signatureString = name ~ "(" ~ joinArgs!(A) ~ ")"; | |
959 } | |
960 | |
961 template findSymbolImpl(Qualifier, C, int id, string key) | |
962 { | |
963 static if ( is(typeof(mixin("C." ~ staticSymbolName!(Qualifier, id)))) ) | |
964 { | |
965 mixin ("alias C." ~ staticSymbolName!(Qualifier, id) ~ " current;"); | |
966 static if ( Qualifier.matches!(TupleWrapper!(current), key)() ) { | |
967 alias current result; | |
968 } | |
969 else | |
970 alias findSymbolImpl!(Qualifier, C, id + 1, key).result result; | |
971 } | |
972 else | |
973 { | |
974 static assert(0, Qualifier.name ~ " " ~ key ~ " not found."); | |
975 } | |
976 } | |
977 | |
978 template findSymbol(Qualifier, C, string key) | |
979 { | |
980 alias findSymbolImpl!(Qualifier, C, 0, key).result findSymbol; | |
981 } | |
982 | |
983 /** ---------------- */ | |
984 | |
879 | 985 |
880 /** | 986 /** |
881 Examples: | 987 Examples: |
882 ---- | 988 ---- |
883 struct Args | 989 struct Args |
923 // mixed-in once | 1029 // mixed-in once |
924 static if (!is(typeof(this.signalHandler))) | 1030 static if (!is(typeof(this.signalHandler))) |
925 { | 1031 { |
926 mixin SignalHandlerOps; | 1032 mixin SignalHandlerOps; |
927 } | 1033 } |
928 mixin("private static const int __sig" ~ ToString!(index) ~ " = " ~ ToString!(index) ~ ";"); | 1034 /* deprecated */ mixin("private static const int __sig" ~ ToString!(index) ~ " = " ~ ToString!(index) ~ ";"); |
1035 mixin("public alias TypeTuple!(\"" ~ signatureString!(name, A) ~ "\", index, TupleWrapper!(A)) __signal" ~ ToString!(index) ~ ";"); | |
929 mixin("SignalOps!(" ~ ToString!(index) ~ ", A) " ~ name ~ "(){ return SignalOps!(" | 1036 mixin("SignalOps!(" ~ ToString!(index) ~ ", A) " ~ name ~ "(){ return SignalOps!(" |
930 ~ ToString!(index) ~ ", A)(signalHandler); }"); | 1037 ~ ToString!(index) ~ ", A)(signalHandler); }"); |
931 } | 1038 } |
932 } | 1039 } |
933 | 1040 |