annotate qt/d2/qt/Signal.d @ 284:1f6923c8cba0

consistent emit syntax.
author eldar
date Fri, 16 Oct 2009 12:23:12 +0000
parents 256ab6cb8e85
children f9559a957be9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
e78566595089 initial import
mandel
parents:
diff changeset
1 /**
e78566595089 initial import
mandel
parents:
diff changeset
2 *
e78566595089 initial import
mandel
parents:
diff changeset
3 * Copyright: Copyright QtD Team, 2008-2009
e78566595089 initial import
mandel
parents:
diff changeset
4 * Authors: Max Samukha, Eldar Insafutdinov
e78566595089 initial import
mandel
parents:
diff changeset
5 * License: <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>
e78566595089 initial import
mandel
parents:
diff changeset
6 *
e78566595089 initial import
mandel
parents:
diff changeset
7 * Copyright QtD Team, 2008-2009
e78566595089 initial import
mandel
parents:
diff changeset
8 * Distributed under the Boost Software License, Version 1.0.
e78566595089 initial import
mandel
parents:
diff changeset
9 * (See accompanying file boost-license-1.0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
e78566595089 initial import
mandel
parents:
diff changeset
10 *
e78566595089 initial import
mandel
parents:
diff changeset
11 */
16
6faf3d3cb95e CMake: implement install and package targets.
SokoL_SD
parents: 1
diff changeset
12 module qt.Signal;
1
e78566595089 initial import
mandel
parents:
diff changeset
13
e78566595089 initial import
mandel
parents:
diff changeset
14 public import qt.QGlobal;
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
15 public import
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
16 std.metastrings,
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
17 std.typetuple;
1
e78566595089 initial import
mandel
parents:
diff changeset
18 import core.stdc.stdlib : crealloc = realloc, cfree = free;
e78566595089 initial import
mandel
parents:
diff changeset
19 import core.stdc.string : memmove;
e78566595089 initial import
mandel
parents:
diff changeset
20 import
e78566595089 initial import
mandel
parents:
diff changeset
21 std.traits,
188
7dd099050621 initial commit for D2 support
eldar
parents: 16
diff changeset
22 core.thread,
7dd099050621 initial commit for D2 support
eldar
parents: 16
diff changeset
23 core.exception;
1
e78566595089 initial import
mandel
parents:
diff changeset
24
e78566595089 initial import
mandel
parents:
diff changeset
25 private: // private by default
e78566595089 initial import
mandel
parents:
diff changeset
26
e78566595089 initial import
mandel
parents:
diff changeset
27 alias void delegate(Object) DEvent;
e78566595089 initial import
mandel
parents:
diff changeset
28
e78566595089 initial import
mandel
parents:
diff changeset
29 extern(C) void rt_attachDisposeEvent(Object o, DEvent e);
e78566595089 initial import
mandel
parents:
diff changeset
30 extern(C) void rt_detachDisposeEvent(Object o, DEvent e);
e78566595089 initial import
mandel
parents:
diff changeset
31 extern(C) Object _d_toObject(void* p);
e78566595089 initial import
mandel
parents:
diff changeset
32
e78566595089 initial import
mandel
parents:
diff changeset
33 void realloc(T)(ref T[] a, size_t length)
e78566595089 initial import
mandel
parents:
diff changeset
34 {
e78566595089 initial import
mandel
parents:
diff changeset
35 a = (cast(T*)crealloc(a.ptr, length * T.sizeof))[0..length];
e78566595089 initial import
mandel
parents:
diff changeset
36 if (!a.ptr)
188
7dd099050621 initial commit for D2 support
eldar
parents: 16
diff changeset
37 new OutOfMemoryError(__FILE__, __LINE__);
1
e78566595089 initial import
mandel
parents:
diff changeset
38 }
e78566595089 initial import
mandel
parents:
diff changeset
39
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
40
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
41 void append(T)(ref T[] a, T element)
1
e78566595089 initial import
mandel
parents:
diff changeset
42 {
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
43 auto newLen = a.length + 1;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
44 a = (cast(T*)crealloc(a.ptr, newLen * T.sizeof))[0..newLen];
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
45 if (!a.ptr)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
46 new OutOfMemoryError(__FILE__, __LINE__);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
47 a[newLen - 1] = element;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
48 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
49
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
50 void move(T)(ref T[] a, size_t src, size_t dest, size_t length)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
51 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
52 if (a.length > 1)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
53 memmove(a.ptr + dest, a.ptr + src, length * T.sizeof);
1
e78566595089 initial import
mandel
parents:
diff changeset
54 }
e78566595089 initial import
mandel
parents:
diff changeset
55
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
56 // COMPILER BUG: Though this is private cannot name it 'remove' because of conflicts
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
57 // with Array.remove
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
58 void erase(T)(ref T[] a, size_t i)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
59 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
60 auto newLen = a.length - 1;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
61 move(a, i + 1, i, newLen);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
62 realloc(a, newLen);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
63 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
64
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
65 version (QtdUnittest)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
66 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
67 unittest
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
68 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
69 int[] a;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
70 realloc(a, 16);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
71 assert(a.length == 16);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
72 foreach (i, ref e; a)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
73 e = i;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
74 realloc(a, 4096);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
75 assert(a.length == 4096);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
76 foreach (i, e; a[0..16])
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
77 assert(e == i);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
78 cfree(a.ptr);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
79 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
80 }
1
e78566595089 initial import
mandel
parents:
diff changeset
81
e78566595089 initial import
mandel
parents:
diff changeset
82 //TODO: should be in the standard library
e78566595089 initial import
mandel
parents:
diff changeset
83 struct STuple(A...)
e78566595089 initial import
mandel
parents:
diff changeset
84 {
e78566595089 initial import
mandel
parents:
diff changeset
85 static string genSTuple()
e78566595089 initial import
mandel
parents:
diff changeset
86 {
e78566595089 initial import
mandel
parents:
diff changeset
87 string r = "";
e78566595089 initial import
mandel
parents:
diff changeset
88 foreach (i, e; A)
e78566595089 initial import
mandel
parents:
diff changeset
89 r ~= A[i].stringof ~ " _" ~ ToString!(i) ~ ";";
e78566595089 initial import
mandel
parents:
diff changeset
90 return r;
e78566595089 initial import
mandel
parents:
diff changeset
91 }
e78566595089 initial import
mandel
parents:
diff changeset
92
e78566595089 initial import
mandel
parents:
diff changeset
93 mixin (genSTuple);
e78566595089 initial import
mandel
parents:
diff changeset
94 template at(size_t i) { mixin("alias _" ~ ToString!(i) ~ " at;"); };
e78566595089 initial import
mandel
parents:
diff changeset
95 }
e78566595089 initial import
mandel
parents:
diff changeset
96
253
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
97 enum SignalEventId
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
98 {
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
99 firstSlotConnected,
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
100 lastSlotDisconnected
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
101 }
1
e78566595089 initial import
mandel
parents:
diff changeset
102
e78566595089 initial import
mandel
parents:
diff changeset
103 public class SignalException : Exception
e78566595089 initial import
mandel
parents:
diff changeset
104 {
e78566595089 initial import
mandel
parents:
diff changeset
105 this(string msg)
e78566595089 initial import
mandel
parents:
diff changeset
106 {
e78566595089 initial import
mandel
parents:
diff changeset
107 super(msg);
e78566595089 initial import
mandel
parents:
diff changeset
108 }
e78566595089 initial import
mandel
parents:
diff changeset
109 }
e78566595089 initial import
mandel
parents:
diff changeset
110
e78566595089 initial import
mandel
parents:
diff changeset
111 struct Fn
e78566595089 initial import
mandel
parents:
diff changeset
112 {
e78566595089 initial import
mandel
parents:
diff changeset
113 void* funcptr;
e78566595089 initial import
mandel
parents:
diff changeset
114
190
a1b48a630f73 D2 support, simple stuff works now
eldar
parents: 188
diff changeset
115 static typeof(this) opCall(R, A...)(R function(A) fn)
1
e78566595089 initial import
mandel
parents:
diff changeset
116 {
190
a1b48a630f73 D2 support, simple stuff works now
eldar
parents: 188
diff changeset
117 typeof(this) r;
1
e78566595089 initial import
mandel
parents:
diff changeset
118 r.funcptr = fn;
e78566595089 initial import
mandel
parents:
diff changeset
119 return r;
e78566595089 initial import
mandel
parents:
diff changeset
120 }
e78566595089 initial import
mandel
parents:
diff changeset
121
e78566595089 initial import
mandel
parents:
diff changeset
122 template call(R)
e78566595089 initial import
mandel
parents:
diff changeset
123 {
e78566595089 initial import
mandel
parents:
diff changeset
124 R call(A...)(A args)
e78566595089 initial import
mandel
parents:
diff changeset
125 {
e78566595089 initial import
mandel
parents:
diff changeset
126 alias R function(A) Fn;
e78566595089 initial import
mandel
parents:
diff changeset
127 return (cast(Fn)funcptr)(args);
e78566595089 initial import
mandel
parents:
diff changeset
128 }
e78566595089 initial import
mandel
parents:
diff changeset
129 }
e78566595089 initial import
mandel
parents:
diff changeset
130
e78566595089 initial import
mandel
parents:
diff changeset
131 S get(S)()
e78566595089 initial import
mandel
parents:
diff changeset
132 {
e78566595089 initial import
mandel
parents:
diff changeset
133 static assert (is(typeof(*S.init) == function));
e78566595089 initial import
mandel
parents:
diff changeset
134 return cast(S)funcptr;
e78566595089 initial import
mandel
parents:
diff changeset
135 }
e78566595089 initial import
mandel
parents:
diff changeset
136 }
e78566595089 initial import
mandel
parents:
diff changeset
137
e78566595089 initial import
mandel
parents:
diff changeset
138 struct Dg
e78566595089 initial import
mandel
parents:
diff changeset
139 {
e78566595089 initial import
mandel
parents:
diff changeset
140 void* context;
e78566595089 initial import
mandel
parents:
diff changeset
141 void* funcptr;
e78566595089 initial import
mandel
parents:
diff changeset
142
190
a1b48a630f73 D2 support, simple stuff works now
eldar
parents: 188
diff changeset
143 static typeof(this) opCall(R, A...)(R delegate(A) dg)
1
e78566595089 initial import
mandel
parents:
diff changeset
144 {
190
a1b48a630f73 D2 support, simple stuff works now
eldar
parents: 188
diff changeset
145 typeof(this) r;
1
e78566595089 initial import
mandel
parents:
diff changeset
146 r.context = dg.ptr;
e78566595089 initial import
mandel
parents:
diff changeset
147 r.funcptr = dg.funcptr;
e78566595089 initial import
mandel
parents:
diff changeset
148 return r;
e78566595089 initial import
mandel
parents:
diff changeset
149 }
e78566595089 initial import
mandel
parents:
diff changeset
150
e78566595089 initial import
mandel
parents:
diff changeset
151 template call(R)
e78566595089 initial import
mandel
parents:
diff changeset
152 {
e78566595089 initial import
mandel
parents:
diff changeset
153 R call(A...)(A args)
e78566595089 initial import
mandel
parents:
diff changeset
154 {
e78566595089 initial import
mandel
parents:
diff changeset
155 R delegate(A) dg; // BUG: parameter storage classes are ignored
e78566595089 initial import
mandel
parents:
diff changeset
156 dg.ptr = context;
e78566595089 initial import
mandel
parents:
diff changeset
157 dg.funcptr = cast(typeof(dg.funcptr))funcptr;
e78566595089 initial import
mandel
parents:
diff changeset
158 return dg(args);
e78566595089 initial import
mandel
parents:
diff changeset
159 }
e78566595089 initial import
mandel
parents:
diff changeset
160 }
e78566595089 initial import
mandel
parents:
diff changeset
161
e78566595089 initial import
mandel
parents:
diff changeset
162 S get(S)()
e78566595089 initial import
mandel
parents:
diff changeset
163 {
e78566595089 initial import
mandel
parents:
diff changeset
164 static assert (is(S == delegate));
e78566595089 initial import
mandel
parents:
diff changeset
165 S r;
e78566595089 initial import
mandel
parents:
diff changeset
166 r.ptr = context;
e78566595089 initial import
mandel
parents:
diff changeset
167 r.funcptr = cast(typeof(r.funcptr))funcptr;
e78566595089 initial import
mandel
parents:
diff changeset
168 return r;
e78566595089 initial import
mandel
parents:
diff changeset
169 }
e78566595089 initial import
mandel
parents:
diff changeset
170 }
e78566595089 initial import
mandel
parents:
diff changeset
171
e78566595089 initial import
mandel
parents:
diff changeset
172 struct Slot(R)
e78566595089 initial import
mandel
parents:
diff changeset
173 {
e78566595089 initial import
mandel
parents:
diff changeset
174 alias R Receiver;
e78566595089 initial import
mandel
parents:
diff changeset
175
e78566595089 initial import
mandel
parents:
diff changeset
176 Receiver receiver;
e78566595089 initial import
mandel
parents:
diff changeset
177 Dg invoker;
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
178 ConnectionFlags flags;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
179
1
e78566595089 initial import
mandel
parents:
diff changeset
180 static if (is(Receiver == Dg))
e78566595089 initial import
mandel
parents:
diff changeset
181 {
e78566595089 initial import
mandel
parents:
diff changeset
182 static const isDelegate = true;
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
183
1
e78566595089 initial import
mandel
parents:
diff changeset
184 bool isDisposed()
e78566595089 initial import
mandel
parents:
diff changeset
185 {
e78566595089 initial import
mandel
parents:
diff changeset
186 return !receiver.funcptr;
e78566595089 initial import
mandel
parents:
diff changeset
187 }
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
188
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
189 void dispose()
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
190 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
191 receiver.funcptr = null;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
192 receiver.context = null;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
193 }
1
e78566595089 initial import
mandel
parents:
diff changeset
194
e78566595089 initial import
mandel
parents:
diff changeset
195 Object getObject()
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
196 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
197 return flags & ConnectionFlags.NoObject || !receiver.context
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
198 ? null : _d_toObject(receiver.context);
1
e78566595089 initial import
mandel
parents:
diff changeset
199 }
e78566595089 initial import
mandel
parents:
diff changeset
200 }
e78566595089 initial import
mandel
parents:
diff changeset
201 else
e78566595089 initial import
mandel
parents:
diff changeset
202 static const isDelegate = false;
e78566595089 initial import
mandel
parents:
diff changeset
203 }
e78566595089 initial import
mandel
parents:
diff changeset
204
e78566595089 initial import
mandel
parents:
diff changeset
205 enum SlotListId
e78566595089 initial import
mandel
parents:
diff changeset
206 {
e78566595089 initial import
mandel
parents:
diff changeset
207 Func, // function pointers
e78566595089 initial import
mandel
parents:
diff changeset
208 Weak, // object delegates stored in C heap
e78566595089 initial import
mandel
parents:
diff changeset
209 Strong // delegates stored in GC heap
e78566595089 initial import
mandel
parents:
diff changeset
210 }
e78566595089 initial import
mandel
parents:
diff changeset
211
e78566595089 initial import
mandel
parents:
diff changeset
212 /**
e78566595089 initial import
mandel
parents:
diff changeset
213 Used to specify the type of a signal-to-slot connection.
e78566595089 initial import
mandel
parents:
diff changeset
214
e78566595089 initial import
mandel
parents:
diff changeset
215 Examples:
e78566595089 initial import
mandel
parents:
diff changeset
216 ----
e78566595089 initial import
mandel
parents:
diff changeset
217 class Sender
e78566595089 initial import
mandel
parents:
diff changeset
218 {
e78566595089 initial import
mandel
parents:
diff changeset
219 mixin Signal!("changed");
e78566595089 initial import
mandel
parents:
diff changeset
220 void change()
e78566595089 initial import
mandel
parents:
diff changeset
221 {
e78566595089 initial import
mandel
parents:
diff changeset
222 changed.emit;
e78566595089 initial import
mandel
parents:
diff changeset
223 }
e78566595089 initial import
mandel
parents:
diff changeset
224 }
e78566595089 initial import
mandel
parents:
diff changeset
225
e78566595089 initial import
mandel
parents:
diff changeset
226
e78566595089 initial import
mandel
parents:
diff changeset
227 class Receiver
e78566595089 initial import
mandel
parents:
diff changeset
228 {
e78566595089 initial import
mandel
parents:
diff changeset
229 void alarm() {}
e78566595089 initial import
mandel
parents:
diff changeset
230 }
e78566595089 initial import
mandel
parents:
diff changeset
231
e78566595089 initial import
mandel
parents:
diff changeset
232 void main()
e78566595089 initial import
mandel
parents:
diff changeset
233 {
e78566595089 initial import
mandel
parents:
diff changeset
234 auto s = new Sender;
e78566595089 initial import
mandel
parents:
diff changeset
235 auto r = new Receiver;
e78566595089 initial import
mandel
parents:
diff changeset
236 s.changed.connect(&r.alarm); // now s weakly references r
e78566595089 initial import
mandel
parents:
diff changeset
237
e78566595089 initial import
mandel
parents:
diff changeset
238 r = null;
e78566595089 initial import
mandel
parents:
diff changeset
239 // collect garbage (assume there is no more reachable pointers
e78566595089 initial import
mandel
parents:
diff changeset
240 // to the receiver and it gets finalized)
e78566595089 initial import
mandel
parents:
diff changeset
241 ...
e78566595089 initial import
mandel
parents:
diff changeset
242
e78566595089 initial import
mandel
parents:
diff changeset
243 s.change;
e78566595089 initial import
mandel
parents:
diff changeset
244 // weak reference to the receiving object
e78566595089 initial import
mandel
parents:
diff changeset
245 // has been removed from the sender's connection lists.
e78566595089 initial import
mandel
parents:
diff changeset
246
e78566595089 initial import
mandel
parents:
diff changeset
247 r = new Receiver;
e78566595089 initial import
mandel
parents:
diff changeset
248 s.changed.connect(&r.alarm, ConnectionFlags.Strong);
e78566595089 initial import
mandel
parents:
diff changeset
249
e78566595089 initial import
mandel
parents:
diff changeset
250 r = null;
e78566595089 initial import
mandel
parents:
diff changeset
251 // collect garbage
e78566595089 initial import
mandel
parents:
diff changeset
252 ...
e78566595089 initial import
mandel
parents:
diff changeset
253 // the receiving object has not been finalized because s strongly references it.
e78566595089 initial import
mandel
parents:
diff changeset
254
e78566595089 initial import
mandel
parents:
diff changeset
255 s.change; // the receiver is called.
e78566595089 initial import
mandel
parents:
diff changeset
256 delete r;
e78566595089 initial import
mandel
parents:
diff changeset
257 s.change; // the receiver is disconnected from the sender.
e78566595089 initial import
mandel
parents:
diff changeset
258
e78566595089 initial import
mandel
parents:
diff changeset
259 static void foo()
e78566595089 initial import
mandel
parents:
diff changeset
260 {
e78566595089 initial import
mandel
parents:
diff changeset
261 }
e78566595089 initial import
mandel
parents:
diff changeset
262
e78566595089 initial import
mandel
parents:
diff changeset
263 s.changed.connect(&foo);
e78566595089 initial import
mandel
parents:
diff changeset
264 s.changed.emit; // foo is called.
e78566595089 initial import
mandel
parents:
diff changeset
265 s.changed.disconnect(&foo); // must be explicitly disconnected.
e78566595089 initial import
mandel
parents:
diff changeset
266
e78566595089 initial import
mandel
parents:
diff changeset
267 void bar()
e78566595089 initial import
mandel
parents:
diff changeset
268 {
e78566595089 initial import
mandel
parents:
diff changeset
269 }
e78566595089 initial import
mandel
parents:
diff changeset
270
e78566595089 initial import
mandel
parents:
diff changeset
271 // ConnectionFlags.NoObject must be specified for delegates
e78566595089 initial import
mandel
parents:
diff changeset
272 // to non-static local functions or struct member functions.
e78566595089 initial import
mandel
parents:
diff changeset
273 s.changed.connect(&bar, ConnectionFlags.NoObject);
e78566595089 initial import
mandel
parents:
diff changeset
274 s.changed.emit; // bar is called.
e78566595089 initial import
mandel
parents:
diff changeset
275 s.changed.disconnect(&bar); // must be explicitly disconnected.
e78566595089 initial import
mandel
parents:
diff changeset
276 }
e78566595089 initial import
mandel
parents:
diff changeset
277 ----
e78566595089 initial import
mandel
parents:
diff changeset
278 */
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
279 public enum ConnectionFlags : ubyte
1
e78566595089 initial import
mandel
parents:
diff changeset
280 {
e78566595089 initial import
mandel
parents:
diff changeset
281 ///
e78566595089 initial import
mandel
parents:
diff changeset
282 None,
e78566595089 initial import
mandel
parents:
diff changeset
283 /**
e78566595089 initial import
mandel
parents:
diff changeset
284 The receiver will be stored as weak reference (implied if ConnectionFlags.NoObject is not specified).
e78566595089 initial import
mandel
parents:
diff changeset
285 If the signal receiver is not a function pointer or a delegate referencing a D class instance.
e78566595089 initial import
mandel
parents:
diff changeset
286 the sender will not be notified when the receiving object is deleted and emitting the signal
e78566595089 initial import
mandel
parents:
diff changeset
287 connected to that receiving object will result in undefined behavior.
e78566595089 initial import
mandel
parents:
diff changeset
288 */
e78566595089 initial import
mandel
parents:
diff changeset
289 Weak = 0x0001,
e78566595089 initial import
mandel
parents:
diff changeset
290 /**
e78566595089 initial import
mandel
parents:
diff changeset
291 The receiver is stored as strong reference (implied if ConnectionFlags.NoObject is specified).
e78566595089 initial import
mandel
parents:
diff changeset
292 */
e78566595089 initial import
mandel
parents:
diff changeset
293 Strong = 0x0002,
e78566595089 initial import
mandel
parents:
diff changeset
294 /**
e78566595089 initial import
mandel
parents:
diff changeset
295 Must be specified if the receiver is not a function pointer or a delegate referencing a D class instance.
e78566595089 initial import
mandel
parents:
diff changeset
296 */
e78566595089 initial import
mandel
parents:
diff changeset
297 NoObject = 0x0004
e78566595089 initial import
mandel
parents:
diff changeset
298
e78566595089 initial import
mandel
parents:
diff changeset
299 // Queued = 0x0004,
e78566595089 initial import
mandel
parents:
diff changeset
300 // BlockingQueued = 0x0008
e78566595089 initial import
mandel
parents:
diff changeset
301 }
e78566595089 initial import
mandel
parents:
diff changeset
302
e78566595089 initial import
mandel
parents:
diff changeset
303
e78566595089 initial import
mandel
parents:
diff changeset
304 struct SlotList(SlotT, bool strong = false)
e78566595089 initial import
mandel
parents:
diff changeset
305 {
e78566595089 initial import
mandel
parents:
diff changeset
306 alias SlotT SlotType;
e78566595089 initial import
mandel
parents:
diff changeset
307 SlotType[] data;
e78566595089 initial import
mandel
parents:
diff changeset
308
e78566595089 initial import
mandel
parents:
diff changeset
309 void length(size_t length)
e78566595089 initial import
mandel
parents:
diff changeset
310 {
e78566595089 initial import
mandel
parents:
diff changeset
311 static if (strong)
e78566595089 initial import
mandel
parents:
diff changeset
312 data.length = length;
e78566595089 initial import
mandel
parents:
diff changeset
313 else
e78566595089 initial import
mandel
parents:
diff changeset
314 realloc(data, length);
e78566595089 initial import
mandel
parents:
diff changeset
315 }
e78566595089 initial import
mandel
parents:
diff changeset
316
e78566595089 initial import
mandel
parents:
diff changeset
317 SlotType* add(SlotType slot)
e78566595089 initial import
mandel
parents:
diff changeset
318 {
e78566595089 initial import
mandel
parents:
diff changeset
319 auto oldLen = data.length;
e78566595089 initial import
mandel
parents:
diff changeset
320 length = oldLen + 1;
e78566595089 initial import
mandel
parents:
diff changeset
321 auto p = &data[oldLen];
e78566595089 initial import
mandel
parents:
diff changeset
322 *p = slot;
e78566595089 initial import
mandel
parents:
diff changeset
323 return p;
e78566595089 initial import
mandel
parents:
diff changeset
324 }
e78566595089 initial import
mandel
parents:
diff changeset
325
e78566595089 initial import
mandel
parents:
diff changeset
326 SlotType* get(int slotId)
e78566595089 initial import
mandel
parents:
diff changeset
327 {
e78566595089 initial import
mandel
parents:
diff changeset
328 return &data[slotId];
e78566595089 initial import
mandel
parents:
diff changeset
329 }
e78566595089 initial import
mandel
parents:
diff changeset
330
e78566595089 initial import
mandel
parents:
diff changeset
331 void remove(int slotId)
e78566595089 initial import
mandel
parents:
diff changeset
332 {
e78566595089 initial import
mandel
parents:
diff changeset
333 move(data, slotId, slotId + 1, data.length - slotId - 1);
e78566595089 initial import
mandel
parents:
diff changeset
334 data = data[0..$ - 1];
e78566595089 initial import
mandel
parents:
diff changeset
335 }
e78566595089 initial import
mandel
parents:
diff changeset
336
e78566595089 initial import
mandel
parents:
diff changeset
337 size_t length()
e78566595089 initial import
mandel
parents:
diff changeset
338 {
e78566595089 initial import
mandel
parents:
diff changeset
339 return data.length;
e78566595089 initial import
mandel
parents:
diff changeset
340 }
e78566595089 initial import
mandel
parents:
diff changeset
341
e78566595089 initial import
mandel
parents:
diff changeset
342 void free()
e78566595089 initial import
mandel
parents:
diff changeset
343 {
e78566595089 initial import
mandel
parents:
diff changeset
344 static if (!strong)
e78566595089 initial import
mandel
parents:
diff changeset
345 cfree(data.ptr);
e78566595089 initial import
mandel
parents:
diff changeset
346 }
e78566595089 initial import
mandel
parents:
diff changeset
347 }
e78566595089 initial import
mandel
parents:
diff changeset
348
253
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
349 public alias void delegate(int signalId, SignalEventId event) SignalEvent;
1
e78566595089 initial import
mandel
parents:
diff changeset
350
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
351 struct Receivers
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
352 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
353 struct Data
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
354 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
355 Object object;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
356 int refs;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
357 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
358
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
359 Data[] data;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
360 void add(Object receiver, DEvent disposeEvent)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
361 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
362 foreach (ref d; data)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
363 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
364 if (d.object is receiver)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
365 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
366 d.refs++;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
367 return;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
368 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
369 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
370
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
371 append(data, Data(receiver, 1));
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
372 rt_attachDisposeEvent(receiver, disposeEvent);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
373 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
374
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
375 void remove(Object receiver, DEvent disposeEvent)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
376 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
377 foreach (i, ref d; data)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
378 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
379 if (d.object is receiver)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
380 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
381 assert (d.refs);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
382 d.refs--;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
383 if (!d.refs)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
384 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
385 .erase(data, i);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
386 rt_detachDisposeEvent(receiver, disposeEvent);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
387 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
388 return;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
389 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
390 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
391
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
392 assert (false);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
393 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
394
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
395 // remove all refarences for receiver, receiver has been disposed
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
396 void removeAll(Object receiver)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
397 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
398 foreach (i, ref d; data)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
399 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
400 if (d.object is receiver)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
401 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
402 .erase(data, i);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
403 return;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
404 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
405 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
406 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
407
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
408 // remove all references for all receivers, detaching dispose events
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
409 void free(DEvent disposeEvent)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
410 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
411 foreach (i, ref d; data)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
412 rt_detachDisposeEvent(d.object, disposeEvent);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
413 cfree(data.ptr);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
414 data = null;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
415 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
416 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
417
1
e78566595089 initial import
mandel
parents:
diff changeset
418 struct SignalConnections
e78566595089 initial import
mandel
parents:
diff changeset
419 {
e78566595089 initial import
mandel
parents:
diff changeset
420 bool isInUse;
e78566595089 initial import
mandel
parents:
diff changeset
421
e78566595089 initial import
mandel
parents:
diff changeset
422 STuple!(
e78566595089 initial import
mandel
parents:
diff changeset
423 SlotList!(Slot!(Fn)),
e78566595089 initial import
mandel
parents:
diff changeset
424 SlotList!(Slot!(Dg)),
e78566595089 initial import
mandel
parents:
diff changeset
425 SlotList!(Slot!(Dg), true)
e78566595089 initial import
mandel
parents:
diff changeset
426 ) slotLists;
e78566595089 initial import
mandel
parents:
diff changeset
427
e78566595089 initial import
mandel
parents:
diff changeset
428 STuple!(
e78566595089 initial import
mandel
parents:
diff changeset
429 Fn[],
e78566595089 initial import
mandel
parents:
diff changeset
430 Dg[]
e78566595089 initial import
mandel
parents:
diff changeset
431 ) delayedDisconnects;
e78566595089 initial import
mandel
parents:
diff changeset
432
e78566595089 initial import
mandel
parents:
diff changeset
433 void addDelayedDisconnect(Fn r)
e78566595089 initial import
mandel
parents:
diff changeset
434 {
e78566595089 initial import
mandel
parents:
diff changeset
435 delayedDisconnects.at!(0) ~= r;
e78566595089 initial import
mandel
parents:
diff changeset
436 }
e78566595089 initial import
mandel
parents:
diff changeset
437
e78566595089 initial import
mandel
parents:
diff changeset
438 void addDelayedDisconnect(Dg r)
e78566595089 initial import
mandel
parents:
diff changeset
439 {
e78566595089 initial import
mandel
parents:
diff changeset
440 delayedDisconnects.at!(1) ~= r;
e78566595089 initial import
mandel
parents:
diff changeset
441 }
e78566595089 initial import
mandel
parents:
diff changeset
442
e78566595089 initial import
mandel
parents:
diff changeset
443 SlotListType!(slotListId)* getSlotList(int slotListId)()
e78566595089 initial import
mandel
parents:
diff changeset
444 {
e78566595089 initial import
mandel
parents:
diff changeset
445 return &slotLists.tupleof[slotListId];
e78566595089 initial import
mandel
parents:
diff changeset
446 }
e78566595089 initial import
mandel
parents:
diff changeset
447
e78566595089 initial import
mandel
parents:
diff changeset
448 bool hasSlots()
e78566595089 initial import
mandel
parents:
diff changeset
449 {
e78566595089 initial import
mandel
parents:
diff changeset
450 foreach(i, e; slotLists.tupleof)
e78566595089 initial import
mandel
parents:
diff changeset
451 {
e78566595089 initial import
mandel
parents:
diff changeset
452 if (slotLists.tupleof[i].length)
e78566595089 initial import
mandel
parents:
diff changeset
453 return true;
e78566595089 initial import
mandel
parents:
diff changeset
454 }
e78566595089 initial import
mandel
parents:
diff changeset
455 return false;
e78566595089 initial import
mandel
parents:
diff changeset
456 }
e78566595089 initial import
mandel
parents:
diff changeset
457
e78566595089 initial import
mandel
parents:
diff changeset
458 int slotCount()
e78566595089 initial import
mandel
parents:
diff changeset
459 {
e78566595089 initial import
mandel
parents:
diff changeset
460 int count;
e78566595089 initial import
mandel
parents:
diff changeset
461 foreach(i, e; slotLists.tupleof)
e78566595089 initial import
mandel
parents:
diff changeset
462 count += slotLists.at!(i).length;
e78566595089 initial import
mandel
parents:
diff changeset
463 return count;
e78566595089 initial import
mandel
parents:
diff changeset
464 }
e78566595089 initial import
mandel
parents:
diff changeset
465
e78566595089 initial import
mandel
parents:
diff changeset
466 void slotListLengths(int[] lengths)
e78566595089 initial import
mandel
parents:
diff changeset
467 {
e78566595089 initial import
mandel
parents:
diff changeset
468 foreach(i, e; slotLists.tupleof)
e78566595089 initial import
mandel
parents:
diff changeset
469 lengths[i] = slotLists.at!(i).length;
e78566595089 initial import
mandel
parents:
diff changeset
470 }
e78566595089 initial import
mandel
parents:
diff changeset
471
e78566595089 initial import
mandel
parents:
diff changeset
472 SlotType!(slotListId)* addSlot(int slotListId)(SlotType!(slotListId) slot)
e78566595089 initial import
mandel
parents:
diff changeset
473 {
e78566595089 initial import
mandel
parents:
diff changeset
474 return getSlotList!(slotListId).add(slot);
e78566595089 initial import
mandel
parents:
diff changeset
475 }
e78566595089 initial import
mandel
parents:
diff changeset
476
e78566595089 initial import
mandel
parents:
diff changeset
477 void removeSlot(int slotListId)(int slotId)
e78566595089 initial import
mandel
parents:
diff changeset
478 {
e78566595089 initial import
mandel
parents:
diff changeset
479 slotLists.at!(slotListId).remove(slotId);
e78566595089 initial import
mandel
parents:
diff changeset
480 }
e78566595089 initial import
mandel
parents:
diff changeset
481
e78566595089 initial import
mandel
parents:
diff changeset
482 void free()
e78566595089 initial import
mandel
parents:
diff changeset
483 {
e78566595089 initial import
mandel
parents:
diff changeset
484 foreach(i, e; slotLists.tupleof)
e78566595089 initial import
mandel
parents:
diff changeset
485 {
e78566595089 initial import
mandel
parents:
diff changeset
486 static if (is(typeof(slotLists.at!(i).free)))
e78566595089 initial import
mandel
parents:
diff changeset
487 slotLists.at!(i).free;
e78566595089 initial import
mandel
parents:
diff changeset
488 }
e78566595089 initial import
mandel
parents:
diff changeset
489 }
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
490
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
491 void onReceiverDisposed(Object receiver)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
492 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
493 foreach (i, e; slotLists.tupleof)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
494 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
495 static if (slotLists.at!(i).SlotType.isDelegate)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
496 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
497 foreach (ref slot; slotLists.at!(i).data)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
498 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
499 if (slot.getObject is receiver)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
500 slot.dispose;
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
501 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
502 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
503 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
504 }
1
e78566595089 initial import
mandel
parents:
diff changeset
505
e78566595089 initial import
mandel
parents:
diff changeset
506 template SlotListType(int slotListId)
e78566595089 initial import
mandel
parents:
diff changeset
507 {
e78566595089 initial import
mandel
parents:
diff changeset
508 alias typeof(slotLists.tupleof)[slotListId] SlotListType;
e78566595089 initial import
mandel
parents:
diff changeset
509 }
e78566595089 initial import
mandel
parents:
diff changeset
510
e78566595089 initial import
mandel
parents:
diff changeset
511 template SlotType(int slotListId)
e78566595089 initial import
mandel
parents:
diff changeset
512 {
e78566595089 initial import
mandel
parents:
diff changeset
513 alias SlotListType!(slotListId).SlotType SlotType;
e78566595089 initial import
mandel
parents:
diff changeset
514 }
e78566595089 initial import
mandel
parents:
diff changeset
515
e78566595089 initial import
mandel
parents:
diff changeset
516 template ReceiverType(int slotListId)
e78566595089 initial import
mandel
parents:
diff changeset
517 {
e78566595089 initial import
mandel
parents:
diff changeset
518 alias SlotType!(slotListId).Receiver ReceiverType;
e78566595089 initial import
mandel
parents:
diff changeset
519 }
e78566595089 initial import
mandel
parents:
diff changeset
520
e78566595089 initial import
mandel
parents:
diff changeset
521 static const slotListCount = slotLists.tupleof.length;
e78566595089 initial import
mandel
parents:
diff changeset
522 }
e78566595089 initial import
mandel
parents:
diff changeset
523
e78566595089 initial import
mandel
parents:
diff changeset
524
268
cf6a4cd0e3f2 fix for #35
eldar
parents: 253
diff changeset
525 private Object signalSender_;
1
e78566595089 initial import
mandel
parents:
diff changeset
526
e78566595089 initial import
mandel
parents:
diff changeset
527 /**
e78566595089 initial import
mandel
parents:
diff changeset
528 If called from a slot, returns the object
e78566595089 initial import
mandel
parents:
diff changeset
529 that is emitting the signal. Otherwise, returns null.
e78566595089 initial import
mandel
parents:
diff changeset
530 */
e78566595089 initial import
mandel
parents:
diff changeset
531 public Object signalSender() {
268
cf6a4cd0e3f2 fix for #35
eldar
parents: 253
diff changeset
532 return signalSender_;
1
e78566595089 initial import
mandel
parents:
diff changeset
533 }
e78566595089 initial import
mandel
parents:
diff changeset
534
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
535 public final class SignalHandler
1
e78566595089 initial import
mandel
parents:
diff changeset
536 {
e78566595089 initial import
mandel
parents:
diff changeset
537 SignalConnections[] connections;
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
538 Receivers receivers;
1
e78566595089 initial import
mandel
parents:
diff changeset
539 Object owner;
e78566595089 initial import
mandel
parents:
diff changeset
540 int blocked;
253
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
541
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
542 SignalEvent signalEvent;
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
543
1
e78566595089 initial import
mandel
parents:
diff changeset
544 alias SignalConnections.SlotType SlotType;
e78566595089 initial import
mandel
parents:
diff changeset
545 alias SignalConnections.ReceiverType ReceiverType;
e78566595089 initial import
mandel
parents:
diff changeset
546
e78566595089 initial import
mandel
parents:
diff changeset
547 public this(Object owner_) {
e78566595089 initial import
mandel
parents:
diff changeset
548 owner = owner_;
e78566595089 initial import
mandel
parents:
diff changeset
549 }
e78566595089 initial import
mandel
parents:
diff changeset
550
e78566595089 initial import
mandel
parents:
diff changeset
551 private SignalConnections* getConnections(int signalId)
e78566595089 initial import
mandel
parents:
diff changeset
552 {
e78566595089 initial import
mandel
parents:
diff changeset
553 if (signalId < connections.length)
e78566595089 initial import
mandel
parents:
diff changeset
554 return &connections[signalId];
e78566595089 initial import
mandel
parents:
diff changeset
555 return null;
e78566595089 initial import
mandel
parents:
diff changeset
556 }
e78566595089 initial import
mandel
parents:
diff changeset
557
e78566595089 initial import
mandel
parents:
diff changeset
558 private SlotType!(slotListId)* addSlot(int slotListId)(int signalId, ReceiverType!(slotListId) receiver,
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
559 Dg invoker, ConnectionFlags flags)
1
e78566595089 initial import
mandel
parents:
diff changeset
560 {
e78566595089 initial import
mandel
parents:
diff changeset
561 if (signalId >= connections.length)
e78566595089 initial import
mandel
parents:
diff changeset
562 connections.length = signalId + 1;
e78566595089 initial import
mandel
parents:
diff changeset
563 auto slot = connections[signalId].addSlot!(slotListId)(SlotType!(slotListId)(receiver, invoker));
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
564
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
565 static if (slot.isDelegate)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
566 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
567 if (!(flags & ConnectionFlags.NoObject))
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
568 receivers.add(_d_toObject(receiver.context), &onReceiverDisposed);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
569 }
1
e78566595089 initial import
mandel
parents:
diff changeset
570
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
571 if (signalEvent && connections[signalId].slotCount == 1)
253
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
572 signalEvent(signalId, SignalEventId.firstSlotConnected);
1
e78566595089 initial import
mandel
parents:
diff changeset
573
e78566595089 initial import
mandel
parents:
diff changeset
574 return slot;
e78566595089 initial import
mandel
parents:
diff changeset
575 }
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
576
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
577 void onReceiverDisposed(Object receiver)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
578 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
579 synchronized(this)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
580 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
581 foreach(ref c; connections)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
582 c.onReceiverDisposed(receiver);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
583 receivers.removeAll(receiver);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
584 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
585 }
1
e78566595089 initial import
mandel
parents:
diff changeset
586
e78566595089 initial import
mandel
parents:
diff changeset
587 private void removeSlot(int slotListId)(int signalId, int slotId)
e78566595089 initial import
mandel
parents:
diff changeset
588 {
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
589 auto slot = connections[signalId].getSlotList!(slotListId).get(slotId);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
590 static if (slot.isDelegate)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
591 {
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
592 if (auto obj = slot.getObject)
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
593 receivers.remove(obj, &onReceiverDisposed);
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
594 }
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
595
1
e78566595089 initial import
mandel
parents:
diff changeset
596 connections[signalId].removeSlot!(slotListId)(slotId);
e78566595089 initial import
mandel
parents:
diff changeset
597
253
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
598 if (signalEvent && !connections[signalId].slotCount)
073b9153ed8a Rev. 264 done right.
maxter
parents: 246
diff changeset
599 signalEvent(signalId, SignalEventId.lastSlotDisconnected);
1
e78566595089 initial import
mandel
parents:
diff changeset
600 }
e78566595089 initial import
mandel
parents:
diff changeset
601
e78566595089 initial import
mandel
parents:
diff changeset
602 size_t slotCount(int signalId)
e78566595089 initial import
mandel
parents:
diff changeset
603 {
e78566595089 initial import
mandel
parents:
diff changeset
604 synchronized(this)
e78566595089 initial import
mandel
parents:
diff changeset
605 {
e78566595089 initial import
mandel
parents:
diff changeset
606 auto con = getConnections(signalId);
e78566595089 initial import
mandel
parents:
diff changeset
607 if (con)
e78566595089 initial import
mandel
parents:
diff changeset
608 return con.slotCount;
e78566595089 initial import
mandel
parents:
diff changeset
609 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
610 }
e78566595089 initial import
mandel
parents:
diff changeset
611 }
e78566595089 initial import
mandel
parents:
diff changeset
612
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
613 void connect(Receiver)(int signalId, Receiver receiver,
1
e78566595089 initial import
mandel
parents:
diff changeset
614 Dg invoker, ConnectionFlags flags)
e78566595089 initial import
mandel
parents:
diff changeset
615 {
e78566595089 initial import
mandel
parents:
diff changeset
616 synchronized(this)
e78566595089 initial import
mandel
parents:
diff changeset
617 {
e78566595089 initial import
mandel
parents:
diff changeset
618 static if (is(typeof(receiver.context)))
e78566595089 initial import
mandel
parents:
diff changeset
619 {
e78566595089 initial import
mandel
parents:
diff changeset
620 Object obj;
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
621 if ((flags & ConnectionFlags.NoObject))
1
e78566595089 initial import
mandel
parents:
diff changeset
622 {
e78566595089 initial import
mandel
parents:
diff changeset
623 // strong by default
e78566595089 initial import
mandel
parents:
diff changeset
624 if (flags & ConnectionFlags.Weak)
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
625 addSlot!(SlotListId.Weak)(signalId, receiver, invoker, flags);
1
e78566595089 initial import
mandel
parents:
diff changeset
626 else
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
627 addSlot!(SlotListId.Strong)(signalId, receiver, invoker, flags);
1
e78566595089 initial import
mandel
parents:
diff changeset
628 }
e78566595089 initial import
mandel
parents:
diff changeset
629 else
e78566595089 initial import
mandel
parents:
diff changeset
630 {
e78566595089 initial import
mandel
parents:
diff changeset
631 // weak by default
e78566595089 initial import
mandel
parents:
diff changeset
632 if (flags & ConnectionFlags.Strong)
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
633 addSlot!(SlotListId.Strong)(signalId, receiver, invoker, flags);
1
e78566595089 initial import
mandel
parents:
diff changeset
634 else
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
635 addSlot!(SlotListId.Weak)(signalId, receiver, invoker, flags);
1
e78566595089 initial import
mandel
parents:
diff changeset
636 }
e78566595089 initial import
mandel
parents:
diff changeset
637 }
e78566595089 initial import
mandel
parents:
diff changeset
638 else
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
639 addSlot!(SlotListId.Func)(signalId, receiver, invoker, flags);
1
e78566595089 initial import
mandel
parents:
diff changeset
640 }
e78566595089 initial import
mandel
parents:
diff changeset
641 }
e78566595089 initial import
mandel
parents:
diff changeset
642
e78566595089 initial import
mandel
parents:
diff changeset
643 void disconnect(Receiver)(int signalId, Receiver receiver)
e78566595089 initial import
mandel
parents:
diff changeset
644 {
e78566595089 initial import
mandel
parents:
diff changeset
645 synchronized(this)
e78566595089 initial import
mandel
parents:
diff changeset
646 {
e78566595089 initial import
mandel
parents:
diff changeset
647 auto cons = getConnections(signalId);
e78566595089 initial import
mandel
parents:
diff changeset
648 if (!cons)
e78566595089 initial import
mandel
parents:
diff changeset
649 return;
e78566595089 initial import
mandel
parents:
diff changeset
650
e78566595089 initial import
mandel
parents:
diff changeset
651 // if called from a slot being executed by this signal, delay disconnection
e78566595089 initial import
mandel
parents:
diff changeset
652 // until all slots has been called.
e78566595089 initial import
mandel
parents:
diff changeset
653 if (cons.isInUse)
e78566595089 initial import
mandel
parents:
diff changeset
654 {
e78566595089 initial import
mandel
parents:
diff changeset
655 cons.addDelayedDisconnect(receiver);
e78566595089 initial import
mandel
parents:
diff changeset
656 return;
e78566595089 initial import
mandel
parents:
diff changeset
657 }
e78566595089 initial import
mandel
parents:
diff changeset
658
e78566595089 initial import
mandel
parents:
diff changeset
659 TOP:
e78566595089 initial import
mandel
parents:
diff changeset
660 foreach (slotListId, e; cons.slotLists.tupleof)
e78566595089 initial import
mandel
parents:
diff changeset
661 {
e78566595089 initial import
mandel
parents:
diff changeset
662 /// COMPILER BUG: ReceiverType is evaluated to expression instead of type.
e78566595089 initial import
mandel
parents:
diff changeset
663 static if (is(typeof(cons.ReceiverType!(slotListId)) == Receiver))
e78566595089 initial import
mandel
parents:
diff changeset
664 {
e78566595089 initial import
mandel
parents:
diff changeset
665 auto slotList = cons.getSlotList!(slotListId);
e78566595089 initial import
mandel
parents:
diff changeset
666 for (int slotId; slotId < slotList.length;)
e78566595089 initial import
mandel
parents:
diff changeset
667 {
e78566595089 initial import
mandel
parents:
diff changeset
668 auto slot = slotList.get(slotId);
e78566595089 initial import
mandel
parents:
diff changeset
669 static if (slot.isDelegate)
e78566595089 initial import
mandel
parents:
diff changeset
670 {
e78566595089 initial import
mandel
parents:
diff changeset
671 if (slot.isDisposed)
e78566595089 initial import
mandel
parents:
diff changeset
672 {
e78566595089 initial import
mandel
parents:
diff changeset
673 removeSlot!(slotListId)(signalId, slotId);
e78566595089 initial import
mandel
parents:
diff changeset
674 continue;
e78566595089 initial import
mandel
parents:
diff changeset
675 }
e78566595089 initial import
mandel
parents:
diff changeset
676 }
e78566595089 initial import
mandel
parents:
diff changeset
677
e78566595089 initial import
mandel
parents:
diff changeset
678 if (slot.receiver == receiver)
e78566595089 initial import
mandel
parents:
diff changeset
679 {
e78566595089 initial import
mandel
parents:
diff changeset
680 removeSlot!(slotListId)(signalId, slotId);
e78566595089 initial import
mandel
parents:
diff changeset
681 break TOP;
e78566595089 initial import
mandel
parents:
diff changeset
682 }
e78566595089 initial import
mandel
parents:
diff changeset
683
e78566595089 initial import
mandel
parents:
diff changeset
684 slotId++;
e78566595089 initial import
mandel
parents:
diff changeset
685 }
e78566595089 initial import
mandel
parents:
diff changeset
686 }
e78566595089 initial import
mandel
parents:
diff changeset
687 }
e78566595089 initial import
mandel
parents:
diff changeset
688 }
e78566595089 initial import
mandel
parents:
diff changeset
689 }
e78566595089 initial import
mandel
parents:
diff changeset
690
e78566595089 initial import
mandel
parents:
diff changeset
691 void emit(A...)(size_t signalId, A args)
e78566595089 initial import
mandel
parents:
diff changeset
692 {
e78566595089 initial import
mandel
parents:
diff changeset
693 synchronized(this)
e78566595089 initial import
mandel
parents:
diff changeset
694 {
e78566595089 initial import
mandel
parents:
diff changeset
695 if (signalId >= connections.length || blocked)
e78566595089 initial import
mandel
parents:
diff changeset
696 return;
e78566595089 initial import
mandel
parents:
diff changeset
697 auto cons = &connections[signalId];
e78566595089 initial import
mandel
parents:
diff changeset
698
e78566595089 initial import
mandel
parents:
diff changeset
699 if (cons.hasSlots)
e78566595089 initial import
mandel
parents:
diff changeset
700 {
e78566595089 initial import
mandel
parents:
diff changeset
701 {
e78566595089 initial import
mandel
parents:
diff changeset
702 cons.isInUse = true;
268
cf6a4cd0e3f2 fix for #35
eldar
parents: 253
diff changeset
703 signalSender_ = owner;
1
e78566595089 initial import
mandel
parents:
diff changeset
704 scope(exit)
e78566595089 initial import
mandel
parents:
diff changeset
705 {
e78566595089 initial import
mandel
parents:
diff changeset
706 cons.isInUse = false;
268
cf6a4cd0e3f2 fix for #35
eldar
parents: 253
diff changeset
707 signalSender_ = null;
1
e78566595089 initial import
mandel
parents:
diff changeset
708 }
e78566595089 initial import
mandel
parents:
diff changeset
709
e78566595089 initial import
mandel
parents:
diff changeset
710 // Store the lengths to avoid calling new slots
e78566595089 initial import
mandel
parents:
diff changeset
711 // connected in the slots being called.
e78566595089 initial import
mandel
parents:
diff changeset
712 // dmd bug: int[cons.slotListCount] fails
e78566595089 initial import
mandel
parents:
diff changeset
713 static const c = cons.slotListCount;
e78566595089 initial import
mandel
parents:
diff changeset
714 int[c] lengths = void;
e78566595089 initial import
mandel
parents:
diff changeset
715 cons.slotListLengths(lengths);
e78566595089 initial import
mandel
parents:
diff changeset
716
e78566595089 initial import
mandel
parents:
diff changeset
717 foreach (slotListId, e; cons.slotLists.tupleof)
e78566595089 initial import
mandel
parents:
diff changeset
718 {
e78566595089 initial import
mandel
parents:
diff changeset
719 auto slotList = cons.getSlotList!(slotListId);
e78566595089 initial import
mandel
parents:
diff changeset
720 for (size_t slotId; slotId < lengths[slotListId];)
e78566595089 initial import
mandel
parents:
diff changeset
721 {
e78566595089 initial import
mandel
parents:
diff changeset
722 auto slot = slotList.get(slotId);
e78566595089 initial import
mandel
parents:
diff changeset
723 static if (slot.isDelegate)
e78566595089 initial import
mandel
parents:
diff changeset
724 {
e78566595089 initial import
mandel
parents:
diff changeset
725 if (slot.isDisposed)
e78566595089 initial import
mandel
parents:
diff changeset
726 {
e78566595089 initial import
mandel
parents:
diff changeset
727 removeSlot!(slotListId)(signalId, slotId);
e78566595089 initial import
mandel
parents:
diff changeset
728 lengths[slotListId]--;
e78566595089 initial import
mandel
parents:
diff changeset
729 continue;
e78566595089 initial import
mandel
parents:
diff changeset
730 }
e78566595089 initial import
mandel
parents:
diff changeset
731 }
e78566595089 initial import
mandel
parents:
diff changeset
732
e78566595089 initial import
mandel
parents:
diff changeset
733 slot.invoker.call!(void)(slot.receiver, args);
e78566595089 initial import
mandel
parents:
diff changeset
734 ++slotId;
e78566595089 initial import
mandel
parents:
diff changeset
735 }
e78566595089 initial import
mandel
parents:
diff changeset
736 }
e78566595089 initial import
mandel
parents:
diff changeset
737 }
e78566595089 initial import
mandel
parents:
diff changeset
738
e78566595089 initial import
mandel
parents:
diff changeset
739
e78566595089 initial import
mandel
parents:
diff changeset
740 // process delayed disconnects if any
e78566595089 initial import
mandel
parents:
diff changeset
741 foreach(i, e; cons.delayedDisconnects.tupleof)
e78566595089 initial import
mandel
parents:
diff changeset
742 {
e78566595089 initial import
mandel
parents:
diff changeset
743 if (cons.delayedDisconnects.at!(i).length)
e78566595089 initial import
mandel
parents:
diff changeset
744 {
e78566595089 initial import
mandel
parents:
diff changeset
745 foreach (d; cons.delayedDisconnects.at!(i))
e78566595089 initial import
mandel
parents:
diff changeset
746 disconnect(signalId, d);
e78566595089 initial import
mandel
parents:
diff changeset
747 cons.delayedDisconnects.at!(i).length = 0;
e78566595089 initial import
mandel
parents:
diff changeset
748 }
e78566595089 initial import
mandel
parents:
diff changeset
749 }
e78566595089 initial import
mandel
parents:
diff changeset
750 }
e78566595089 initial import
mandel
parents:
diff changeset
751 }
e78566595089 initial import
mandel
parents:
diff changeset
752 }
e78566595089 initial import
mandel
parents:
diff changeset
753
e78566595089 initial import
mandel
parents:
diff changeset
754 // Adjusts signal arguments and calls the slot. S - slot signature, A - signal arguments
e78566595089 initial import
mandel
parents:
diff changeset
755 private void invokeSlot(S, Receiver, A...)(Receiver r, A args)
e78566595089 initial import
mandel
parents:
diff changeset
756 {
190
a1b48a630f73 D2 support, simple stuff works now
eldar
parents: 188
diff changeset
757 r.get!(S)()(args[0..ParameterTypeTuple!(S).length]);
1
e78566595089 initial import
mandel
parents:
diff changeset
758 }
e78566595089 initial import
mandel
parents:
diff changeset
759
e78566595089 initial import
mandel
parents:
diff changeset
760 void blockSignals()
e78566595089 initial import
mandel
parents:
diff changeset
761 {
e78566595089 initial import
mandel
parents:
diff changeset
762 synchronized(this)
e78566595089 initial import
mandel
parents:
diff changeset
763 blocked++;
e78566595089 initial import
mandel
parents:
diff changeset
764 }
e78566595089 initial import
mandel
parents:
diff changeset
765
e78566595089 initial import
mandel
parents:
diff changeset
766 void unblockSignals()
e78566595089 initial import
mandel
parents:
diff changeset
767 {
e78566595089 initial import
mandel
parents:
diff changeset
768 synchronized(this)
e78566595089 initial import
mandel
parents:
diff changeset
769 {
e78566595089 initial import
mandel
parents:
diff changeset
770 if(!blocked)
e78566595089 initial import
mandel
parents:
diff changeset
771 throw new SignalException("Signals are not blocked");
e78566595089 initial import
mandel
parents:
diff changeset
772 blocked--;
e78566595089 initial import
mandel
parents:
diff changeset
773 }
e78566595089 initial import
mandel
parents:
diff changeset
774 }
e78566595089 initial import
mandel
parents:
diff changeset
775
e78566595089 initial import
mandel
parents:
diff changeset
776 ~this()
e78566595089 initial import
mandel
parents:
diff changeset
777 {
276
501128ac7a2c signals cleaned up correctly on receiver destruction
maxter
parents: 268
diff changeset
778 receivers.free(&onReceiverDisposed);
1
e78566595089 initial import
mandel
parents:
diff changeset
779 foreach(ref c; connections)
e78566595089 initial import
mandel
parents:
diff changeset
780 c.free;
e78566595089 initial import
mandel
parents:
diff changeset
781 }
e78566595089 initial import
mandel
parents:
diff changeset
782 }
e78566595089 initial import
mandel
parents:
diff changeset
783
e78566595089 initial import
mandel
parents:
diff changeset
784 public template SignalHandlerOps()
e78566595089 initial import
mandel
parents:
diff changeset
785 {
e78566595089 initial import
mandel
parents:
diff changeset
786 static assert (is(typeof(this.signalHandler)),
e78566595089 initial import
mandel
parents:
diff changeset
787 "SignalHandlerOps is already instantiated in " ~ typeof(this).stringof ~ " or one of its base classes");
e78566595089 initial import
mandel
parents:
diff changeset
788
e78566595089 initial import
mandel
parents:
diff changeset
789 protected:
e78566595089 initial import
mandel
parents:
diff changeset
790 SignalHandler signalHandler_; // manages signal-to-slot connections
e78566595089 initial import
mandel
parents:
diff changeset
791
e78566595089 initial import
mandel
parents:
diff changeset
792 final SignalHandler signalHandler()
e78566595089 initial import
mandel
parents:
diff changeset
793 {
e78566595089 initial import
mandel
parents:
diff changeset
794 if (!signalHandler_)
e78566595089 initial import
mandel
parents:
diff changeset
795 {
e78566595089 initial import
mandel
parents:
diff changeset
796 signalHandler_ = new SignalHandler(this);
e78566595089 initial import
mandel
parents:
diff changeset
797 onSignalHandlerCreated(signalHandler_);
e78566595089 initial import
mandel
parents:
diff changeset
798 }
e78566595089 initial import
mandel
parents:
diff changeset
799 return signalHandler_;
e78566595089 initial import
mandel
parents:
diff changeset
800 }
e78566595089 initial import
mandel
parents:
diff changeset
801
e78566595089 initial import
mandel
parents:
diff changeset
802 void onSignalHandlerCreated(ref SignalHandler sh)
e78566595089 initial import
mandel
parents:
diff changeset
803 {
e78566595089 initial import
mandel
parents:
diff changeset
804 }
e78566595089 initial import
mandel
parents:
diff changeset
805
e78566595089 initial import
mandel
parents:
diff changeset
806 public:
e78566595089 initial import
mandel
parents:
diff changeset
807 final void blockSignals()
e78566595089 initial import
mandel
parents:
diff changeset
808 {
e78566595089 initial import
mandel
parents:
diff changeset
809 signalHandler.blockSignals();
e78566595089 initial import
mandel
parents:
diff changeset
810 }
e78566595089 initial import
mandel
parents:
diff changeset
811
e78566595089 initial import
mandel
parents:
diff changeset
812 final void unblockSignals()
e78566595089 initial import
mandel
parents:
diff changeset
813 {
e78566595089 initial import
mandel
parents:
diff changeset
814 signalHandler.unblockSignals();
e78566595089 initial import
mandel
parents:
diff changeset
815 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
816
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
817 template connect(string signalName, A...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
818 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
819 static void connect(T, Func)(T sender, Func func, ConnectionFlags flags = ConnectionFlags.None)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
820 if (isFnOrDg!(Func))
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
821 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
822 alias findSignal!(T, signalName, Func, A).result sig;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
823 auto sh = sender.signalHandler();
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
824 static if (isFn!(Func))
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
825 alias Fn Callable;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
826 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
827 alias Dg Callable;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
828 auto invoker = Dg(&sh.invokeSlot!(typeof(func), Callable, sig[2..$]));
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
829 sh.connect(sig[1], Callable(func), invoker, flags);
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
830 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
831 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
832
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
833 template disconnect(string signalName, A...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
834 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
835 static void connect(T, Func)(T sender, Func func, ConnectionFlags flags = ConnectionFlags.None)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
836 if (isFnOrDg!(Func))
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
837 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
838 alias findSignal!(T, signalName, Func, A).result sig;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
839 auto sh = sender.signalHandler();
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
840 static if (isFn!(Func))
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
841 alias Fn Callable;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
842 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
843 alias Dg Callable;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
844 sh.disconnect(sig[1], Callable(func));
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
845 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
846 }
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
847 /*
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
848 template slotCount(string signalName, A...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
849 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
850 debug static void slotCount(T)(T sender)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
851 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
852 alias findSignal!(T, signalName, Func, A).result sig;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
853 auto sh = sender.signalHandler();
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
854 return sh.slotCount(sig[1]);
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
855 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
856 }
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
857 */
1
e78566595089 initial import
mandel
parents:
diff changeset
858 }
e78566595089 initial import
mandel
parents:
diff changeset
859
e78566595089 initial import
mandel
parents:
diff changeset
860 /**
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
861 New implementation.
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
862 */
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
863
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
864 const string signalPrefix = "__signal";
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
865
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
866 template TupleWrapper(A...) { alias A at; }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
867
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
868 template isDg(Dg)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
869 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
870 enum isDg = is(Dg == delegate);
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
871 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
872
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
873 template isFn(Fn)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
874 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
875 enum isFn = is(typeof(*Fn.init) == function);
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
876 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
877
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
878 template isFnOrDg(Dg)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
879 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
880 enum isFnOrDg = isFn!(Dg) || isDg!(Dg);
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
881 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
882
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
883 string joinArgs(A...)()
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
884 {
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
885 string res = "";
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
886 static if(A.length)
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
887 {
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
888 res = A[0].stringof;
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
889 foreach(k; A[1..$])
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
890 res ~= "," ~ k.stringof;
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
891 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
892 return res;
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
893 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
894
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
895 template SlotPred(T1, T2)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
896 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
897 enum SlotPred = is(T1 : T2);
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
898 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
899
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
900 template CheckSlot(alias Needle, alias Source)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
901 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
902 static if(Needle.at.length <= Source.at.length)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
903 enum CheckSlot = CheckArgs!(Needle, Source, SlotPred, 0).value;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
904 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
905 enum CheckSlot = false;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
906 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
907
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
908 template SignalPred(T1, T2)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
909 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
910 enum SignalPred = is(T1 == T2);
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
911 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
912
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
913 template CheckSignal(alias Needle, alias Source)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
914 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
915 static if(Needle.at.length == Source.at.length)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
916 enum CheckSignal = CheckArgs!(Needle, Source, SignalPred, 0).value;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
917 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
918 enum CheckSignal = false;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
919 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
920
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
921 template CheckArgs(alias Needle, alias Source, alias pred, int i)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
922 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
923 static if (i < Needle.at.length)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
924 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
925 static if (pred!(Needle.at[i], Source.at[i]))
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
926 enum value = CheckArgs!(Needle, Source, pred, i + 1).value;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
927 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
928 enum value = false;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
929 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
930 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
931 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
932 enum value = true;
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
933 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
934 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
935
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
936 template SigByNamePred(string name, SlotArgs...)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
937 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
938 template SigByNamePred(source...)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
939 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
940 static if (source[0] == name) // only instantiate CheckSlot if names match
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
941 enum SigByNamePred = CheckSlot!(TupleWrapper!(SlotArgs), TupleWrapper!(source[2 .. $]));
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
942 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
943 enum SigByNamePred = false;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
944 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
945 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
946
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
947 template SigBySignPred(string name, SigArgs...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
948 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
949 template SigBySignPred(source...)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
950 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
951 static if (source[0] == name) // only instantiate CheckSignal if names match
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
952 enum SigBySignPred = CheckSignal!(TupleWrapper!(SigArgs), TupleWrapper!(source[2 .. $]));
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
953 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
954 enum SigBySignPred = false;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
955 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
956 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
957
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
958 template staticSymbolName(string prefix, int id)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
959 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
960 const string staticSymbolName = prefix ~ ToString!(id);
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
961 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
962
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
963 template signatureString(string name, A...)
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
964 {
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
965 const string signatureString = name ~ "(" ~ joinArgs!(A) ~ ")";
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
966 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
967
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
968 template findSymbolImpl(string prefix, C, int id, alias pred)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
969 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
970 static if ( is(typeof(mixin("C." ~ staticSymbolName!(prefix, id)))) )
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
971 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
972 mixin ("alias C." ~ staticSymbolName!(prefix, id) ~ " current;");
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
973 static if (pred!current)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
974 alias current result;
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
975 else
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
976 alias findSymbolImpl!(prefix, C, id + 1, pred).result result;
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
977 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
978 else
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
979 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
980 alias void result;
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
981 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
982 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
983
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
984 template findSymbol(string prefix, C, alias pred)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
985 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
986 alias findSymbolImpl!(prefix, C, 0, pred).result findSymbol;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
987 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
988
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
989 template findSignal(C, string name, Receiver, SigArgs...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
990 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
991 alias TupleWrapper!(ParameterTypeTuple!Receiver) SlotArgsWr;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
992 static if (SigArgs.length > 0)
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
993 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
994 alias findSymbol!(signalPrefix, C, SigBySignPred!(name, SigArgs)) result;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
995 static if (is(result == void))
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
996 static assert(0, "Signal " ~ name ~ "(" ~ joinArgs!SigArgs() ~ ") was not found.");
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
997 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
998 static if (!CheckSlot!(SlotArgsWr, TupleWrapper!(result[2 .. $])))
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
999 static assert(0, "Signature of slot is incompatible with signal " ~ name ~ ".");
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
1000 }
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
1001 else
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
1002 {
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
1003 alias findSymbol!(signalPrefix, C, SigByNamePred!(name, SlotArgsWr.at)) result;
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
1004 static if (is(result == void))
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
1005 static assert(0, "Signal " ~ name ~ " was not found.");
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
1006 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1007 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1008
284
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1009 string __toString(long v)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1010 {
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1011 if (v == 0)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1012 return "0";
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1013
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1014 string ret;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1015
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1016 bool neg;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1017 if (v < 0)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1018 {
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1019 neg = true;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1020 v = -v;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1021 }
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1022
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1023 while (v != 0)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1024 {
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1025 ret = cast(char)(v % 10 + '0') ~ ret;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1026 v = cast(long)(v / 10);
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1027 }
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1028
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1029 if (neg)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1030 ret = "-" ~ ret;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1031
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1032 return ret;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1033 }
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1034
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1035 public string SignalEmitter(A...)(SignalType signalType, string name, int index)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1036 {
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1037 string fullArgs, args;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1038 static if (A.length)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1039 {
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1040 fullArgs = A[0].stringof ~ " a0";
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1041 args = ", a0";
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1042 foreach(i, _; A[1..$])
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1043 {
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1044 fullArgs ~= ", " ~ A[i+1].stringof ~ " a" ~ __toString(i+1);
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1045 args ~= ", a" ~ __toString(i+1);
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1046 }
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1047 }
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1048 string attribute;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1049 string sigName = name;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1050 if (signalType == SignalType.BindQtSignal)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1051 name ~= "_emit";
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1052 else
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1053 attribute = "protected ";
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1054 string str = attribute ~ "void " ~ name ~ "(" ~ fullArgs ~ ")" ~
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1055 "{ this.signalHandler.emit(" ~ __toString(index) ~ args ~ "); }";
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1056 return str;
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1057 }
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1058
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1059 /** ---------------- */
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1060
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1061
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1062 /**
1
e78566595089 initial import
mandel
parents:
diff changeset
1063 Examples:
e78566595089 initial import
mandel
parents:
diff changeset
1064 ----
e78566595089 initial import
mandel
parents:
diff changeset
1065 struct Args
e78566595089 initial import
mandel
parents:
diff changeset
1066 {
e78566595089 initial import
mandel
parents:
diff changeset
1067 bool cancel;
e78566595089 initial import
mandel
parents:
diff changeset
1068 }
e78566595089 initial import
mandel
parents:
diff changeset
1069
e78566595089 initial import
mandel
parents:
diff changeset
1070 class C
e78566595089 initial import
mandel
parents:
diff changeset
1071 {
e78566595089 initial import
mandel
parents:
diff changeset
1072 private int _x;
e78566595089 initial import
mandel
parents:
diff changeset
1073 // reference parameters are not supported yet,
e78566595089 initial import
mandel
parents:
diff changeset
1074 // so we pass arguments by pointer.
e78566595089 initial import
mandel
parents:
diff changeset
1075 mixin Signal!("xChanging", int, Args*);
e78566595089 initial import
mandel
parents:
diff changeset
1076 mixin Signal!("xChanged");
e78566595089 initial import
mandel
parents:
diff changeset
1077
e78566595089 initial import
mandel
parents:
diff changeset
1078 void x(int v)
e78566595089 initial import
mandel
parents:
diff changeset
1079 {
e78566595089 initial import
mandel
parents:
diff changeset
1080 if (v != _x)
e78566595089 initial import
mandel
parents:
diff changeset
1081 {
e78566595089 initial import
mandel
parents:
diff changeset
1082 Args args;
e78566595089 initial import
mandel
parents:
diff changeset
1083 xChanging.emit(v, &args);
e78566595089 initial import
mandel
parents:
diff changeset
1084 if (!args.cancel)
e78566595089 initial import
mandel
parents:
diff changeset
1085 {
e78566595089 initial import
mandel
parents:
diff changeset
1086 _x = v;
e78566595089 initial import
mandel
parents:
diff changeset
1087 xChanged.emit;
e78566595089 initial import
mandel
parents:
diff changeset
1088 }
e78566595089 initial import
mandel
parents:
diff changeset
1089 }
e78566595089 initial import
mandel
parents:
diff changeset
1090 }
e78566595089 initial import
mandel
parents:
diff changeset
1091 }
e78566595089 initial import
mandel
parents:
diff changeset
1092 ----
e78566595089 initial import
mandel
parents:
diff changeset
1093 */
284
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1094
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1095 enum SignalType
1
e78566595089 initial import
mandel
parents:
diff changeset
1096 {
284
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1097 BindQtSignal,
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1098 NewSignal
1
e78566595089 initial import
mandel
parents:
diff changeset
1099 }
e78566595089 initial import
mandel
parents:
diff changeset
1100
284
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1101 template BindQtSignal(string name, A...)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1102 {
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1103 mixin SignalImpl!(0, name, SignalType.BindQtSignal, A);
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1104 }
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1105
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1106 template Signal(string name, A...)
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1107 {
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1108 mixin SignalImpl!(0, name, SignalType.NewSignal, A);
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1109 }
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1110
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1111 template SignalImpl(int index, string name, SignalType signalType, A...)
1
e78566595089 initial import
mandel
parents:
diff changeset
1112 {
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
1113 static if (is(typeof(mixin(typeof(this).stringof ~ ".__signal" ~ ToString!(index)))))
284
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1114 mixin SignalImpl!(index + 1, name, signalType, A);
1
e78566595089 initial import
mandel
parents:
diff changeset
1115 else
e78566595089 initial import
mandel
parents:
diff changeset
1116 {
e78566595089 initial import
mandel
parents:
diff changeset
1117 // mixed-in once
e78566595089 initial import
mandel
parents:
diff changeset
1118 static if (!is(typeof(this.signalHandler)))
e78566595089 initial import
mandel
parents:
diff changeset
1119 mixin SignalHandlerOps;
284
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1120
1f6923c8cba0 consistent emit syntax.
eldar
parents: 282
diff changeset
1121 mixin (SignalEmitter!(A)(signalType, name, index));
282
256ab6cb8e85 Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents: 279
diff changeset
1122 mixin("public alias TypeTuple!(\"" ~ name ~ "\", index, A) __signal" ~ ToString!(index) ~ ";");
1
e78566595089 initial import
mandel
parents:
diff changeset
1123 }
e78566595089 initial import
mandel
parents:
diff changeset
1124 }
e78566595089 initial import
mandel
parents:
diff changeset
1125
e78566595089 initial import
mandel
parents:
diff changeset
1126 extern(C) alias void function(void*) SlotConnector;
e78566595089 initial import
mandel
parents:
diff changeset
1127
e78566595089 initial import
mandel
parents:
diff changeset
1128 debug (UnitTest)
e78566595089 initial import
mandel
parents:
diff changeset
1129 {
e78566595089 initial import
mandel
parents:
diff changeset
1130 class A
e78566595089 initial import
mandel
parents:
diff changeset
1131 {
e78566595089 initial import
mandel
parents:
diff changeset
1132 mixin Signal!("scorched", int);
e78566595089 initial import
mandel
parents:
diff changeset
1133
e78566595089 initial import
mandel
parents:
diff changeset
1134 int signalId1 = -1;
e78566595089 initial import
mandel
parents:
diff changeset
1135 int signalId2 = -1;
e78566595089 initial import
mandel
parents:
diff changeset
1136
e78566595089 initial import
mandel
parents:
diff changeset
1137 void onFirstConnect(int sId)
e78566595089 initial import
mandel
parents:
diff changeset
1138 {
e78566595089 initial import
mandel
parents:
diff changeset
1139 signalId1 = sId;
e78566595089 initial import
mandel
parents:
diff changeset
1140 }
e78566595089 initial import
mandel
parents:
diff changeset
1141
e78566595089 initial import
mandel
parents:
diff changeset
1142 void onLastDisconnect(int sId)
e78566595089 initial import
mandel
parents:
diff changeset
1143 {
e78566595089 initial import
mandel
parents:
diff changeset
1144 signalId2 = sId;
e78566595089 initial import
mandel
parents:
diff changeset
1145 }
e78566595089 initial import
mandel
parents:
diff changeset
1146
e78566595089 initial import
mandel
parents:
diff changeset
1147 this()
e78566595089 initial import
mandel
parents:
diff changeset
1148 {
e78566595089 initial import
mandel
parents:
diff changeset
1149 signalHandler.firstSlotConnected = &onFirstConnect;
e78566595089 initial import
mandel
parents:
diff changeset
1150 signalHandler.lastSlotDisconnected = &onLastDisconnect;
e78566595089 initial import
mandel
parents:
diff changeset
1151 }
e78566595089 initial import
mandel
parents:
diff changeset
1152 }
e78566595089 initial import
mandel
parents:
diff changeset
1153
e78566595089 initial import
mandel
parents:
diff changeset
1154 class B : A
e78566595089 initial import
mandel
parents:
diff changeset
1155 {
e78566595089 initial import
mandel
parents:
diff changeset
1156 mixin Signal!("booed", int);
e78566595089 initial import
mandel
parents:
diff changeset
1157
e78566595089 initial import
mandel
parents:
diff changeset
1158 int bazSum;
e78566595089 initial import
mandel
parents:
diff changeset
1159 void baz(int i)
e78566595089 initial import
mandel
parents:
diff changeset
1160 {
e78566595089 initial import
mandel
parents:
diff changeset
1161 bazSum += i;
e78566595089 initial import
mandel
parents:
diff changeset
1162 }
e78566595089 initial import
mandel
parents:
diff changeset
1163 }
e78566595089 initial import
mandel
parents:
diff changeset
1164
e78566595089 initial import
mandel
parents:
diff changeset
1165 class C : A
e78566595089 initial import
mandel
parents:
diff changeset
1166 {
e78566595089 initial import
mandel
parents:
diff changeset
1167 mixin Signal!("cooked");
e78566595089 initial import
mandel
parents:
diff changeset
1168 }
e78566595089 initial import
mandel
parents:
diff changeset
1169 }
e78566595089 initial import
mandel
parents:
diff changeset
1170
e78566595089 initial import
mandel
parents:
diff changeset
1171 unittest
e78566595089 initial import
mandel
parents:
diff changeset
1172 {
e78566595089 initial import
mandel
parents:
diff changeset
1173 static int fooSum;
e78566595089 initial import
mandel
parents:
diff changeset
1174 static int barSum;
e78566595089 initial import
mandel
parents:
diff changeset
1175
e78566595089 initial import
mandel
parents:
diff changeset
1176 static void foo(int i)
e78566595089 initial import
mandel
parents:
diff changeset
1177 {
e78566595089 initial import
mandel
parents:
diff changeset
1178 fooSum += i;
e78566595089 initial import
mandel
parents:
diff changeset
1179 }
e78566595089 initial import
mandel
parents:
diff changeset
1180
e78566595089 initial import
mandel
parents:
diff changeset
1181 void bar(long i)
e78566595089 initial import
mandel
parents:
diff changeset
1182 {
e78566595089 initial import
mandel
parents:
diff changeset
1183 barSum += i;
e78566595089 initial import
mandel
parents:
diff changeset
1184 }
e78566595089 initial import
mandel
parents:
diff changeset
1185
e78566595089 initial import
mandel
parents:
diff changeset
1186 auto a = new A;
e78566595089 initial import
mandel
parents:
diff changeset
1187 auto b = new B;
e78566595089 initial import
mandel
parents:
diff changeset
1188 auto c = new C;
e78566595089 initial import
mandel
parents:
diff changeset
1189 assert(b.scorched.signalId == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1190 assert(b.booed.signalId == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1191 assert(c.cooked.signalId == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1192
e78566595089 initial import
mandel
parents:
diff changeset
1193 auto sh = b.signalHandler;
e78566595089 initial import
mandel
parents:
diff changeset
1194
e78566595089 initial import
mandel
parents:
diff changeset
1195 b.scorched.connect(&foo);
e78566595089 initial import
mandel
parents:
diff changeset
1196 assert(sh.connections.length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1197 assert(b.signalId1 == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1198 auto scCons = &sh.connections[0];
e78566595089 initial import
mandel
parents:
diff changeset
1199
e78566595089 initial import
mandel
parents:
diff changeset
1200 assert(scCons.getSlotList!(SlotListId.Func).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1201 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1202 assert(fooSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1203
e78566595089 initial import
mandel
parents:
diff changeset
1204 b.scorched.connect(&bar, ConnectionFlags.NoObject);
e78566595089 initial import
mandel
parents:
diff changeset
1205 assert(sh.connections.length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1206 assert(scCons.getSlotList!(SlotListId.Strong).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1207 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1208 assert (fooSum == 2 && barSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1209
e78566595089 initial import
mandel
parents:
diff changeset
1210 b.scorched.connect(&b.baz);
e78566595089 initial import
mandel
parents:
diff changeset
1211 assert(scCons.getSlotList!(SlotListId.Weak).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1212 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1213 assert (fooSum == 3 && barSum == 2 && b.bazSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1214
e78566595089 initial import
mandel
parents:
diff changeset
1215 b.scorched.disconnect(&bar);
e78566595089 initial import
mandel
parents:
diff changeset
1216 assert(scCons.slotCount == 2);
e78566595089 initial import
mandel
parents:
diff changeset
1217 b.scorched.disconnect(&b.baz);
e78566595089 initial import
mandel
parents:
diff changeset
1218 assert(scCons.slotCount == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1219 b.scorched.disconnect(&foo);
e78566595089 initial import
mandel
parents:
diff changeset
1220 assert(scCons.slotCount == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1221 assert(b.signalId2 == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1222
e78566595089 initial import
mandel
parents:
diff changeset
1223 fooSum = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1224 void connectFoo()
e78566595089 initial import
mandel
parents:
diff changeset
1225 {
e78566595089 initial import
mandel
parents:
diff changeset
1226 b.scorched.connect(&foo);
e78566595089 initial import
mandel
parents:
diff changeset
1227 b.scorched.disconnect(&connectFoo);
e78566595089 initial import
mandel
parents:
diff changeset
1228 }
e78566595089 initial import
mandel
parents:
diff changeset
1229
e78566595089 initial import
mandel
parents:
diff changeset
1230 b.scorched.connect(&connectFoo, ConnectionFlags.NoObject);
e78566595089 initial import
mandel
parents:
diff changeset
1231 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1232 assert(scCons.getSlotList!(SlotListId.Func).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1233 assert(scCons.getSlotList!(SlotListId.Strong).length == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1234 assert(!fooSum);
e78566595089 initial import
mandel
parents:
diff changeset
1235
e78566595089 initial import
mandel
parents:
diff changeset
1236 auto r = new B();
e78566595089 initial import
mandel
parents:
diff changeset
1237 b.scorched.connect(&r.baz);
e78566595089 initial import
mandel
parents:
diff changeset
1238 assert(scCons.getSlotList!(SlotListId.Weak).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1239 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1240 assert(r.bazSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1241 assert(fooSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1242
e78566595089 initial import
mandel
parents:
diff changeset
1243 delete(r);
e78566595089 initial import
mandel
parents:
diff changeset
1244 assert(scCons.getSlotList!(SlotListId.Weak).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1245 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1246 assert(scCons.getSlotList!(SlotListId.Weak).length == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1247 }