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