Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmeteor/include/syg/signal.hpp
2 views
1
#ifndef SYG_connection_HPP
2
#define SYG_connection_HPP
3
4
#include <list>
5
6
namespace syg
7
{
8
9
//------------------------------
10
// connections
11
//------------------------------
12
13
template <typename Tret>
14
class connection_base
15
{
16
public:
17
virtual Tret call() const = 0;
18
virtual connection_base<Tret>* clone() const = 0;
19
virtual ~connection_base() {}
20
};
21
22
template <typename Tret, typename Targ0>
23
class connection_base1
24
{
25
public:
26
virtual Tret call(Targ0) const = 0;
27
virtual connection_base1<Tret, Targ0>* clone() const = 0;
28
virtual ~connection_base1() {}
29
};
30
31
template <typename Tret>
32
class connection_func : public connection_base<Tret>
33
{
34
public:
35
typedef Tret (*FuncPtr)();
36
37
connection_func(FuncPtr ptr):
38
_func(ptr)
39
{}
40
41
Tret call() const
42
{
43
return _func();
44
}
45
46
connection_base<Tret>* clone() const
47
{
48
return new connection_func<Tret>(*this);
49
}
50
51
private:
52
FuncPtr _func;
53
};
54
55
template <typename Tret, typename Targ0>
56
class connection_func1 : public connection_base1<Tret, Targ0>
57
{
58
public:
59
typedef Tret (*FuncPtr)(Targ0);
60
61
connection_func1(FuncPtr ptr):
62
_func(ptr)
63
{}
64
65
Tret call(Targ0 arg0) const
66
{
67
return _func(arg0);
68
}
69
70
connection_base1<Tret, Targ0>* clone() const
71
{
72
return new connection_func1<Tret, Targ0>(*this);
73
}
74
75
private:
76
FuncPtr _func;
77
};
78
79
template <typename Tobj, typename Tret>
80
class connection_meth : public connection_base<Tret>
81
{
82
public:
83
typedef Tobj TypeObj;
84
typedef Tret (Tobj::*FuncPtr)();
85
86
connection_meth(TypeObj& obj, FuncPtr ptr):
87
_obj(obj),
88
_meth(ptr)
89
{}
90
91
Tret call() const
92
{
93
return (_obj.*_meth)();
94
}
95
96
connection_base<Tret>* clone() const
97
{
98
return new connection_meth<Tobj, Tret>(*this);
99
}
100
101
private:
102
Tobj& _obj;
103
FuncPtr _meth;
104
};
105
106
template <typename Tobj, typename Tret, typename Targ0>
107
class connection_meth1 : public connection_base1<Tret, Targ0>
108
{
109
public:
110
typedef Tobj TypeObj;
111
typedef Tret (Tobj::*FuncPtr)(Targ0);
112
113
connection_meth1(TypeObj& obj, FuncPtr ptr):
114
_obj(obj),
115
_meth(ptr)
116
{}
117
118
Tret call(Targ0 arg0) const
119
{
120
return (_obj.*_meth)(arg0);
121
}
122
123
connection_base1<Tret, Targ0>* clone() const
124
{
125
return new connection_meth1<Tobj, Tret, Targ0>(*this);
126
}
127
128
private:
129
Tobj& _obj;
130
FuncPtr _meth;
131
};
132
133
//------------------------------
134
// slots
135
//------------------------------
136
137
template <typename Tret>
138
class slot;
139
140
template <typename Tret, typename Targ0>
141
class slot1;
142
143
template <typename Tret>
144
slot<Tret> ptr_fun(Tret (*fun)());
145
146
template <typename Tobj, typename Tret>
147
slot<Tret> mem_fun(Tobj& obj, Tret (Tobj::*fun)());
148
149
template <typename Tret, typename Targ0>
150
slot1<Tret, Targ0> ptr_fun(Tret (*fun)(Targ0));
151
152
template <typename Tobj, typename Tret, typename Targ0>
153
slot1<Tret, Targ0> mem_fun(Tobj& obj, Tret (Tobj::*fun)(Targ0));
154
155
template <typename Tret>
156
class slot
157
{
158
public:
159
slot():
160
_conn(0)
161
{}
162
slot(const slot<Tret>& s)
163
{
164
*this = s;
165
}
166
~slot()
167
{
168
delete _conn;
169
}
170
171
slot& operator=(const slot<Tret>& s)
172
{
173
if (s._conn)
174
_conn = s._conn->clone();
175
else
176
_conn = 0;
177
178
return *this;
179
}
180
181
Tret call() const
182
{
183
return _conn->call();
184
}
185
186
Tret operator()() const
187
{
188
return call();
189
}
190
191
operator bool() const
192
{
193
return _conn;
194
}
195
196
private:
197
connection_base<Tret>* _conn;
198
199
slot(const connection_base<Tret>& conn):
200
_conn(conn.clone())
201
{}
202
203
friend slot<Tret> ptr_fun<Tret>(Tret (*fun)());
204
205
template <typename Tobj2, typename Tret2>
206
friend slot<Tret2> mem_fun(Tobj2& obj, Tret2 (Tobj2::*fun)());
207
};
208
209
template <typename Tret, typename Targ0>
210
class slot1
211
{
212
public:
213
typedef slot1<Tret, Targ0> SlotType;
214
215
slot1():
216
_conn(0)
217
{}
218
slot1(const SlotType& s)
219
{
220
*this = s;
221
}
222
~slot1()
223
{
224
delete _conn;
225
}
226
227
slot1& operator=(const SlotType& s)
228
{
229
if (s._conn)
230
_conn = s._conn->clone();
231
else
232
_conn = 0;
233
234
return *this;
235
}
236
237
Tret call(Targ0 arg0) const
238
{
239
return _conn->call(arg0);
240
}
241
242
Tret operator()(Targ0 arg0) const
243
{
244
return call(arg0);
245
}
246
247
operator bool() const
248
{
249
return _conn;
250
}
251
252
private:
253
typedef connection_base1<Tret, Targ0> Connection;
254
255
Connection* _conn;
256
257
slot1(const Connection& conn):
258
_conn(conn.clone())
259
{}
260
261
friend SlotType ptr_fun<Tret, Targ0>(Tret (*fun)(Targ0));
262
263
template <typename Tobj2, typename Tret2, typename Targ02>
264
friend slot1<Tret2, Targ02> mem_fun(Tobj2& obj,
265
Tret2 (Tobj2::*fun)(Targ02));
266
};
267
268
template <typename Tret>
269
inline slot<Tret> ptr_fun(Tret (*fun)())
270
{
271
return slot<Tret>(connection_func<Tret>(fun));
272
}
273
274
template <typename Tobj, typename Tret>
275
inline slot<Tret> mem_fun(Tobj& obj, Tret (Tobj::*fun)())
276
{
277
return slot<Tret>(connection_meth<Tobj, Tret>(obj, fun));
278
}
279
280
template <typename Tret, typename Targ0>
281
inline slot1<Tret, Targ0> ptr_fun(Tret (*fun)(Targ0))
282
{
283
return slot1<Tret, Targ0>(connection_func1<Tret, Targ0>(fun));
284
}
285
286
template <typename Tobj, typename Tret, typename Targ0>
287
inline slot1<Tret, Targ0> mem_fun(Tobj& obj, Tret (Tobj::*fun)(Targ0))
288
{
289
return slot1<Tret, Targ0>(connection_meth1<Tobj, Tret, Targ0>(obj, fun));
290
}
291
292
//------------------------------
293
// signals
294
//------------------------------
295
/*
296
template <typename Tret>
297
class signal;
298
299
template <typename Tret>
300
class connection
301
{
302
public:
303
connection():
304
_list(0)
305
{
306
}
307
308
void disconnect()
309
{
310
_list->erase(_iter);
311
}
312
313
private:
314
typedef std::list<slot<Tret> > List;
315
typedef typename List::iterator Iterator;
316
317
List* _list;
318
Iterator _iter;
319
320
connection(List* list, Iterator iter):
321
_list(list),
322
_iter(iter)
323
{}
324
325
friend class signal<Tret>;
326
};
327
328
template <typename Tret>
329
class signal
330
{
331
public:
332
connection<Tret> connect(const slot<Tret> s)
333
{
334
_slots.push_back(s);
335
return connection<Tret>(&_slots, (++_slots.rbegin()).base());
336
}
337
338
Tret emit() const
339
{
340
for (typename Slots::const_iterator iter = _slots.begin(),
341
end = (++_slots.rbegin()).base();
342
iter != end; ++iter)
343
iter->call();
344
345
return _slots.back().call();
346
}
347
348
Tret operator()() const
349
{
350
return emit();
351
}
352
353
private:
354
typedef std::list<slot<Tret> > Slots;
355
356
Slots _slots;
357
};
358
359
template <typename Tret, typename Targ0>
360
class signal1
361
{
362
public:
363
void connect(const slot<Tret> s)
364
{
365
_slots.push_back(s);
366
}
367
368
Tret emit(Targ0 arg0) const
369
{
370
for (typename Slots::const_iterator iter = _slots.begin(); iter != _slots.end() - 1; ++iter)
371
iter->call();
372
373
return _slots.back().call(arg0);
374
}
375
376
Tret operator()(Targ0 arg0) const
377
{
378
return emit(arg0);
379
}
380
381
private:
382
typedef std::list<slot<Tret> > Slots;
383
384
Slots _slots;
385
};
386
*/
387
} // namespace syg
388
389
#endif
390
391