annotate qt/d2/qt/Signal.d @ 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.
author eldar
date Fri, 16 Oct 2009 02:43:59 +0000
parents 519befd5a5d1
children 1f6923c8cba0
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 //TODO: this could be avoided if named mixins didn't suck.
e78566595089 initial import
mandel
parents:
diff changeset
785 public struct SignalOps(int sigId, A...)
e78566595089 initial import
mandel
parents:
diff changeset
786 {
e78566595089 initial import
mandel
parents:
diff changeset
787 private SignalHandler sh;
e78566595089 initial import
mandel
parents:
diff changeset
788 enum { signalId = sigId }
e78566595089 initial import
mandel
parents:
diff changeset
789
e78566595089 initial import
mandel
parents:
diff changeset
790 void emit(A args)
e78566595089 initial import
mandel
parents:
diff changeset
791 {
e78566595089 initial import
mandel
parents:
diff changeset
792 sh.emit(signalId, args);
e78566595089 initial import
mandel
parents:
diff changeset
793 }
e78566595089 initial import
mandel
parents:
diff changeset
794
e78566595089 initial import
mandel
parents:
diff changeset
795 debug size_t slotCount()
e78566595089 initial import
mandel
parents:
diff changeset
796 {
e78566595089 initial import
mandel
parents:
diff changeset
797 return sh.slotCount(signalId);
e78566595089 initial import
mandel
parents:
diff changeset
798 }
e78566595089 initial import
mandel
parents:
diff changeset
799 }
e78566595089 initial import
mandel
parents:
diff changeset
800
e78566595089 initial import
mandel
parents:
diff changeset
801 public template SignalHandlerOps()
e78566595089 initial import
mandel
parents:
diff changeset
802 {
e78566595089 initial import
mandel
parents:
diff changeset
803 static assert (is(typeof(this.signalHandler)),
e78566595089 initial import
mandel
parents:
diff changeset
804 "SignalHandlerOps is already instantiated in " ~ typeof(this).stringof ~ " or one of its base classes");
e78566595089 initial import
mandel
parents:
diff changeset
805
e78566595089 initial import
mandel
parents:
diff changeset
806 protected:
e78566595089 initial import
mandel
parents:
diff changeset
807 SignalHandler signalHandler_; // manages signal-to-slot connections
e78566595089 initial import
mandel
parents:
diff changeset
808
e78566595089 initial import
mandel
parents:
diff changeset
809 final SignalHandler signalHandler()
e78566595089 initial import
mandel
parents:
diff changeset
810 {
e78566595089 initial import
mandel
parents:
diff changeset
811 if (!signalHandler_)
e78566595089 initial import
mandel
parents:
diff changeset
812 {
e78566595089 initial import
mandel
parents:
diff changeset
813 signalHandler_ = new SignalHandler(this);
e78566595089 initial import
mandel
parents:
diff changeset
814 onSignalHandlerCreated(signalHandler_);
e78566595089 initial import
mandel
parents:
diff changeset
815 }
e78566595089 initial import
mandel
parents:
diff changeset
816 return signalHandler_;
e78566595089 initial import
mandel
parents:
diff changeset
817 }
e78566595089 initial import
mandel
parents:
diff changeset
818
e78566595089 initial import
mandel
parents:
diff changeset
819 void onSignalHandlerCreated(ref SignalHandler sh)
e78566595089 initial import
mandel
parents:
diff changeset
820 {
e78566595089 initial import
mandel
parents:
diff changeset
821 }
e78566595089 initial import
mandel
parents:
diff changeset
822
e78566595089 initial import
mandel
parents:
diff changeset
823 public:
e78566595089 initial import
mandel
parents:
diff changeset
824 final void blockSignals()
e78566595089 initial import
mandel
parents:
diff changeset
825 {
e78566595089 initial import
mandel
parents:
diff changeset
826 signalHandler.blockSignals();
e78566595089 initial import
mandel
parents:
diff changeset
827 }
e78566595089 initial import
mandel
parents:
diff changeset
828
e78566595089 initial import
mandel
parents:
diff changeset
829 final void unblockSignals()
e78566595089 initial import
mandel
parents:
diff changeset
830 {
e78566595089 initial import
mandel
parents:
diff changeset
831 signalHandler.unblockSignals();
e78566595089 initial import
mandel
parents:
diff changeset
832 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
833
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
834 template connect(string signalName, A...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
835 {
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
836 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
837 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
838 {
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 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
840 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
841 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
842 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
843 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
844 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
845 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
846 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
847 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
848 }
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 template disconnect(string signalName, A...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
851 {
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
852 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
853 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
854 {
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 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
856 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
857 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
858 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
859 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
860 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
861 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
862 }
278
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 /*
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 template slotCount(string signalName, A...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
866 {
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
867 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
868 {
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
869 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
870 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
871 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
872 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
873 }
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
874 */
1
e78566595089 initial import
mandel
parents:
diff changeset
875 }
e78566595089 initial import
mandel
parents:
diff changeset
876
e78566595089 initial import
mandel
parents:
diff changeset
877 /**
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
878 New implementation.
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
879 */
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
880
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
881 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
882
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
883 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
884
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
885 template isDg(Dg)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
886 {
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
887 enum isDg = is(Dg == delegate);
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
888 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
889
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
890 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
891 {
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
892 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
893 }
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
894
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 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
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 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
898 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
899
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
900 string joinArgs(A...)()
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
901 {
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
902 string res = "";
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
903 static if(A.length)
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
904 {
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
905 res = A[0].stringof;
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
906 foreach(k; A[1..$])
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
907 res ~= "," ~ k.stringof;
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
908 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
909 return res;
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
910 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
911
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
912 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
913 {
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 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
915 }
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
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 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
918 {
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 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
920 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
921 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
922 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
923 }
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
924
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 template SignalPred(T1, T2)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
926 {
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
927 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
928 }
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 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
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 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
933 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
934 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
935 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
936 }
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 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
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 (i < Needle.at.length)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
941 {
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
942 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
943 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
944 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
945 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
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 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
948 {
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 enum value = true;
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
950 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
951 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
952
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
953 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
954 {
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 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
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 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
958 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
959 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
960 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
961 }
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
962 }
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
963
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
964 template SigBySignPred(string name, SigArgs...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
965 {
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
966 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
967 {
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 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
969 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
970 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
971 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
972 }
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 }
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
974
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
975 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
976 {
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
977 const string staticSymbolName = prefix ~ ToString!(id);
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
978 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
979
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
980 template signatureString(string name, A...)
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 const string signatureString = name ~ "(" ~ joinArgs!(A) ~ ")";
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
983 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
984
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
985 template findSymbolImpl(string prefix, C, int id, alias pred)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
986 {
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
987 static if ( is(typeof(mixin("C." ~ staticSymbolName!(prefix, id)))) )
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
988 {
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
989 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
990 static if (pred!current)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
991 alias current result;
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
992 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
993 alias findSymbolImpl!(prefix, C, id + 1, pred).result result;
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
994 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
995 else
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
996 {
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
997 alias void result;
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
998 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
999 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1000
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
1001 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
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 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
1004 }
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
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 template findSignal(C, string name, Receiver, SigArgs...)
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1007 {
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
1008 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
1009 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
1010 {
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
1011 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
1012 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
1013 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
1014 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
1015 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
1016 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
1017 }
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
1018 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
1019 {
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
1020 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
1021 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
1022 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
1023 }
278
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1024 }
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1025
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1026 /** ---------------- */
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1027
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1028
5df570e79cfc new syntax for connecting using static information
eldar
parents: 276
diff changeset
1029 /**
1
e78566595089 initial import
mandel
parents:
diff changeset
1030 Examples:
e78566595089 initial import
mandel
parents:
diff changeset
1031 ----
e78566595089 initial import
mandel
parents:
diff changeset
1032 struct Args
e78566595089 initial import
mandel
parents:
diff changeset
1033 {
e78566595089 initial import
mandel
parents:
diff changeset
1034 bool cancel;
e78566595089 initial import
mandel
parents:
diff changeset
1035 }
e78566595089 initial import
mandel
parents:
diff changeset
1036
e78566595089 initial import
mandel
parents:
diff changeset
1037 class C
e78566595089 initial import
mandel
parents:
diff changeset
1038 {
e78566595089 initial import
mandel
parents:
diff changeset
1039 private int _x;
e78566595089 initial import
mandel
parents:
diff changeset
1040 // reference parameters are not supported yet,
e78566595089 initial import
mandel
parents:
diff changeset
1041 // so we pass arguments by pointer.
e78566595089 initial import
mandel
parents:
diff changeset
1042 mixin Signal!("xChanging", int, Args*);
e78566595089 initial import
mandel
parents:
diff changeset
1043 mixin Signal!("xChanged");
e78566595089 initial import
mandel
parents:
diff changeset
1044
e78566595089 initial import
mandel
parents:
diff changeset
1045 void x(int v)
e78566595089 initial import
mandel
parents:
diff changeset
1046 {
e78566595089 initial import
mandel
parents:
diff changeset
1047 if (v != _x)
e78566595089 initial import
mandel
parents:
diff changeset
1048 {
e78566595089 initial import
mandel
parents:
diff changeset
1049 Args args;
e78566595089 initial import
mandel
parents:
diff changeset
1050 xChanging.emit(v, &args);
e78566595089 initial import
mandel
parents:
diff changeset
1051 if (!args.cancel)
e78566595089 initial import
mandel
parents:
diff changeset
1052 {
e78566595089 initial import
mandel
parents:
diff changeset
1053 _x = v;
e78566595089 initial import
mandel
parents:
diff changeset
1054 xChanged.emit;
e78566595089 initial import
mandel
parents:
diff changeset
1055 }
e78566595089 initial import
mandel
parents:
diff changeset
1056 }
e78566595089 initial import
mandel
parents:
diff changeset
1057 }
e78566595089 initial import
mandel
parents:
diff changeset
1058 }
e78566595089 initial import
mandel
parents:
diff changeset
1059 ----
e78566595089 initial import
mandel
parents:
diff changeset
1060 */
e78566595089 initial import
mandel
parents:
diff changeset
1061 template Signal(string name, A...)
e78566595089 initial import
mandel
parents:
diff changeset
1062 {
e78566595089 initial import
mandel
parents:
diff changeset
1063 mixin SignalImpl!(0, name, A);
e78566595089 initial import
mandel
parents:
diff changeset
1064 }
e78566595089 initial import
mandel
parents:
diff changeset
1065
e78566595089 initial import
mandel
parents:
diff changeset
1066 template SignalImpl(int index, string name, A...)
e78566595089 initial import
mandel
parents:
diff changeset
1067 {
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
1068 static if (is(typeof(mixin(typeof(this).stringof ~ ".__signal" ~ ToString!(index)))))
1
e78566595089 initial import
mandel
parents:
diff changeset
1069 mixin SignalImpl!(index + 1, name, A);
e78566595089 initial import
mandel
parents:
diff changeset
1070 else
e78566595089 initial import
mandel
parents:
diff changeset
1071 {
e78566595089 initial import
mandel
parents:
diff changeset
1072 // mixed-in once
e78566595089 initial import
mandel
parents:
diff changeset
1073 static if (!is(typeof(this.signalHandler)))
e78566595089 initial import
mandel
parents:
diff changeset
1074 {
e78566595089 initial import
mandel
parents:
diff changeset
1075 mixin SignalHandlerOps;
e78566595089 initial import
mandel
parents:
diff changeset
1076 }
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
1077 mixin("public alias TypeTuple!(\"" ~ name ~ "\", index, A) __signal" ~ ToString!(index) ~ ";");
1
e78566595089 initial import
mandel
parents:
diff changeset
1078 mixin("SignalOps!(" ~ ToString!(index) ~ ", A) " ~ name ~ "(){ return SignalOps!("
e78566595089 initial import
mandel
parents:
diff changeset
1079 ~ ToString!(index) ~ ", A)(signalHandler); }");
e78566595089 initial import
mandel
parents:
diff changeset
1080 }
e78566595089 initial import
mandel
parents:
diff changeset
1081 }
e78566595089 initial import
mandel
parents:
diff changeset
1082
e78566595089 initial import
mandel
parents:
diff changeset
1083 extern(C) alias void function(void*) SlotConnector;
e78566595089 initial import
mandel
parents:
diff changeset
1084
e78566595089 initial import
mandel
parents:
diff changeset
1085 debug (UnitTest)
e78566595089 initial import
mandel
parents:
diff changeset
1086 {
e78566595089 initial import
mandel
parents:
diff changeset
1087 class A
e78566595089 initial import
mandel
parents:
diff changeset
1088 {
e78566595089 initial import
mandel
parents:
diff changeset
1089 mixin Signal!("scorched", int);
e78566595089 initial import
mandel
parents:
diff changeset
1090
e78566595089 initial import
mandel
parents:
diff changeset
1091 int signalId1 = -1;
e78566595089 initial import
mandel
parents:
diff changeset
1092 int signalId2 = -1;
e78566595089 initial import
mandel
parents:
diff changeset
1093
e78566595089 initial import
mandel
parents:
diff changeset
1094 void onFirstConnect(int sId)
e78566595089 initial import
mandel
parents:
diff changeset
1095 {
e78566595089 initial import
mandel
parents:
diff changeset
1096 signalId1 = sId;
e78566595089 initial import
mandel
parents:
diff changeset
1097 }
e78566595089 initial import
mandel
parents:
diff changeset
1098
e78566595089 initial import
mandel
parents:
diff changeset
1099 void onLastDisconnect(int sId)
e78566595089 initial import
mandel
parents:
diff changeset
1100 {
e78566595089 initial import
mandel
parents:
diff changeset
1101 signalId2 = sId;
e78566595089 initial import
mandel
parents:
diff changeset
1102 }
e78566595089 initial import
mandel
parents:
diff changeset
1103
e78566595089 initial import
mandel
parents:
diff changeset
1104 this()
e78566595089 initial import
mandel
parents:
diff changeset
1105 {
e78566595089 initial import
mandel
parents:
diff changeset
1106 signalHandler.firstSlotConnected = &onFirstConnect;
e78566595089 initial import
mandel
parents:
diff changeset
1107 signalHandler.lastSlotDisconnected = &onLastDisconnect;
e78566595089 initial import
mandel
parents:
diff changeset
1108 }
e78566595089 initial import
mandel
parents:
diff changeset
1109 }
e78566595089 initial import
mandel
parents:
diff changeset
1110
e78566595089 initial import
mandel
parents:
diff changeset
1111 class B : A
e78566595089 initial import
mandel
parents:
diff changeset
1112 {
e78566595089 initial import
mandel
parents:
diff changeset
1113 mixin Signal!("booed", int);
e78566595089 initial import
mandel
parents:
diff changeset
1114
e78566595089 initial import
mandel
parents:
diff changeset
1115 int bazSum;
e78566595089 initial import
mandel
parents:
diff changeset
1116 void baz(int i)
e78566595089 initial import
mandel
parents:
diff changeset
1117 {
e78566595089 initial import
mandel
parents:
diff changeset
1118 bazSum += i;
e78566595089 initial import
mandel
parents:
diff changeset
1119 }
e78566595089 initial import
mandel
parents:
diff changeset
1120 }
e78566595089 initial import
mandel
parents:
diff changeset
1121
e78566595089 initial import
mandel
parents:
diff changeset
1122 class C : A
e78566595089 initial import
mandel
parents:
diff changeset
1123 {
e78566595089 initial import
mandel
parents:
diff changeset
1124 mixin Signal!("cooked");
e78566595089 initial import
mandel
parents:
diff changeset
1125 }
e78566595089 initial import
mandel
parents:
diff changeset
1126 }
e78566595089 initial import
mandel
parents:
diff changeset
1127
e78566595089 initial import
mandel
parents:
diff changeset
1128 unittest
e78566595089 initial import
mandel
parents:
diff changeset
1129 {
e78566595089 initial import
mandel
parents:
diff changeset
1130 static int fooSum;
e78566595089 initial import
mandel
parents:
diff changeset
1131 static int barSum;
e78566595089 initial import
mandel
parents:
diff changeset
1132
e78566595089 initial import
mandel
parents:
diff changeset
1133 static void foo(int i)
e78566595089 initial import
mandel
parents:
diff changeset
1134 {
e78566595089 initial import
mandel
parents:
diff changeset
1135 fooSum += i;
e78566595089 initial import
mandel
parents:
diff changeset
1136 }
e78566595089 initial import
mandel
parents:
diff changeset
1137
e78566595089 initial import
mandel
parents:
diff changeset
1138 void bar(long i)
e78566595089 initial import
mandel
parents:
diff changeset
1139 {
e78566595089 initial import
mandel
parents:
diff changeset
1140 barSum += i;
e78566595089 initial import
mandel
parents:
diff changeset
1141 }
e78566595089 initial import
mandel
parents:
diff changeset
1142
e78566595089 initial import
mandel
parents:
diff changeset
1143 auto a = new A;
e78566595089 initial import
mandel
parents:
diff changeset
1144 auto b = new B;
e78566595089 initial import
mandel
parents:
diff changeset
1145 auto c = new C;
e78566595089 initial import
mandel
parents:
diff changeset
1146 assert(b.scorched.signalId == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1147 assert(b.booed.signalId == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1148 assert(c.cooked.signalId == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1149
e78566595089 initial import
mandel
parents:
diff changeset
1150 auto sh = b.signalHandler;
e78566595089 initial import
mandel
parents:
diff changeset
1151
e78566595089 initial import
mandel
parents:
diff changeset
1152 b.scorched.connect(&foo);
e78566595089 initial import
mandel
parents:
diff changeset
1153 assert(sh.connections.length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1154 assert(b.signalId1 == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1155 auto scCons = &sh.connections[0];
e78566595089 initial import
mandel
parents:
diff changeset
1156
e78566595089 initial import
mandel
parents:
diff changeset
1157 assert(scCons.getSlotList!(SlotListId.Func).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1158 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1159 assert(fooSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1160
e78566595089 initial import
mandel
parents:
diff changeset
1161 b.scorched.connect(&bar, ConnectionFlags.NoObject);
e78566595089 initial import
mandel
parents:
diff changeset
1162 assert(sh.connections.length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1163 assert(scCons.getSlotList!(SlotListId.Strong).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1164 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1165 assert (fooSum == 2 && barSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1166
e78566595089 initial import
mandel
parents:
diff changeset
1167 b.scorched.connect(&b.baz);
e78566595089 initial import
mandel
parents:
diff changeset
1168 assert(scCons.getSlotList!(SlotListId.Weak).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1169 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1170 assert (fooSum == 3 && barSum == 2 && b.bazSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1171
e78566595089 initial import
mandel
parents:
diff changeset
1172 b.scorched.disconnect(&bar);
e78566595089 initial import
mandel
parents:
diff changeset
1173 assert(scCons.slotCount == 2);
e78566595089 initial import
mandel
parents:
diff changeset
1174 b.scorched.disconnect(&b.baz);
e78566595089 initial import
mandel
parents:
diff changeset
1175 assert(scCons.slotCount == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1176 b.scorched.disconnect(&foo);
e78566595089 initial import
mandel
parents:
diff changeset
1177 assert(scCons.slotCount == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1178 assert(b.signalId2 == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1179
e78566595089 initial import
mandel
parents:
diff changeset
1180 fooSum = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1181 void connectFoo()
e78566595089 initial import
mandel
parents:
diff changeset
1182 {
e78566595089 initial import
mandel
parents:
diff changeset
1183 b.scorched.connect(&foo);
e78566595089 initial import
mandel
parents:
diff changeset
1184 b.scorched.disconnect(&connectFoo);
e78566595089 initial import
mandel
parents:
diff changeset
1185 }
e78566595089 initial import
mandel
parents:
diff changeset
1186
e78566595089 initial import
mandel
parents:
diff changeset
1187 b.scorched.connect(&connectFoo, ConnectionFlags.NoObject);
e78566595089 initial import
mandel
parents:
diff changeset
1188 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1189 assert(scCons.getSlotList!(SlotListId.Func).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1190 assert(scCons.getSlotList!(SlotListId.Strong).length == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1191 assert(!fooSum);
e78566595089 initial import
mandel
parents:
diff changeset
1192
e78566595089 initial import
mandel
parents:
diff changeset
1193 auto r = new B();
e78566595089 initial import
mandel
parents:
diff changeset
1194 b.scorched.connect(&r.baz);
e78566595089 initial import
mandel
parents:
diff changeset
1195 assert(scCons.getSlotList!(SlotListId.Weak).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1196 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1197 assert(r.bazSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1198 assert(fooSum == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1199
e78566595089 initial import
mandel
parents:
diff changeset
1200 delete(r);
e78566595089 initial import
mandel
parents:
diff changeset
1201 assert(scCons.getSlotList!(SlotListId.Weak).length == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1202 b.scorched.emit(1);
e78566595089 initial import
mandel
parents:
diff changeset
1203 assert(scCons.getSlotList!(SlotListId.Weak).length == 0);
e78566595089 initial import
mandel
parents:
diff changeset
1204 }