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