milligram
Révision | df726866632f095971b477ee8f068558dca82726 (tree) |
---|---|
l'heure | 2011-03-24 17:11:53 |
Auteur | ![]() |
Commiter | beru |
bkup
@@ -0,0 +1,1038 @@ | ||
1 | +#ifndef UTIL_CALLBACK_HPP | |
2 | +#define UTIL_CALLBACK_HPP | |
3 | + | |
4 | +#define UTIL_GET_CALLBACK_FACTORY_BIND_FREE(freeFuncPtr) \ | |
5 | + (util::GetCallbackFactory(freeFuncPtr).Bind<freeFuncPtr>()) | |
6 | +#define BIND_FREE_CB UTIL_GET_CALLBACK_FACTORY_BIND_FREE | |
7 | + | |
8 | +#define UTIL_GET_CALLBACK_FACTORY_BIND_MEMBER(memFuncPtr, instancePtr) \ | |
9 | + (util::GetCallbackFactory(memFuncPtr).Bind<memFuncPtr>(instancePtr)) | |
10 | +#define BIND_MEM_CB UTIL_GET_CALLBACK_FACTORY_BIND_MEMBER | |
11 | + | |
12 | +namespace util { | |
13 | + | |
14 | +template<typename FuncSignature> | |
15 | +class Callback; | |
16 | + | |
17 | +struct NullCallback {}; | |
18 | + | |
19 | +// 0 parameter version | |
20 | + | |
21 | +template<typename R> | |
22 | +class Callback<R ()> | |
23 | +{ | |
24 | +public: | |
25 | + static const int Arity = 0; | |
26 | + typedef R ReturnType; | |
27 | + | |
28 | + Callback() : func(0), obj(0) {} | |
29 | + Callback(NullCallback) : func(0), obj(0) {} | |
30 | + Callback(const Callback& rhs) : func(rhs.func), obj(rhs.obj) {} | |
31 | + ~Callback() {} | |
32 | + | |
33 | + Callback& operator=(NullCallback) | |
34 | + { obj = 0; func = 0; return *this; } | |
35 | + Callback& operator=(const Callback& rhs) | |
36 | + { obj = rhs.obj; func = rhs.func; return *this; } | |
37 | + | |
38 | + inline R operator()() const | |
39 | + { | |
40 | + return (*func)(obj); | |
41 | + } | |
42 | + | |
43 | +private: | |
44 | + typedef const void* Callback::*SafeBoolType; | |
45 | +public: | |
46 | + inline operator SafeBoolType() const | |
47 | + { return func != 0 ? &Callback::obj : 0; } | |
48 | + inline bool operator!() const | |
49 | + { return func == 0; } | |
50 | + | |
51 | +private: | |
52 | + typedef R (*FuncType)(const void*); | |
53 | + Callback(FuncType f, const void* o) : func(f), obj(o) {} | |
54 | + | |
55 | +private: | |
56 | + FuncType func; | |
57 | + const void* obj; | |
58 | + | |
59 | + template<typename FR> | |
60 | + friend class FreeCallbackFactory0; | |
61 | + template<typename FR, class FT> | |
62 | + friend class MemberCallbackFactory0; | |
63 | + template<typename FR, class FT> | |
64 | + friend class ConstMemberCallbackFactory0; | |
65 | +}; | |
66 | + | |
67 | +template<typename R> | |
68 | +void operator==(const Callback<R ()>&, | |
69 | + const Callback<R ()>&); | |
70 | +template<typename R> | |
71 | +void operator!=(const Callback<R ()>&, | |
72 | + const Callback<R ()>&); | |
73 | + | |
74 | +template<typename R> | |
75 | +class FreeCallbackFactory0 | |
76 | +{ | |
77 | +private: | |
78 | + template<R (*Func)()> | |
79 | + static R Wrapper(const void*) | |
80 | + { | |
81 | + return (*Func)(); | |
82 | + } | |
83 | + | |
84 | +public: | |
85 | + template<R (*Func)()> | |
86 | + inline static Callback<R ()> Bind() | |
87 | + { | |
88 | + return Callback<R ()> | |
89 | + (&FreeCallbackFactory0::Wrapper<Func>, 0); | |
90 | + } | |
91 | +}; | |
92 | + | |
93 | +template<typename R> | |
94 | +inline FreeCallbackFactory0<R> | |
95 | +GetCallbackFactory(R (*)()) | |
96 | +{ | |
97 | + return FreeCallbackFactory0<R>(); | |
98 | +} | |
99 | + | |
100 | +template<typename R, class T> | |
101 | +class MemberCallbackFactory0 | |
102 | +{ | |
103 | +private: | |
104 | + template<R (T::*Func)()> | |
105 | + static R Wrapper(const void* o) | |
106 | + { | |
107 | + T* obj = const_cast<T*>(static_cast<const T*>(o)); | |
108 | + return (obj->*Func)(); | |
109 | + } | |
110 | + | |
111 | +public: | |
112 | + template<R (T::*Func)()> | |
113 | + inline static Callback<R ()> Bind(T* o) | |
114 | + { | |
115 | + return Callback<R ()> | |
116 | + (&MemberCallbackFactory0::Wrapper<Func>, | |
117 | + static_cast<const void*>(o)); | |
118 | + } | |
119 | +}; | |
120 | + | |
121 | +template<typename R, class T> | |
122 | +inline MemberCallbackFactory0<R, T> | |
123 | +GetCallbackFactory(R (T::*)()) | |
124 | +{ | |
125 | + return MemberCallbackFactory0<R, T>(); | |
126 | +} | |
127 | + | |
128 | +template<typename R, class T> | |
129 | +class ConstMemberCallbackFactory0 | |
130 | +{ | |
131 | +private: | |
132 | + template<R (T::*Func)() const> | |
133 | + static R Wrapper(const void* o) | |
134 | + { | |
135 | + const T* obj = static_cast<const T*>(o); | |
136 | + return (obj->*Func)(); | |
137 | + } | |
138 | + | |
139 | +public: | |
140 | + template<R (T::*Func)() const> | |
141 | + inline static Callback<R ()> Bind(const T* o) | |
142 | + { | |
143 | + return Callback<R ()> | |
144 | + (&ConstMemberCallbackFactory0::Wrapper<Func>, | |
145 | + static_cast<const void*>(o)); | |
146 | + } | |
147 | +}; | |
148 | + | |
149 | +template<typename R, class T> | |
150 | +inline ConstMemberCallbackFactory0<R, T> | |
151 | +GetCallbackFactory(R (T::*)() const) | |
152 | +{ | |
153 | + return ConstMemberCallbackFactory0<R, T>(); | |
154 | +} | |
155 | + | |
156 | +// 1 parameter version | |
157 | + | |
158 | +template<typename R, typename P1> | |
159 | +class Callback<R (P1)> | |
160 | +{ | |
161 | +public: | |
162 | + static const int Arity = 1; | |
163 | + typedef R ReturnType; | |
164 | + typedef P1 Param1Type; | |
165 | + | |
166 | + Callback() : func(0), obj(0) {} | |
167 | + Callback(NullCallback) : func(0), obj(0) {} | |
168 | + Callback(const Callback& rhs) : func(rhs.func), obj(rhs.obj) {} | |
169 | + ~Callback() {} | |
170 | + | |
171 | + Callback& operator=(NullCallback) | |
172 | + { obj = 0; func = 0; return *this; } | |
173 | + Callback& operator=(const Callback& rhs) | |
174 | + { obj = rhs.obj; func = rhs.func; return *this; } | |
175 | + | |
176 | + inline R operator()(P1 a1) const | |
177 | + { | |
178 | + return (*func)(obj, a1); | |
179 | + } | |
180 | + | |
181 | +private: | |
182 | + typedef const void* Callback::*SafeBoolType; | |
183 | +public: | |
184 | + inline operator SafeBoolType() const | |
185 | + { return func != 0 ? &Callback::obj : 0; } | |
186 | + inline bool operator!() const | |
187 | + { return func == 0; } | |
188 | + | |
189 | +private: | |
190 | + typedef R (*FuncType)(const void*, P1); | |
191 | + Callback(FuncType f, const void* o) : func(f), obj(o) {} | |
192 | + | |
193 | +private: | |
194 | + FuncType func; | |
195 | + const void* obj; | |
196 | + | |
197 | + template<typename FR, typename FP1> | |
198 | + friend class FreeCallbackFactory1; | |
199 | + template<typename FR, class FT, typename FP1> | |
200 | + friend class MemberCallbackFactory1; | |
201 | + template<typename FR, class FT, typename FP1> | |
202 | + friend class ConstMemberCallbackFactory1; | |
203 | +}; | |
204 | + | |
205 | +template<typename R, typename P1> | |
206 | +void operator==(const Callback<R (P1)>&, | |
207 | + const Callback<R (P1)>&); | |
208 | +template<typename R, typename P1> | |
209 | +void operator!=(const Callback<R (P1)>&, | |
210 | + const Callback<R (P1)>&); | |
211 | + | |
212 | +template<typename R, typename P1> | |
213 | +class FreeCallbackFactory1 | |
214 | +{ | |
215 | +private: | |
216 | + template<R (*Func)(P1)> | |
217 | + static R Wrapper(const void*, P1 a1) | |
218 | + { | |
219 | + return (*Func)(a1); | |
220 | + } | |
221 | + | |
222 | +public: | |
223 | + template<R (*Func)(P1)> | |
224 | + inline static Callback<R (P1)> Bind() | |
225 | + { | |
226 | + return Callback<R (P1)> | |
227 | + (&FreeCallbackFactory1::Wrapper<Func>, 0); | |
228 | + } | |
229 | +}; | |
230 | + | |
231 | +template<typename R, typename P1> | |
232 | +inline FreeCallbackFactory1<R, P1> | |
233 | +GetCallbackFactory(R (*)(P1)) | |
234 | +{ | |
235 | + return FreeCallbackFactory1<R, P1>(); | |
236 | +} | |
237 | + | |
238 | +template<typename R, class T, typename P1> | |
239 | +class MemberCallbackFactory1 | |
240 | +{ | |
241 | +private: | |
242 | + template<R (T::*Func)(P1)> | |
243 | + static R Wrapper(const void* o, P1 a1) | |
244 | + { | |
245 | + T* obj = const_cast<T*>(static_cast<const T*>(o)); | |
246 | + return (obj->*Func)(a1); | |
247 | + } | |
248 | + | |
249 | +public: | |
250 | + template<R (T::*Func)(P1)> | |
251 | + inline static Callback<R (P1)> Bind(T* o) | |
252 | + { | |
253 | + return Callback<R (P1)> | |
254 | + (&MemberCallbackFactory1::Wrapper<Func>, | |
255 | + static_cast<const void*>(o)); | |
256 | + } | |
257 | +}; | |
258 | + | |
259 | +template<typename R, class T, typename P1> | |
260 | +inline MemberCallbackFactory1<R, T, P1> | |
261 | +GetCallbackFactory(R (T::*)(P1)) | |
262 | +{ | |
263 | + return MemberCallbackFactory1<R, T, P1>(); | |
264 | +} | |
265 | + | |
266 | +template<typename R, class T, typename P1> | |
267 | +class ConstMemberCallbackFactory1 | |
268 | +{ | |
269 | +private: | |
270 | + template<R (T::*Func)(P1) const> | |
271 | + static R Wrapper(const void* o, P1 a1) | |
272 | + { | |
273 | + const T* obj = static_cast<const T*>(o); | |
274 | + return (obj->*Func)(a1); | |
275 | + } | |
276 | + | |
277 | +public: | |
278 | + template<R (T::*Func)(P1) const> | |
279 | + inline static Callback<R (P1)> Bind(const T* o) | |
280 | + { | |
281 | + return Callback<R (P1)> | |
282 | + (&ConstMemberCallbackFactory1::Wrapper<Func>, | |
283 | + static_cast<const void*>(o)); | |
284 | + } | |
285 | +}; | |
286 | + | |
287 | +template<typename R, class T, typename P1> | |
288 | +inline ConstMemberCallbackFactory1<R, T, P1> | |
289 | +GetCallbackFactory(R (T::*)(P1) const) | |
290 | +{ | |
291 | + return ConstMemberCallbackFactory1<R, T, P1>(); | |
292 | +} | |
293 | + | |
294 | +// 2 parameter version | |
295 | + | |
296 | +template<typename R, typename P1, typename P2> | |
297 | +class Callback<R (P1, P2)> | |
298 | +{ | |
299 | +public: | |
300 | + static const int Arity = 2; | |
301 | + typedef R ReturnType; | |
302 | + typedef P1 Param1Type; | |
303 | + typedef P2 Param2Type; | |
304 | + | |
305 | + Callback() : func(0), obj(0) {} | |
306 | + Callback(NullCallback) : func(0), obj(0) {} | |
307 | + Callback(const Callback& rhs) : func(rhs.func), obj(rhs.obj) {} | |
308 | + ~Callback() {} | |
309 | + | |
310 | + Callback& operator=(NullCallback) | |
311 | + { obj = 0; func = 0; return *this; } | |
312 | + Callback& operator=(const Callback& rhs) | |
313 | + { obj = rhs.obj; func = rhs.func; return *this; } | |
314 | + | |
315 | + inline R operator()(P1 a1, P2 a2) const | |
316 | + { | |
317 | + return (*func)(obj, a1, a2); | |
318 | + } | |
319 | + | |
320 | +private: | |
321 | + typedef const void* Callback::*SafeBoolType; | |
322 | +public: | |
323 | + inline operator SafeBoolType() const | |
324 | + { return func != 0 ? &Callback::obj : 0; } | |
325 | + inline bool operator!() const | |
326 | + { return func == 0; } | |
327 | + | |
328 | +private: | |
329 | + typedef R (*FuncType)(const void*, P1, P2); | |
330 | + Callback(FuncType f, const void* o) : func(f), obj(o) {} | |
331 | + | |
332 | +private: | |
333 | + FuncType func; | |
334 | + const void* obj; | |
335 | + | |
336 | + template<typename FR, typename FP1, typename FP2> | |
337 | + friend class FreeCallbackFactory2; | |
338 | + template<typename FR, class FT, typename FP1, typename FP2> | |
339 | + friend class MemberCallbackFactory2; | |
340 | + template<typename FR, class FT, typename FP1, typename FP2> | |
341 | + friend class ConstMemberCallbackFactory2; | |
342 | +}; | |
343 | + | |
344 | +template<typename R, typename P1, typename P2> | |
345 | +void operator==(const Callback<R (P1, P2)>&, | |
346 | + const Callback<R (P1, P2)>&); | |
347 | +template<typename R, typename P1, typename P2> | |
348 | +void operator!=(const Callback<R (P1, P2)>&, | |
349 | + const Callback<R (P1, P2)>&); | |
350 | + | |
351 | +template<typename R, typename P1, typename P2> | |
352 | +class FreeCallbackFactory2 | |
353 | +{ | |
354 | +private: | |
355 | + template<R (*Func)(P1, P2)> | |
356 | + static R Wrapper(const void*, P1 a1, P2 a2) | |
357 | + { | |
358 | + return (*Func)(a1, a2); | |
359 | + } | |
360 | + | |
361 | +public: | |
362 | + template<R (*Func)(P1, P2)> | |
363 | + inline static Callback<R (P1, P2)> Bind() | |
364 | + { | |
365 | + return Callback<R (P1, P2)> | |
366 | + (&FreeCallbackFactory2::Wrapper<Func>, 0); | |
367 | + } | |
368 | +}; | |
369 | + | |
370 | +template<typename R, typename P1, typename P2> | |
371 | +inline FreeCallbackFactory2<R, P1, P2> | |
372 | +GetCallbackFactory(R (*)(P1, P2)) | |
373 | +{ | |
374 | + return FreeCallbackFactory2<R, P1, P2>(); | |
375 | +} | |
376 | + | |
377 | +template<typename R, class T, typename P1, typename P2> | |
378 | +class MemberCallbackFactory2 | |
379 | +{ | |
380 | +private: | |
381 | + template<R (T::*Func)(P1, P2)> | |
382 | + static R Wrapper(const void* o, P1 a1, P2 a2) | |
383 | + { | |
384 | + T* obj = const_cast<T*>(static_cast<const T*>(o)); | |
385 | + return (obj->*Func)(a1, a2); | |
386 | + } | |
387 | + | |
388 | +public: | |
389 | + template<R (T::*Func)(P1, P2)> | |
390 | + inline static Callback<R (P1, P2)> Bind(T* o) | |
391 | + { | |
392 | + return Callback<R (P1, P2)> | |
393 | + (&MemberCallbackFactory2::Wrapper<Func>, | |
394 | + static_cast<const void*>(o)); | |
395 | + } | |
396 | +}; | |
397 | + | |
398 | +template<typename R, class T, typename P1, typename P2> | |
399 | +inline MemberCallbackFactory2<R, T, P1, P2> | |
400 | +GetCallbackFactory(R (T::*)(P1, P2)) | |
401 | +{ | |
402 | + return MemberCallbackFactory2<R, T, P1, P2>(); | |
403 | +} | |
404 | + | |
405 | +template<typename R, class T, typename P1, typename P2> | |
406 | +class ConstMemberCallbackFactory2 | |
407 | +{ | |
408 | +private: | |
409 | + template<R (T::*Func)(P1, P2) const> | |
410 | + static R Wrapper(const void* o, P1 a1, P2 a2) | |
411 | + { | |
412 | + const T* obj = static_cast<const T*>(o); | |
413 | + return (obj->*Func)(a1, a2); | |
414 | + } | |
415 | + | |
416 | +public: | |
417 | + template<R (T::*Func)(P1, P2) const> | |
418 | + inline static Callback<R (P1, P2)> Bind(const T* o) | |
419 | + { | |
420 | + return Callback<R (P1, P2)> | |
421 | + (&ConstMemberCallbackFactory2::Wrapper<Func>, | |
422 | + static_cast<const void*>(o)); | |
423 | + } | |
424 | +}; | |
425 | + | |
426 | +template<typename R, class T, typename P1, typename P2> | |
427 | +inline ConstMemberCallbackFactory2<R, T, P1, P2> | |
428 | +GetCallbackFactory(R (T::*)(P1, P2) const) | |
429 | +{ | |
430 | + return ConstMemberCallbackFactory2<R, T, P1, P2>(); | |
431 | +} | |
432 | + | |
433 | +// 3 parameter version | |
434 | + | |
435 | +template<typename R, typename P1, typename P2, typename P3> | |
436 | +class Callback<R (P1, P2, P3)> | |
437 | +{ | |
438 | +public: | |
439 | + static const int Arity = 3; | |
440 | + typedef R ReturnType; | |
441 | + typedef P1 Param1Type; | |
442 | + typedef P2 Param2Type; | |
443 | + typedef P3 Param3Type; | |
444 | + | |
445 | + Callback() : func(0), obj(0) {} | |
446 | + Callback(NullCallback) : func(0), obj(0) {} | |
447 | + Callback(const Callback& rhs) : func(rhs.func), obj(rhs.obj) {} | |
448 | + ~Callback() {} | |
449 | + | |
450 | + Callback& operator=(NullCallback) | |
451 | + { obj = 0; func = 0; return *this; } | |
452 | + Callback& operator=(const Callback& rhs) | |
453 | + { obj = rhs.obj; func = rhs.func; return *this; } | |
454 | + | |
455 | + inline R operator()(P1 a1, P2 a2, P3 a3) const | |
456 | + { | |
457 | + return (*func)(obj, a1, a2, a3); | |
458 | + } | |
459 | + | |
460 | +private: | |
461 | + typedef const void* Callback::*SafeBoolType; | |
462 | +public: | |
463 | + inline operator SafeBoolType() const | |
464 | + { return func != 0 ? &Callback::obj : 0; } | |
465 | + inline bool operator!() const | |
466 | + { return func == 0; } | |
467 | + | |
468 | +private: | |
469 | + typedef R (*FuncType)(const void*, P1, P2, P3); | |
470 | + Callback(FuncType f, const void* o) : func(f), obj(o) {} | |
471 | + | |
472 | +private: | |
473 | + FuncType func; | |
474 | + const void* obj; | |
475 | + | |
476 | + template<typename FR, typename FP1, typename FP2, typename FP3> | |
477 | + friend class FreeCallbackFactory3; | |
478 | + template<typename FR, class FT, typename FP1, typename FP2, typename FP3> | |
479 | + friend class MemberCallbackFactory3; | |
480 | + template<typename FR, class FT, typename FP1, typename FP2, typename FP3> | |
481 | + friend class ConstMemberCallbackFactory3; | |
482 | +}; | |
483 | + | |
484 | +template<typename R, typename P1, typename P2, typename P3> | |
485 | +void operator==(const Callback<R (P1, P2, P3)>&, | |
486 | + const Callback<R (P1, P2, P3)>&); | |
487 | +template<typename R, typename P1, typename P2, typename P3> | |
488 | +void operator!=(const Callback<R (P1, P2, P3)>&, | |
489 | + const Callback<R (P1, P2, P3)>&); | |
490 | + | |
491 | +template<typename R, typename P1, typename P2, typename P3> | |
492 | +class FreeCallbackFactory3 | |
493 | +{ | |
494 | +private: | |
495 | + template<R (*Func)(P1, P2, P3)> | |
496 | + static R Wrapper(const void*, P1 a1, P2 a2, P3 a3) | |
497 | + { | |
498 | + return (*Func)(a1, a2, a3); | |
499 | + } | |
500 | + | |
501 | +public: | |
502 | + template<R (*Func)(P1, P2, P3)> | |
503 | + inline static Callback<R (P1, P2, P3)> Bind() | |
504 | + { | |
505 | + return Callback<R (P1, P2, P3)> | |
506 | + (&FreeCallbackFactory3::Wrapper<Func>, 0); | |
507 | + } | |
508 | +}; | |
509 | + | |
510 | +template<typename R, typename P1, typename P2, typename P3> | |
511 | +inline FreeCallbackFactory3<R, P1, P2, P3> | |
512 | +GetCallbackFactory(R (*)(P1, P2, P3)) | |
513 | +{ | |
514 | + return FreeCallbackFactory3<R, P1, P2, P3>(); | |
515 | +} | |
516 | + | |
517 | +template<typename R, class T, typename P1, typename P2, typename P3> | |
518 | +class MemberCallbackFactory3 | |
519 | +{ | |
520 | +private: | |
521 | + template<R (T::*Func)(P1, P2, P3)> | |
522 | + static R Wrapper(const void* o, P1 a1, P2 a2, P3 a3) | |
523 | + { | |
524 | + T* obj = const_cast<T*>(static_cast<const T*>(o)); | |
525 | + return (obj->*Func)(a1, a2, a3); | |
526 | + } | |
527 | + | |
528 | +public: | |
529 | + template<R (T::*Func)(P1, P2, P3)> | |
530 | + inline static Callback<R (P1, P2, P3)> Bind(T* o) | |
531 | + { | |
532 | + return Callback<R (P1, P2, P3)> | |
533 | + (&MemberCallbackFactory3::Wrapper<Func>, | |
534 | + static_cast<const void*>(o)); | |
535 | + } | |
536 | +}; | |
537 | + | |
538 | +template<typename R, class T, typename P1, typename P2, typename P3> | |
539 | +inline MemberCallbackFactory3<R, T, P1, P2, P3> | |
540 | +GetCallbackFactory(R (T::*)(P1, P2, P3)) | |
541 | +{ | |
542 | + return MemberCallbackFactory3<R, T, P1, P2, P3>(); | |
543 | +} | |
544 | + | |
545 | +template<typename R, class T, typename P1, typename P2, typename P3> | |
546 | +class ConstMemberCallbackFactory3 | |
547 | +{ | |
548 | +private: | |
549 | + template<R (T::*Func)(P1, P2, P3) const> | |
550 | + static R Wrapper(const void* o, P1 a1, P2 a2, P3 a3) | |
551 | + { | |
552 | + const T* obj = static_cast<const T*>(o); | |
553 | + return (obj->*Func)(a1, a2, a3); | |
554 | + } | |
555 | + | |
556 | +public: | |
557 | + template<R (T::*Func)(P1, P2, P3) const> | |
558 | + inline static Callback<R (P1, P2, P3)> Bind(const T* o) | |
559 | + { | |
560 | + return Callback<R (P1, P2, P3)> | |
561 | + (&ConstMemberCallbackFactory3::Wrapper<Func>, | |
562 | + static_cast<const void*>(o)); | |
563 | + } | |
564 | +}; | |
565 | + | |
566 | +template<typename R, class T, typename P1, typename P2, typename P3> | |
567 | +inline ConstMemberCallbackFactory3<R, T, P1, P2, P3> | |
568 | +GetCallbackFactory(R (T::*)(P1, P2, P3) const) | |
569 | +{ | |
570 | + return ConstMemberCallbackFactory3<R, T, P1, P2, P3>(); | |
571 | +} | |
572 | + | |
573 | +// 4 parameter version | |
574 | + | |
575 | +template<typename R, typename P1, typename P2, typename P3, | |
576 | + typename P4> | |
577 | +class Callback<R (P1, P2, P3, P4)> | |
578 | +{ | |
579 | +public: | |
580 | + static const int Arity = 4; | |
581 | + typedef R ReturnType; | |
582 | + typedef P1 Param1Type; | |
583 | + typedef P2 Param2Type; | |
584 | + typedef P3 Param3Type; | |
585 | + typedef P4 Param4Type; | |
586 | + | |
587 | + Callback() : func(0), obj(0) {} | |
588 | + Callback(NullCallback) : func(0), obj(0) {} | |
589 | + Callback(const Callback& rhs) : func(rhs.func), obj(rhs.obj) {} | |
590 | + ~Callback() {} | |
591 | + | |
592 | + Callback& operator=(NullCallback) | |
593 | + { obj = 0; func = 0; return *this; } | |
594 | + Callback& operator=(const Callback& rhs) | |
595 | + { obj = rhs.obj; func = rhs.func; return *this; } | |
596 | + | |
597 | + inline R operator()(P1 a1, P2 a2, P3 a3, P4 a4) const | |
598 | + { | |
599 | + return (*func)(obj, a1, a2, a3, a4); | |
600 | + } | |
601 | + | |
602 | +private: | |
603 | + typedef const void* Callback::*SafeBoolType; | |
604 | +public: | |
605 | + inline operator SafeBoolType() const | |
606 | + { return func != 0 ? &Callback::obj : 0; } | |
607 | + inline bool operator!() const | |
608 | + { return func == 0; } | |
609 | + | |
610 | +private: | |
611 | + typedef R (*FuncType)(const void*, P1, P2, P3, P4); | |
612 | + Callback(FuncType f, const void* o) : func(f), obj(o) {} | |
613 | + | |
614 | +private: | |
615 | + FuncType func; | |
616 | + const void* obj; | |
617 | + | |
618 | + template<typename FR, typename FP1, typename FP2, typename FP3, | |
619 | + typename FP4> | |
620 | + friend class FreeCallbackFactory4; | |
621 | + template<typename FR, class FT, typename FP1, typename FP2, typename FP3, | |
622 | + typename FP4> | |
623 | + friend class MemberCallbackFactory4; | |
624 | + template<typename FR, class FT, typename FP1, typename FP2, typename FP3, | |
625 | + typename FP4> | |
626 | + friend class ConstMemberCallbackFactory4; | |
627 | +}; | |
628 | + | |
629 | +template<typename R, typename P1, typename P2, typename P3, | |
630 | + typename P4> | |
631 | +void operator==(const Callback<R (P1, P2, P3, P4)>&, | |
632 | + const Callback<R (P1, P2, P3, P4)>&); | |
633 | +template<typename R, typename P1, typename P2, typename P3, | |
634 | + typename P4> | |
635 | +void operator!=(const Callback<R (P1, P2, P3, P4)>&, | |
636 | + const Callback<R (P1, P2, P3, P4)>&); | |
637 | + | |
638 | +template<typename R, typename P1, typename P2, typename P3, | |
639 | + typename P4> | |
640 | +class FreeCallbackFactory4 | |
641 | +{ | |
642 | +private: | |
643 | + template<R (*Func)(P1, P2, P3, P4)> | |
644 | + static R Wrapper(const void*, P1 a1, P2 a2, P3 a3, P4 a4) | |
645 | + { | |
646 | + return (*Func)(a1, a2, a3, a4); | |
647 | + } | |
648 | + | |
649 | +public: | |
650 | + template<R (*Func)(P1, P2, P3, P4)> | |
651 | + inline static Callback<R (P1, P2, P3, P4)> Bind() | |
652 | + { | |
653 | + return Callback<R (P1, P2, P3, P4)> | |
654 | + (&FreeCallbackFactory4::Wrapper<Func>, 0); | |
655 | + } | |
656 | +}; | |
657 | + | |
658 | +template<typename R, typename P1, typename P2, typename P3, | |
659 | + typename P4> | |
660 | +inline FreeCallbackFactory4<R, P1, P2, P3, P4> | |
661 | +GetCallbackFactory(R (*)(P1, P2, P3, P4)) | |
662 | +{ | |
663 | + return FreeCallbackFactory4<R, P1, P2, P3, P4>(); | |
664 | +} | |
665 | + | |
666 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
667 | + typename P4> | |
668 | +class MemberCallbackFactory4 | |
669 | +{ | |
670 | +private: | |
671 | + template<R (T::*Func)(P1, P2, P3, P4)> | |
672 | + static R Wrapper(const void* o, P1 a1, P2 a2, P3 a3, P4 a4) | |
673 | + { | |
674 | + T* obj = const_cast<T*>(static_cast<const T*>(o)); | |
675 | + return (obj->*Func)(a1, a2, a3, a4); | |
676 | + } | |
677 | + | |
678 | +public: | |
679 | + template<R (T::*Func)(P1, P2, P3, P4)> | |
680 | + inline static Callback<R (P1, P2, P3, P4)> Bind(T* o) | |
681 | + { | |
682 | + return Callback<R (P1, P2, P3, P4)> | |
683 | + (&MemberCallbackFactory4::Wrapper<Func>, | |
684 | + static_cast<const void*>(o)); | |
685 | + } | |
686 | +}; | |
687 | + | |
688 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
689 | + typename P4> | |
690 | +inline MemberCallbackFactory4<R, T, P1, P2, P3, P4> | |
691 | +GetCallbackFactory(R (T::*)(P1, P2, P3, P4)) | |
692 | +{ | |
693 | + return MemberCallbackFactory4<R, T, P1, P2, P3, P4>(); | |
694 | +} | |
695 | + | |
696 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
697 | + typename P4> | |
698 | +class ConstMemberCallbackFactory4 | |
699 | +{ | |
700 | +private: | |
701 | + template<R (T::*Func)(P1, P2, P3, P4) const> | |
702 | + static R Wrapper(const void* o, P1 a1, P2 a2, P3 a3, P4 a4) | |
703 | + { | |
704 | + const T* obj = static_cast<const T*>(o); | |
705 | + return (obj->*Func)(a1, a2, a3, a4); | |
706 | + } | |
707 | + | |
708 | +public: | |
709 | + template<R (T::*Func)(P1, P2, P3, P4) const> | |
710 | + inline static Callback<R (P1, P2, P3, P4)> Bind(const T* o) | |
711 | + { | |
712 | + return Callback<R (P1, P2, P3, P4)> | |
713 | + (&ConstMemberCallbackFactory4::Wrapper<Func>, | |
714 | + static_cast<const void*>(o)); | |
715 | + } | |
716 | +}; | |
717 | + | |
718 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
719 | + typename P4> | |
720 | +inline ConstMemberCallbackFactory4<R, T, P1, P2, P3, P4> | |
721 | +GetCallbackFactory(R (T::*)(P1, P2, P3, P4) const) | |
722 | +{ | |
723 | + return ConstMemberCallbackFactory4<R, T, P1, P2, P3, P4>(); | |
724 | +} | |
725 | + | |
726 | +// 5 parameter version | |
727 | + | |
728 | +template<typename R, typename P1, typename P2, typename P3, | |
729 | + typename P4, typename P5> | |
730 | +class Callback<R (P1, P2, P3, P4, P5)> | |
731 | +{ | |
732 | +public: | |
733 | + static const int Arity = 5; | |
734 | + typedef R ReturnType; | |
735 | + typedef P1 Param1Type; | |
736 | + typedef P2 Param2Type; | |
737 | + typedef P3 Param3Type; | |
738 | + typedef P4 Param4Type; | |
739 | + typedef P5 Param5Type; | |
740 | + | |
741 | + Callback() : func(0), obj(0) {} | |
742 | + Callback(NullCallback) : func(0), obj(0) {} | |
743 | + Callback(const Callback& rhs) : func(rhs.func), obj(rhs.obj) {} | |
744 | + ~Callback() {} | |
745 | + | |
746 | + Callback& operator=(NullCallback) | |
747 | + { obj = 0; func = 0; return *this; } | |
748 | + Callback& operator=(const Callback& rhs) | |
749 | + { obj = rhs.obj; func = rhs.func; return *this; } | |
750 | + | |
751 | + inline R operator()(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) const | |
752 | + { | |
753 | + return (*func)(obj, a1, a2, a3, a4, a5); | |
754 | + } | |
755 | + | |
756 | +private: | |
757 | + typedef const void* Callback::*SafeBoolType; | |
758 | +public: | |
759 | + inline operator SafeBoolType() const | |
760 | + { return func != 0 ? &Callback::obj : 0; } | |
761 | + inline bool operator!() const | |
762 | + { return func == 0; } | |
763 | + | |
764 | +private: | |
765 | + typedef R (*FuncType)(const void*, P1, P2, P3, P4, P5); | |
766 | + Callback(FuncType f, const void* o) : func(f), obj(o) {} | |
767 | + | |
768 | +private: | |
769 | + FuncType func; | |
770 | + const void* obj; | |
771 | + | |
772 | + template<typename FR, typename FP1, typename FP2, typename FP3, | |
773 | + typename FP4, typename FP5> | |
774 | + friend class FreeCallbackFactory5; | |
775 | + template<typename FR, class FT, typename FP1, typename FP2, typename FP3, | |
776 | + typename FP4, typename FP5> | |
777 | + friend class MemberCallbackFactory5; | |
778 | + template<typename FR, class FT, typename FP1, typename FP2, typename FP3, | |
779 | + typename FP4, typename FP5> | |
780 | + friend class ConstMemberCallbackFactory5; | |
781 | +}; | |
782 | + | |
783 | +template<typename R, typename P1, typename P2, typename P3, | |
784 | + typename P4, typename P5> | |
785 | +void operator==(const Callback<R (P1, P2, P3, P4, P5)>&, | |
786 | + const Callback<R (P1, P2, P3, P4, P5)>&); | |
787 | +template<typename R, typename P1, typename P2, typename P3, | |
788 | + typename P4, typename P5> | |
789 | +void operator!=(const Callback<R (P1, P2, P3, P4, P5)>&, | |
790 | + const Callback<R (P1, P2, P3, P4, P5)>&); | |
791 | + | |
792 | +template<typename R, typename P1, typename P2, typename P3, | |
793 | + typename P4, typename P5> | |
794 | +class FreeCallbackFactory5 | |
795 | +{ | |
796 | +private: | |
797 | + template<R (*Func)(P1, P2, P3, P4, P5)> | |
798 | + static R Wrapper(const void*, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) | |
799 | + { | |
800 | + return (*Func)(a1, a2, a3, a4, a5); | |
801 | + } | |
802 | + | |
803 | +public: | |
804 | + template<R (*Func)(P1, P2, P3, P4, P5)> | |
805 | + inline static Callback<R (P1, P2, P3, P4, P5)> Bind() | |
806 | + { | |
807 | + return Callback<R (P1, P2, P3, P4, P5)> | |
808 | + (&FreeCallbackFactory5::Wrapper<Func>, 0); | |
809 | + } | |
810 | +}; | |
811 | + | |
812 | +template<typename R, typename P1, typename P2, typename P3, | |
813 | + typename P4, typename P5> | |
814 | +inline FreeCallbackFactory5<R, P1, P2, P3, P4, P5> | |
815 | +GetCallbackFactory(R (*)(P1, P2, P3, P4, P5)) | |
816 | +{ | |
817 | + return FreeCallbackFactory5<R, P1, P2, P3, P4, P5>(); | |
818 | +} | |
819 | + | |
820 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
821 | + typename P4, typename P5> | |
822 | +class MemberCallbackFactory5 | |
823 | +{ | |
824 | +private: | |
825 | + template<R (T::*Func)(P1, P2, P3, P4, P5)> | |
826 | + static R Wrapper(const void* o, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) | |
827 | + { | |
828 | + T* obj = const_cast<T*>(static_cast<const T*>(o)); | |
829 | + return (obj->*Func)(a1, a2, a3, a4, a5); | |
830 | + } | |
831 | + | |
832 | +public: | |
833 | + template<R (T::*Func)(P1, P2, P3, P4, P5)> | |
834 | + inline static Callback<R (P1, P2, P3, P4, P5)> Bind(T* o) | |
835 | + { | |
836 | + return Callback<R (P1, P2, P3, P4, P5)> | |
837 | + (&MemberCallbackFactory5::Wrapper<Func>, | |
838 | + static_cast<const void*>(o)); | |
839 | + } | |
840 | +}; | |
841 | + | |
842 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
843 | + typename P4, typename P5> | |
844 | +inline MemberCallbackFactory5<R, T, P1, P2, P3, P4, P5> | |
845 | +GetCallbackFactory(R (T::*)(P1, P2, P3, P4, P5)) | |
846 | +{ | |
847 | + return MemberCallbackFactory5<R, T, P1, P2, P3, P4, P5>(); | |
848 | +} | |
849 | + | |
850 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
851 | + typename P4, typename P5> | |
852 | +class ConstMemberCallbackFactory5 | |
853 | +{ | |
854 | +private: | |
855 | + template<R (T::*Func)(P1, P2, P3, P4, P5) const> | |
856 | + static R Wrapper(const void* o, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) | |
857 | + { | |
858 | + const T* obj = static_cast<const T*>(o); | |
859 | + return (obj->*Func)(a1, a2, a3, a4, a5); | |
860 | + } | |
861 | + | |
862 | +public: | |
863 | + template<R (T::*Func)(P1, P2, P3, P4, P5) const> | |
864 | + inline static Callback<R (P1, P2, P3, P4, P5)> Bind(const T* o) | |
865 | + { | |
866 | + return Callback<R (P1, P2, P3, P4, P5)> | |
867 | + (&ConstMemberCallbackFactory5::Wrapper<Func>, | |
868 | + static_cast<const void*>(o)); | |
869 | + } | |
870 | +}; | |
871 | + | |
872 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
873 | + typename P4, typename P5> | |
874 | +inline ConstMemberCallbackFactory5<R, T, P1, P2, P3, P4, P5> | |
875 | +GetCallbackFactory(R (T::*)(P1, P2, P3, P4, P5) const) | |
876 | +{ | |
877 | + return ConstMemberCallbackFactory5<R, T, P1, P2, P3, P4, P5>(); | |
878 | +} | |
879 | + | |
880 | +// 6 parameter version | |
881 | + | |
882 | +template<typename R, typename P1, typename P2, typename P3, | |
883 | + typename P4, typename P5, typename P6> | |
884 | +class Callback<R (P1, P2, P3, P4, P5, P6)> | |
885 | +{ | |
886 | +public: | |
887 | + static const int Arity = 6; | |
888 | + typedef R ReturnType; | |
889 | + typedef P1 Param1Type; | |
890 | + typedef P2 Param2Type; | |
891 | + typedef P3 Param3Type; | |
892 | + typedef P4 Param4Type; | |
893 | + typedef P5 Param5Type; | |
894 | + typedef P6 Param6Type; | |
895 | + | |
896 | + Callback() : func(0), obj(0) {} | |
897 | + Callback(NullCallback) : func(0), obj(0) {} | |
898 | + Callback(const Callback& rhs) : func(rhs.func), obj(rhs.obj) {} | |
899 | + ~Callback() {} | |
900 | + | |
901 | + Callback& operator=(NullCallback) | |
902 | + { obj = 0; func = 0; return *this; } | |
903 | + Callback& operator=(const Callback& rhs) | |
904 | + { obj = rhs.obj; func = rhs.func; return *this; } | |
905 | + | |
906 | + inline R operator()(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) const | |
907 | + { | |
908 | + return (*func)(obj, a1, a2, a3, a4, a5, a6); | |
909 | + } | |
910 | + | |
911 | +private: | |
912 | + typedef const void* Callback::*SafeBoolType; | |
913 | +public: | |
914 | + inline operator SafeBoolType() const | |
915 | + { return func != 0 ? &Callback::obj : 0; } | |
916 | + inline bool operator!() const | |
917 | + { return func == 0; } | |
918 | + | |
919 | +private: | |
920 | + typedef R (*FuncType)(const void*, P1, P2, P3, P4, P5, P6); | |
921 | + Callback(FuncType f, const void* o) : func(f), obj(o) {} | |
922 | + | |
923 | +private: | |
924 | + FuncType func; | |
925 | + const void* obj; | |
926 | + | |
927 | + template<typename FR, typename FP1, typename FP2, typename FP3, | |
928 | + typename FP4, typename FP5, typename FP6> | |
929 | + friend class FreeCallbackFactory6; | |
930 | + template<typename FR, class FT, typename FP1, typename FP2, typename FP3, | |
931 | + typename FP4, typename FP5, typename FP6> | |
932 | + friend class MemberCallbackFactory6; | |
933 | + template<typename FR, class FT, typename FP1, typename FP2, typename FP3, | |
934 | + typename FP4, typename FP5, typename FP6> | |
935 | + friend class ConstMemberCallbackFactory6; | |
936 | +}; | |
937 | + | |
938 | +template<typename R, typename P1, typename P2, typename P3, | |
939 | + typename P4, typename P5, typename P6> | |
940 | +void operator==(const Callback<R (P1, P2, P3, P4, P5, P6)>&, | |
941 | + const Callback<R (P1, P2, P3, P4, P5, P6)>&); | |
942 | +template<typename R, typename P1, typename P2, typename P3, | |
943 | + typename P4, typename P5, typename P6> | |
944 | +void operator!=(const Callback<R (P1, P2, P3, P4, P5, P6)>&, | |
945 | + const Callback<R (P1, P2, P3, P4, P5, P6)>&); | |
946 | + | |
947 | +template<typename R, typename P1, typename P2, typename P3, | |
948 | + typename P4, typename P5, typename P6> | |
949 | +class FreeCallbackFactory6 | |
950 | +{ | |
951 | +private: | |
952 | + template<R (*Func)(P1, P2, P3, P4, P5, P6)> | |
953 | + static R Wrapper(const void*, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) | |
954 | + { | |
955 | + return (*Func)(a1, a2, a3, a4, a5, a6); | |
956 | + } | |
957 | + | |
958 | +public: | |
959 | + template<R (*Func)(P1, P2, P3, P4, P5, P6)> | |
960 | + inline static Callback<R (P1, P2, P3, P4, P5, P6)> Bind() | |
961 | + { | |
962 | + return Callback<R (P1, P2, P3, P4, P5, P6)> | |
963 | + (&FreeCallbackFactory6::Wrapper<Func>, 0); | |
964 | + } | |
965 | +}; | |
966 | + | |
967 | +template<typename R, typename P1, typename P2, typename P3, | |
968 | + typename P4, typename P5, typename P6> | |
969 | +inline FreeCallbackFactory6<R, P1, P2, P3, P4, P5, P6> | |
970 | +GetCallbackFactory(R (*)(P1, P2, P3, P4, P5, P6)) | |
971 | +{ | |
972 | + return FreeCallbackFactory6<R, P1, P2, P3, P4, P5, P6>(); | |
973 | +} | |
974 | + | |
975 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
976 | + typename P4, typename P5, typename P6> | |
977 | +class MemberCallbackFactory6 | |
978 | +{ | |
979 | +private: | |
980 | + template<R (T::*Func)(P1, P2, P3, P4, P5, P6)> | |
981 | + static R Wrapper(const void* o, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) | |
982 | + { | |
983 | + T* obj = const_cast<T*>(static_cast<const T*>(o)); | |
984 | + return (obj->*Func)(a1, a2, a3, a4, a5, a6); | |
985 | + } | |
986 | + | |
987 | +public: | |
988 | + template<R (T::*Func)(P1, P2, P3, P4, P5, P6)> | |
989 | + inline static Callback<R (P1, P2, P3, P4, P5, P6)> Bind(T* o) | |
990 | + { | |
991 | + return Callback<R (P1, P2, P3, P4, P5, P6)> | |
992 | + (&MemberCallbackFactory6::Wrapper<Func>, | |
993 | + static_cast<const void*>(o)); | |
994 | + } | |
995 | +}; | |
996 | + | |
997 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
998 | + typename P4, typename P5, typename P6> | |
999 | +inline MemberCallbackFactory6<R, T, P1, P2, P3, P4, P5, P6> | |
1000 | +GetCallbackFactory(R (T::*)(P1, P2, P3, P4, P5, P6)) | |
1001 | +{ | |
1002 | + return MemberCallbackFactory6<R, T, P1, P2, P3, P4, P5, P6>(); | |
1003 | +} | |
1004 | + | |
1005 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
1006 | + typename P4, typename P5, typename P6> | |
1007 | +class ConstMemberCallbackFactory6 | |
1008 | +{ | |
1009 | +private: | |
1010 | + template<R (T::*Func)(P1, P2, P3, P4, P5, P6) const> | |
1011 | + static R Wrapper(const void* o, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) | |
1012 | + { | |
1013 | + const T* obj = static_cast<const T*>(o); | |
1014 | + return (obj->*Func)(a1, a2, a3, a4, a5, a6); | |
1015 | + } | |
1016 | + | |
1017 | +public: | |
1018 | + template<R (T::*Func)(P1, P2, P3, P4, P5, P6) const> | |
1019 | + inline static Callback<R (P1, P2, P3, P4, P5, P6)> Bind(const T* o) | |
1020 | + { | |
1021 | + return Callback<R (P1, P2, P3, P4, P5, P6)> | |
1022 | + (&ConstMemberCallbackFactory6::Wrapper<Func>, | |
1023 | + static_cast<const void*>(o)); | |
1024 | + } | |
1025 | +}; | |
1026 | + | |
1027 | +template<typename R, class T, typename P1, typename P2, typename P3, | |
1028 | + typename P4, typename P5, typename P6> | |
1029 | +inline ConstMemberCallbackFactory6<R, T, P1, P2, P3, P4, P5, P6> | |
1030 | +GetCallbackFactory(R (T::*)(P1, P2, P3, P4, P5, P6) const) | |
1031 | +{ | |
1032 | + return ConstMemberCallbackFactory6<R, T, P1, P2, P3, P4, P5, P6>(); | |
1033 | +} | |
1034 | + | |
1035 | +} | |
1036 | + | |
1037 | +#endif | |
1038 | + |
@@ -0,0 +1,46 @@ | ||
1 | +#pragma once | |
2 | + | |
3 | +#include "arrayutil.h" | |
4 | + | |
5 | +template <typename T> | |
6 | +class varray | |
7 | +{ | |
8 | +public: | |
9 | + varray() | |
10 | + : | |
11 | + buff_(0), | |
12 | + maxLength_(0), | |
13 | + length_(0) | |
14 | + { | |
15 | + } | |
16 | + | |
17 | + varray(T* buff, size_t maxLength) | |
18 | + : | |
19 | + buff_(buff), | |
20 | + maxLength_(maxLength), | |
21 | + length_(0) | |
22 | + { | |
23 | + } | |
24 | + | |
25 | + T* buff_; | |
26 | + size_t maxLength_; | |
27 | + size_t length_; | |
28 | + | |
29 | + T& operator[] (int i) { return buff_[i]; } | |
30 | + const T& operator[] (int i) const { return buff_[i]; } | |
31 | + | |
32 | + void push_back(const T& val) | |
33 | + { | |
34 | + assert(length_ < maxLength_); | |
35 | + buff_[length_] = val; | |
36 | + ++length_; | |
37 | + } | |
38 | + | |
39 | +}; | |
40 | + | |
41 | +template <typename T, size_t N> | |
42 | +varray<T> varray_build( T (&arr)[N] ) | |
43 | +{ | |
44 | + return varray<T>(arr, N); | |
45 | +} | |
46 | + |
@@ -11,9 +11,35 @@ | ||
11 | 11 | #include "mg/button.h" |
12 | 12 | |
13 | 13 | #include "winutil.h" |
14 | +#include "arrayutil.h" | |
14 | 15 | #include "ReadImage/File.h" |
15 | 16 | #include "ReadImage/ReadImage.h" |
16 | 17 | |
18 | +namespace MG { | |
19 | + | |
20 | +struct BasicBG : public Element::IBackground | |
21 | +{ | |
22 | +public: | |
23 | + optional<Color> color; | |
24 | + Image image; | |
25 | + bool repeatX; | |
26 | + bool repeatY; | |
27 | + | |
28 | + virtual void Draw(const Rectangle& rect, IRenderer& renderer) | |
29 | + { | |
30 | + if (color) { | |
31 | + Color c = *color; | |
32 | + renderer.FillRectangle(rect, c); | |
33 | + } | |
34 | + if (image.pBitmap) { | |
35 | + const Bitmap& bmp = *image.pBitmap; | |
36 | + renderer.DrawBitmap(bmp, image.GetRect(), rect); | |
37 | + } | |
38 | + } | |
39 | +}; | |
40 | + | |
41 | +} // namespace MG | |
42 | + | |
17 | 43 | namespace { |
18 | 44 | |
19 | 45 | HWND hWnd; |
@@ -24,11 +50,12 @@ void* pBits; | ||
24 | 50 | HDC hMemDC; |
25 | 51 | |
26 | 52 | MG::Renderer24 renderer; |
27 | -MG::Element* elements[128]; | |
28 | 53 | |
29 | -MG::Container mg(elements, 128); | |
30 | -MG::Button button1; | |
31 | -MG::Button button2; | |
54 | +MG::Container mg(4, 8); | |
55 | +MG::Button button1(0); | |
56 | +MG::Button button2(0); | |
57 | +MG::Element pic1(0); | |
58 | +MG::Element pic2(0); | |
32 | 59 | |
33 | 60 | MG::Bitmap bmp24Content; |
34 | 61 | std::vector<uint8_t> image24Buffer; |
@@ -36,8 +63,11 @@ std::vector<uint8_t> image24Buffer; | ||
36 | 63 | MG::Bitmap bmp32Content; |
37 | 64 | std::vector<uint8_t> image32Buffer; |
38 | 65 | |
39 | -MG::Element pic1; | |
40 | -MG::Element pic2; | |
66 | +MG::BasicBG mainbg; | |
67 | +MG::BasicBG buttonBG; | |
68 | +MG::BasicBG buttonBGPressed; | |
69 | +MG::BasicBG picbg1; | |
70 | +MG::BasicBG picbg2; | |
41 | 71 | |
42 | 72 | bool ReadImage(const char* filename, MG::Bitmap& bmp, std::vector<uint8_t>& buffer) |
43 | 73 | { |
@@ -91,7 +121,7 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) | ||
91 | 121 | bmp.pBits = pBits; |
92 | 122 | bmp.lineOffsetBytes = width * 3; |
93 | 123 | renderer.SetBitmap(bmp); |
94 | - | |
124 | + | |
95 | 125 | MG::Rectangle rect; |
96 | 126 | rect.x = 0; |
97 | 127 | rect.y = 0; |
@@ -102,22 +132,33 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) | ||
102 | 132 | col.r = 50; |
103 | 133 | col.g = 200; |
104 | 134 | col.b = 150; |
105 | - mg.bg.color = col; | |
135 | + | |
136 | + mainbg.color = col; | |
137 | + mg.pBG = &mainbg; | |
106 | 138 | mg.needsToDraw = true; |
107 | 139 | |
140 | + col.g = 100; | |
141 | + buttonBG.color = col; | |
142 | + col.r = 200; | |
143 | + buttonBGPressed.color = col; | |
144 | + | |
108 | 145 | rect.x = 100; |
109 | 146 | rect.y = 100; |
110 | 147 | rect.w = 100; |
111 | 148 | rect.h = 50; |
112 | 149 | button1.rect = rect; |
113 | - mg.Add(button1); | |
150 | + button1.pBG = &buttonBG; | |
151 | + button1.pBGPressed = &buttonBGPressed; | |
152 | + mg.AddChild(button1); | |
114 | 153 | |
115 | 154 | rect.x = 300; |
116 | 155 | rect.y = 100; |
117 | 156 | rect.w = 100; |
118 | 157 | rect.h = 50; |
119 | 158 | button2.rect = rect; |
120 | - mg.Add(button2); | |
159 | + button2.pBG = &buttonBG; | |
160 | + button2.pBGPressed = &buttonBGPressed; | |
161 | + mg.AddChild(button2); | |
121 | 162 | |
122 | 163 | if (!ReadImage("test24.bmp", bmp24Content, image24Buffer)) { |
123 | 164 | return; |
@@ -134,10 +175,11 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) | ||
134 | 175 | irec.y = 340; |
135 | 176 | irec.w = 400; |
136 | 177 | irec.h = 400; |
137 | - pic1.bg.image.rect = irec; | |
138 | - pic1.bg.image.pBitmap = &bmp24Content; | |
178 | + picbg1.image.rect = irec; | |
179 | + picbg1.image.pBitmap = &bmp24Content; | |
180 | + pic1.pBG = &picbg1; | |
139 | 181 | pic1.needsToDraw = true; |
140 | - mg.Add(pic1); | |
182 | + mg.AddChild(pic1); | |
141 | 183 | |
142 | 184 | rect.x = 300; |
143 | 185 | rect.y = 200; |
@@ -148,10 +190,11 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) | ||
148 | 190 | irec.y = 0; |
149 | 191 | irec.w = 336; |
150 | 192 | irec.h = 24; |
151 | - pic2.bg.image.rect = irec; | |
152 | - pic2.bg.image.pBitmap = &bmp32Content; | |
193 | + picbg2.image.rect = irec; | |
194 | + picbg2.image.pBitmap = &bmp32Content; | |
195 | + pic2.pBG = &picbg2; | |
153 | 196 | pic2.needsToDraw = true; |
154 | - mg.Add(pic2); | |
197 | + mg.AddChild(pic2); | |
155 | 198 | |
156 | 199 | HDC hWndDC = ::GetDC(hWnd); |
157 | 200 | hMemDC = ::CreateCompatibleDC(hWndDC); |
@@ -313,6 +313,10 @@ | ||
313 | 313 | > |
314 | 314 | </File> |
315 | 315 | <File |
316 | + RelativePath=".\common\callback.hpp" | |
317 | + > | |
318 | + </File> | |
319 | + <File | |
316 | 320 | RelativePath=".\common\optional.h" |
317 | 321 | > |
318 | 322 | </File> |
@@ -321,6 +325,10 @@ | ||
321 | 325 | > |
322 | 326 | </File> |
323 | 327 | <File |
328 | + RelativePath=".\common\varray.h" | |
329 | + > | |
330 | + </File> | |
331 | + <File | |
324 | 332 | RelativePath=".\common\winutil.cpp" |
325 | 333 | > |
326 | 334 | </File> |
@@ -15,11 +15,19 @@ struct Bitmap | ||
15 | 15 | Rectangle GetRect() const; |
16 | 16 | }; |
17 | 17 | |
18 | -struct Image { | |
18 | +struct Image | |
19 | +{ | |
20 | + Image() | |
21 | + : | |
22 | + pBitmap(0) | |
23 | + { | |
24 | + } | |
25 | + | |
19 | 26 | Bitmap* pBitmap; |
20 | 27 | Rectangle rect; |
21 | 28 | |
22 | - Rectangle GetRect() const { | |
29 | + Rectangle GetRect() const | |
30 | + { | |
23 | 31 | if (pBitmap) { |
24 | 32 | return Rectangle::Intersect(pBitmap->GetRect(), rect); |
25 | 33 | }else { |
@@ -4,7 +4,10 @@ | ||
4 | 4 | |
5 | 5 | namespace MG { |
6 | 6 | |
7 | -Button::Button() | |
7 | +Button::Button(size_t nMaxEvents) | |
8 | + : | |
9 | + Element(nMaxEvents), | |
10 | + pBGPressed(0) | |
8 | 11 | { |
9 | 12 | needsToDraw = true; |
10 | 13 | bClickable_ = true; |
@@ -12,11 +15,14 @@ Button::Button() | ||
12 | 15 | |
13 | 16 | void Button::Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer) |
14 | 17 | { |
15 | - Color c; | |
16 | - c.r = c.g = c.b = c.a = (isPressed_ ? 0xcf : 0x55); | |
17 | - bg.color = c; | |
18 | - | |
19 | - __super::Draw(offsetX, offsetY, renderer); | |
18 | + if (isPressed_) { | |
19 | + IBackground* backup = pBG; | |
20 | + pBG = pBGPressed; | |
21 | + __super::Draw(offsetX, offsetY, renderer); | |
22 | + pBG = backup; | |
23 | + }else { | |
24 | + __super::Draw(offsetX, offsetY, renderer); | |
25 | + } | |
20 | 26 | } |
21 | 27 | |
22 | 28 | bool Button::HitTest(int16_t x, int16_t y) const |
@@ -40,6 +46,7 @@ void Button::OnMouseUp(int16_t x, int16_t y) | ||
40 | 46 | |
41 | 47 | void Button::OnMouseMove(int16_t x, int16_t y) |
42 | 48 | { |
49 | + ; | |
43 | 50 | } |
44 | 51 | |
45 | 52 | } // anonymous MG |
@@ -10,7 +10,7 @@ class Button | ||
10 | 10 | public Element |
11 | 11 | { |
12 | 12 | public: |
13 | - Button(); | |
13 | + Button(size_t nMaxEvents); | |
14 | 14 | |
15 | 15 | void Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer); |
16 | 16 | bool HitTest(int16_t x, int16_t y) const; |
@@ -18,7 +18,15 @@ public: | ||
18 | 18 | void OnMouseUp(int16_t x, int16_t y); |
19 | 19 | void OnMouseMove(int16_t x, int16_t y); |
20 | 20 | |
21 | -private: | |
21 | + IBackground* pBGPressed; | |
22 | + | |
23 | + enum EventType { | |
24 | + EventType_Clicked = __super::EventType_End, | |
25 | + | |
26 | + EventType_End, | |
27 | + }; | |
28 | + | |
29 | +protected: | |
22 | 30 | bool isPressed_; |
23 | 31 | |
24 | 32 | }; |
@@ -2,33 +2,42 @@ | ||
2 | 2 | |
3 | 3 | #include "container.h" |
4 | 4 | |
5 | +namespace { | |
6 | + | |
7 | +size_t s_nElementEntries; | |
8 | +MG::Element* s_elementPtrs[128]; | |
9 | + | |
10 | +} // anonymous namespace | |
11 | + | |
5 | 12 | namespace MG { |
6 | 13 | |
7 | -Container::Container(Element** buff, size_t maxLength) | |
14 | +Container::Container(size_t nMaxEvents, size_t nMaxChildren) | |
8 | 15 | : |
9 | - buff_(buff), | |
10 | - maxLength_(maxLength), | |
11 | - length_(0) | |
16 | + Element(nMaxEvents), | |
17 | + clickedElementIndex_(0) | |
12 | 18 | { |
19 | + vElements_.buff_ = &s_elementPtrs[s_nElementEntries]; | |
20 | + vElements_.maxLength_ = nMaxChildren; | |
21 | + s_nElementEntries += nMaxChildren; | |
22 | + assert(s_nElementEntries < countof(s_elementPtrs)); | |
13 | 23 | } |
14 | 24 | |
15 | 25 | Container::~Container() |
16 | 26 | { |
17 | 27 | } |
18 | 28 | |
19 | -void Container::Add(Element& e) | |
29 | +void Container::AddChild(Element& e) | |
20 | 30 | { |
21 | - assert(length_ < maxLength_); | |
22 | - buff_[length_] = &e; | |
23 | - ++length_; | |
31 | + vElements_.push_back(&e); | |
32 | + e.SetParent(this); | |
24 | 33 | } |
25 | 34 | |
26 | -void Container::Remove(Element& e) | |
35 | +void Container::RemoveChild(Element& e) | |
27 | 36 | { |
28 | - const Element* ptr = &e; | |
29 | - for (size_t i=0; i<length_; ++i) { | |
30 | - if (buff_[i] == ptr) { | |
31 | - buff_[i] = NULL; | |
37 | + for (size_t i=0; i<vElements_.length_; ++i) { | |
38 | + if (vElements_[i] == &e) { | |
39 | + vElements_[i] = 0; | |
40 | + e.SetParent(0); | |
32 | 41 | break; |
33 | 42 | } |
34 | 43 | } |
@@ -43,8 +52,8 @@ void Container::Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer) | ||
43 | 52 | |
44 | 53 | int16_t x = rect.x + offsetX; |
45 | 54 | int16_t y = rect.y + offsetY; |
46 | - for (size_t i=0; i<length_; ++i) { | |
47 | - Element* e = buff_[i]; | |
55 | + for (size_t i=0; i<vElements_.length_; ++i) { | |
56 | + Element* e = vElements_[i]; | |
48 | 57 | if (e && e->needsToDraw) { |
49 | 58 | e->Draw(x, y, renderer); |
50 | 59 | e->needsToDraw = false; |
@@ -61,8 +70,8 @@ void Container::OnMouseDown(int16_t x, int16_t y) | ||
61 | 70 | { |
62 | 71 | int16_t ox = x - rect.x; |
63 | 72 | int16_t oy = y - rect.y; |
64 | - for (size_t i=0; i<length_; ++i) { | |
65 | - Element* e = buff_[i]; | |
73 | + for (size_t i=0; i<vElements_.length_; ++i) { | |
74 | + Element* e = vElements_[i]; | |
66 | 75 | if (e) { |
67 | 76 | if (1 |
68 | 77 | && e->IsClickable() |
@@ -81,23 +90,22 @@ void Container::OnMouseUp(int16_t x, int16_t y) | ||
81 | 90 | { |
82 | 91 | int16_t ox = x - rect.x; |
83 | 92 | int16_t oy = y - rect.y; |
84 | - Element* e = buff_[clickedElementIndex_]; | |
85 | - assert(e); | |
86 | - e->OnMouseUp(ox, oy); | |
93 | + Element* e = vElements_[clickedElementIndex_]; | |
94 | + if (e) { | |
95 | + e->OnMouseUp(ox, oy); | |
96 | + } | |
87 | 97 | } |
88 | 98 | |
89 | 99 | void Container::OnMouseMove(int16_t x, int16_t y) |
90 | 100 | { |
91 | 101 | int16_t ox = x - rect.x; |
92 | 102 | int16_t oy = y - rect.y; |
93 | - Element* e = buff_[clickedElementIndex_]; | |
94 | - assert(e); | |
95 | - e->OnMouseMove(ox, oy); | |
103 | + Element* e = vElements_[clickedElementIndex_]; | |
104 | + if (e) { | |
105 | + e->OnMouseMove(ox, oy); | |
106 | + } | |
96 | 107 | } |
97 | 108 | |
98 | 109 | |
99 | 110 | } // namespace MG |
100 | 111 | |
101 | - | |
102 | - | |
103 | - |
@@ -1,17 +1,20 @@ | ||
1 | 1 | #pragma once |
2 | 2 | |
3 | 3 | #include "element.h" |
4 | +#include "varray.h" | |
4 | 5 | |
5 | 6 | namespace MG { |
6 | 7 | |
7 | -class Container : public Element | |
8 | +class Container | |
9 | + : | |
10 | + public Element | |
8 | 11 | { |
9 | 12 | public: |
10 | - Container(Element** buff, size_t maxLength); | |
13 | + Container(size_t nMaxEvents, size_t nMaxChildren); | |
11 | 14 | virtual ~Container(); |
12 | 15 | |
13 | - void Add(Element& e); | |
14 | - void Remove(Element& e); | |
16 | + void AddChild(Element& e); | |
17 | + void RemoveChild(Element& e); | |
15 | 18 | |
16 | 19 | virtual void Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer); |
17 | 20 | virtual bool HitTest(int16_t x, int16_t y) const; |
@@ -19,11 +22,10 @@ public: | ||
19 | 22 | virtual void OnMouseUp(int16_t x, int16_t y); |
20 | 23 | virtual void OnMouseMove(int16_t x, int16_t y); |
21 | 24 | |
22 | -private: | |
23 | - Element** buff_; | |
24 | - size_t maxLength_; | |
25 | - size_t length_; | |
25 | +protected: | |
26 | 26 | size_t clickedElementIndex_; |
27 | + varray<Element*> vElements_; | |
28 | + | |
27 | 29 | }; |
28 | 30 | |
29 | 31 | } // namespace MG |
@@ -1,9 +1,30 @@ | ||
1 | 1 | #include "stdafx.h" |
2 | 2 | |
3 | 3 | #include "element.h" |
4 | +#include "arrayutil.h" | |
5 | + | |
6 | +namespace { | |
7 | + | |
8 | +size_t s_nEventEntries; | |
9 | +MG::Element::EventListenerEntry s_eventEntries[128]; | |
10 | + | |
11 | +} // anonymous namespace | |
4 | 12 | |
5 | 13 | namespace MG { |
6 | 14 | |
15 | +Element::Element(size_t nMaxEvents) | |
16 | +{ | |
17 | + eventEntries_.buff_ = &s_eventEntries[s_nEventEntries]; | |
18 | + eventEntries_.maxLength_ = nMaxEvents; | |
19 | + s_nEventEntries += nMaxEvents; | |
20 | + assert(s_nEventEntries < countof(s_eventEntries)); | |
21 | + | |
22 | + pParent_ = 0; | |
23 | + needsToDraw = false; | |
24 | + pBG = 0; | |
25 | + bClickable_ = false; | |
26 | +} | |
27 | + | |
7 | 28 | // virtual |
8 | 29 | void Element::Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer) |
9 | 30 | { |
@@ -11,15 +32,9 @@ void Element::Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer) | ||
11 | 32 | r.x += offsetX; |
12 | 33 | r.y += offsetY; |
13 | 34 | |
14 | - if (bg.color) { | |
15 | - Color c = *bg.color; | |
16 | - renderer.FillRectangle(r, c); | |
35 | + if (pBG) { | |
36 | + pBG->Draw(r, renderer); | |
17 | 37 | } |
18 | - if (bg.image.pBitmap) { | |
19 | - const Bitmap& bmp = *bg.image.pBitmap; | |
20 | - renderer.DrawBitmap(bmp, bg.image.GetRect(), r); | |
21 | - } | |
22 | - | |
23 | 38 | } |
24 | 39 | |
25 | 40 |
@@ -2,24 +2,18 @@ | ||
2 | 2 | |
3 | 3 | #include "renderer.h" |
4 | 4 | #include "optional.h" |
5 | +#include "callback.hpp" | |
6 | +#include "varray.h" | |
5 | 7 | |
6 | 8 | namespace MG { |
7 | 9 | |
8 | 10 | class Element |
9 | 11 | { |
10 | 12 | public: |
11 | - Element() | |
12 | - : | |
13 | - needsToDraw(false), | |
14 | - bClickable_(false) | |
15 | - { | |
16 | - bg.repeatX = true; | |
17 | - bg.repeatY = true; | |
18 | - } | |
13 | + typedef uint8_t id_t; | |
19 | 14 | |
20 | - virtual ~Element() | |
21 | - { | |
22 | - } | |
15 | + Element(size_t nMaxEvents); | |
16 | + virtual ~Element() {} | |
23 | 17 | |
24 | 18 | bool IsClickable() const { |
25 | 19 | return bClickable_; |
@@ -31,17 +25,45 @@ public: | ||
31 | 25 | virtual void OnMouseUp(int16_t x, int16_t y) {} |
32 | 26 | virtual void OnMouseMove(int16_t x, int16_t y) {} |
33 | 27 | |
34 | - Rectangle rect; | |
28 | + Rectangle rect; // positioning, size | |
35 | 29 | bool needsToDraw; |
36 | 30 | |
37 | - struct Background { | |
38 | - optional<Color> color; | |
39 | - Image image; | |
40 | - bool repeatX; | |
41 | - bool repeatY; | |
42 | - } bg; | |
31 | + struct IBackground { | |
32 | + virtual void Draw(const Rectangle& rect, IRenderer& renderer) = 0; | |
33 | + }; | |
34 | + IBackground* pBG; | |
35 | + | |
36 | + Element* GetParent() const { return pParent_; } | |
37 | + void SetParent(Element* pParent) { pParent_ = pParent; } | |
38 | + | |
39 | + // event | |
40 | + enum EventType { | |
41 | + EventType_MouseDown, | |
42 | + EventType_MouseUp, | |
43 | + EventType_MouseMove, | |
44 | + | |
45 | + EventType_End, | |
46 | + }; | |
47 | + struct Event | |
48 | + { | |
49 | + Element* target; | |
50 | + uint8_t type; | |
51 | + int16_t x; | |
52 | + int16_t y; | |
53 | + }; | |
54 | + typedef util::Callback<void (const Event&)> EventListener; | |
55 | + struct EventListenerEntry { | |
56 | + int type; | |
57 | + EventListener listener; | |
58 | + }; | |
59 | + void AddEventListener(int type, const EventListener& listener); | |
60 | + void RemoveEventListener(int type, const EventListener& listener); | |
61 | + | |
43 | 62 | protected: |
44 | 63 | bool bClickable_; |
64 | + Element* pParent_; | |
65 | + | |
66 | + varray<EventListenerEntry> eventEntries_; | |
45 | 67 | }; |
46 | 68 | |
47 | 69 | } // namespace MG |
@@ -0,0 +1,29 @@ | ||
1 | +#pragma once | |
2 | + | |
3 | +#include "button.h" | |
4 | + | |
5 | +namespace MG { | |
6 | + | |
7 | +class RadioButton | |
8 | + : | |
9 | + public Button | |
10 | +{ | |
11 | +public: | |
12 | + RadioButton(); | |
13 | + | |
14 | + void Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer); | |
15 | + bool HitTest(int16_t x, int16_t y) const; | |
16 | + void OnMouseDown(int16_t x, int16_t y); | |
17 | + void OnMouseUp(int16_t x, int16_t y); | |
18 | + void OnMouseMove(int16_t x, int16_t y); | |
19 | + | |
20 | + uint8_t groupID; | |
21 | +protected: | |
22 | + bool isSelected_; | |
23 | + | |
24 | +}; | |
25 | + | |
26 | +} // anonymous MG | |
27 | + | |
28 | + | |
29 | + |