Mercurial > projects > qtd
comparison qt/d1/qt/Signal.d @ 284:1f6923c8cba0
consistent emit syntax.
author | eldar |
---|---|
date | Fri, 16 Oct 2009 12:23:12 +0000 |
parents | 256ab6cb8e85 |
children |
comparison
equal
deleted
inserted
replaced
283:b61a413fc2f5 | 284:1f6923c8cba0 |
---|---|
815 foreach(ref c; connections) | 815 foreach(ref c; connections) |
816 c.free; | 816 c.free; |
817 } | 817 } |
818 } | 818 } |
819 | 819 |
820 //TODO: this could be avoided if named mixins didn't suck. | |
821 public struct SignalOps(int sigId, A...) | |
822 { | |
823 private SignalHandler sh; | |
824 enum { signalId = sigId } | |
825 | |
826 void connect(R, B...)(R function(B) fn, ConnectionFlags flags = ConnectionFlags.None) | |
827 { | |
828 alias CheckSlot!(typeof(fn), A) check; | |
829 auto invoker = Dg(&sh.invokeSlot!(typeof(fn), Fn, A)); | |
830 sh.connect(signalId, Fn(fn), invoker, flags); | |
831 } | |
832 | |
833 void connect(R, B...)(R delegate(B) dg, ConnectionFlags flags = ConnectionFlags.None) | |
834 { | |
835 alias CheckSlot!(typeof(dg), A) check; | |
836 auto invoker = Dg(&sh.invokeSlot!(typeof(dg), Dg, A)); | |
837 sh.connect(signalId, Dg(dg), invoker, flags); | |
838 } | |
839 | |
840 void disconnect(R, B...)(R function(B) fn) | |
841 { | |
842 sh.disconnect(signalId, Fn(fn)); | |
843 } | |
844 | |
845 void disconnect(R, B...)(R delegate(B) dg) | |
846 { | |
847 sh.disconnect(signalId, Dg(dg)); | |
848 } | |
849 | |
850 void emit(A args) | |
851 { | |
852 sh.emit(signalId, args); | |
853 } | |
854 | |
855 debug size_t slotCount() | |
856 { | |
857 return sh.slotCount(signalId); | |
858 } | |
859 } | |
860 | |
861 public template SignalHandlerOps() | 820 public template SignalHandlerOps() |
862 { | 821 { |
863 static assert (is(typeof(this.signalHandler)), | 822 static assert (is(typeof(this.signalHandler)), |
864 "SignalHandlerOps is already instantiated in " ~ typeof(this).stringof ~ " or one of its base classes"); | 823 "SignalHandlerOps is already instantiated in " ~ typeof(this).stringof ~ " or one of its base classes"); |
865 | 824 |
1094 static assert(0, "Signal " ~ name ~ " was not found."); | 1053 static assert(0, "Signal " ~ name ~ " was not found."); |
1095 } | 1054 } |
1096 } | 1055 } |
1097 | 1056 |
1098 | 1057 |
1058 public string SignalEmitter(A...)(SignalType signalType, string name, int index) | |
1059 { | |
1060 string fullArgs, args; | |
1061 static if (A.length) | |
1062 { | |
1063 fullArgs = A[0].stringof ~ " a0"; | |
1064 args = ", a0"; | |
1065 foreach(i, _; A[1..$]) | |
1066 { | |
1067 fullArgs ~= ", " ~ A[i+1].stringof ~ " a" ~ __toString(i+1); | |
1068 args ~= ", a" ~ __toString(i+1); | |
1069 } | |
1070 } | |
1071 string attribute; | |
1072 string sigName = name; | |
1073 if (signalType == SignalType.BindQtSignal) | |
1074 name ~= "_emit"; | |
1075 else | |
1076 attribute = "protected "; | |
1077 string str = attribute ~ "void " ~ name ~ "(" ~ fullArgs ~ ")" ~ | |
1078 "{ this.signalHandler.emit(" ~ __toString(index) ~ args ~ "); }"; | |
1079 return str; | |
1080 } | |
1081 | |
1099 /** | 1082 /** |
1100 Examples: | 1083 Examples: |
1101 ---- | 1084 ---- |
1102 struct Args | 1085 struct Args |
1103 { | 1086 { |
1126 } | 1109 } |
1127 } | 1110 } |
1128 } | 1111 } |
1129 ---- | 1112 ---- |
1130 */ | 1113 */ |
1114 | |
1115 enum SignalType | |
1116 { | |
1117 BindQtSignal, | |
1118 NewSignal | |
1119 } | |
1120 | |
1121 template BindQtSignal(string name, A...) | |
1122 { | |
1123 mixin SignalImpl!(0, name, SignalType.BindQtSignal, A); | |
1124 } | |
1125 | |
1131 template Signal(string name, A...) | 1126 template Signal(string name, A...) |
1132 { | 1127 { |
1133 mixin SignalImpl!(0, name, A); | 1128 mixin SignalImpl!(0, name, SignalType.NewSignal, A); |
1134 } | 1129 } |
1135 | 1130 |
1136 template SignalImpl(int index, string name, A...) | 1131 template SignalImpl(int index, string name, SignalType signalType, A...) |
1137 { | 1132 { |
1138 static if (is(typeof(mixin(typeof(this).stringof ~ ".__signal" ~ ToString!(index))))) | 1133 static if (is(typeof(mixin(typeof(this).stringof ~ ".__signal" ~ ToString!(index))))) |
1139 mixin SignalImpl!(index + 1, name, A); | 1134 mixin SignalImpl!(index + 1, name, signalType, A); |
1140 else | 1135 else |
1141 { | 1136 { |
1142 // mixed-in once | 1137 // mixed-in once |
1143 static if (!is(typeof(this.signalHandler))) | 1138 static if (!is(typeof(this.signalHandler))) |
1144 { | |
1145 mixin SignalHandlerOps; | 1139 mixin SignalHandlerOps; |
1146 } | 1140 |
1141 mixin (SignalEmitter!(A)(signalType, name, index)); | |
1147 mixin("public alias Tuple!(\"" ~ name ~ "\", index, A) __signal" ~ ToString!(index) ~ ";"); | 1142 mixin("public alias Tuple!(\"" ~ name ~ "\", index, A) __signal" ~ ToString!(index) ~ ";"); |
1148 mixin("SignalOps!(" ~ ToString!(index) ~ ", A) " ~ name ~ "(){ return SignalOps!(" | |
1149 ~ ToString!(index) ~ ", A)(signalHandler); }"); | |
1150 } | 1143 } |
1151 } | 1144 } |
1152 | 1145 |
1153 extern(C) alias void function(void*) SlotConnector; | 1146 extern(C) alias void function(void*) SlotConnector; |
1154 | 1147 |