• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#objective-cqt誰得cocoawindowspythonrubyphpgameguibathyscaphec翻訳omegat計画中(planning stage)frameworktwittertestdombtronvb.netdirectxarduinopreviewerゲームエンジン

milligram


Commit MetaInfo

Révisiondf726866632f095971b477ee8f068558dca82726 (tree)
l'heure2011-03-24 17:11:53
Auteurberu <berupon@gmai...>
Commiterberu

Message de Log

bkup

Change Summary

Modification

--- /dev/null
+++ b/common/callback.hpp
@@ -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+
--- /dev/null
+++ b/common/varray.h
@@ -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+
--- a/main_plus.cpp
+++ b/main_plus.cpp
@@ -11,9 +11,35 @@
1111 #include "mg/button.h"
1212
1313 #include "winutil.h"
14+#include "arrayutil.h"
1415 #include "ReadImage/File.h"
1516 #include "ReadImage/ReadImage.h"
1617
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+
1743 namespace {
1844
1945 HWND hWnd;
@@ -24,11 +50,12 @@ void* pBits;
2450 HDC hMemDC;
2551
2652 MG::Renderer24 renderer;
27-MG::Element* elements[128];
2853
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);
3259
3360 MG::Bitmap bmp24Content;
3461 std::vector<uint8_t> image24Buffer;
@@ -36,8 +63,11 @@ std::vector<uint8_t> image24Buffer;
3663 MG::Bitmap bmp32Content;
3764 std::vector<uint8_t> image32Buffer;
3865
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;
4171
4272 bool ReadImage(const char* filename, MG::Bitmap& bmp, std::vector<uint8_t>& buffer)
4373 {
@@ -91,7 +121,7 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
91121 bmp.pBits = pBits;
92122 bmp.lineOffsetBytes = width * 3;
93123 renderer.SetBitmap(bmp);
94-
124+
95125 MG::Rectangle rect;
96126 rect.x = 0;
97127 rect.y = 0;
@@ -102,22 +132,33 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
102132 col.r = 50;
103133 col.g = 200;
104134 col.b = 150;
105- mg.bg.color = col;
135+
136+ mainbg.color = col;
137+ mg.pBG = &mainbg;
106138 mg.needsToDraw = true;
107139
140+ col.g = 100;
141+ buttonBG.color = col;
142+ col.r = 200;
143+ buttonBGPressed.color = col;
144+
108145 rect.x = 100;
109146 rect.y = 100;
110147 rect.w = 100;
111148 rect.h = 50;
112149 button1.rect = rect;
113- mg.Add(button1);
150+ button1.pBG = &buttonBG;
151+ button1.pBGPressed = &buttonBGPressed;
152+ mg.AddChild(button1);
114153
115154 rect.x = 300;
116155 rect.y = 100;
117156 rect.w = 100;
118157 rect.h = 50;
119158 button2.rect = rect;
120- mg.Add(button2);
159+ button2.pBG = &buttonBG;
160+ button2.pBGPressed = &buttonBGPressed;
161+ mg.AddChild(button2);
121162
122163 if (!ReadImage("test24.bmp", bmp24Content, image24Buffer)) {
123164 return;
@@ -134,10 +175,11 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
134175 irec.y = 340;
135176 irec.w = 400;
136177 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;
139181 pic1.needsToDraw = true;
140- mg.Add(pic1);
182+ mg.AddChild(pic1);
141183
142184 rect.x = 300;
143185 rect.y = 200;
@@ -148,10 +190,11 @@ void OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
148190 irec.y = 0;
149191 irec.w = 336;
150192 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;
153196 pic2.needsToDraw = true;
154- mg.Add(pic2);
197+ mg.AddChild(pic2);
155198
156199 HDC hWndDC = ::GetDC(hWnd);
157200 hMemDC = ::CreateCompatibleDC(hWndDC);
--- a/mg.vcproj
+++ b/mg.vcproj
@@ -313,6 +313,10 @@
313313 >
314314 </File>
315315 <File
316+ RelativePath=".\common\callback.hpp"
317+ >
318+ </File>
319+ <File
316320 RelativePath=".\common\optional.h"
317321 >
318322 </File>
@@ -321,6 +325,10 @@
321325 >
322326 </File>
323327 <File
328+ RelativePath=".\common\varray.h"
329+ >
330+ </File>
331+ <File
324332 RelativePath=".\common\winutil.cpp"
325333 >
326334 </File>
--- a/mg/bitmap.h
+++ b/mg/bitmap.h
@@ -15,11 +15,19 @@ struct Bitmap
1515 Rectangle GetRect() const;
1616 };
1717
18-struct Image {
18+struct Image
19+{
20+ Image()
21+ :
22+ pBitmap(0)
23+ {
24+ }
25+
1926 Bitmap* pBitmap;
2027 Rectangle rect;
2128
22- Rectangle GetRect() const {
29+ Rectangle GetRect() const
30+ {
2331 if (pBitmap) {
2432 return Rectangle::Intersect(pBitmap->GetRect(), rect);
2533 }else {
--- a/mg/button.cpp
+++ b/mg/button.cpp
@@ -4,7 +4,10 @@
44
55 namespace MG {
66
7-Button::Button()
7+Button::Button(size_t nMaxEvents)
8+ :
9+ Element(nMaxEvents),
10+ pBGPressed(0)
811 {
912 needsToDraw = true;
1013 bClickable_ = true;
@@ -12,11 +15,14 @@ Button::Button()
1215
1316 void Button::Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer)
1417 {
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+ }
2026 }
2127
2228 bool Button::HitTest(int16_t x, int16_t y) const
@@ -40,6 +46,7 @@ void Button::OnMouseUp(int16_t x, int16_t y)
4046
4147 void Button::OnMouseMove(int16_t x, int16_t y)
4248 {
49+ ;
4350 }
4451
4552 } // anonymous MG
--- a/mg/button.h
+++ b/mg/button.h
@@ -10,7 +10,7 @@ class Button
1010 public Element
1111 {
1212 public:
13- Button();
13+ Button(size_t nMaxEvents);
1414
1515 void Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer);
1616 bool HitTest(int16_t x, int16_t y) const;
@@ -18,7 +18,15 @@ public:
1818 void OnMouseUp(int16_t x, int16_t y);
1919 void OnMouseMove(int16_t x, int16_t y);
2020
21-private:
21+ IBackground* pBGPressed;
22+
23+ enum EventType {
24+ EventType_Clicked = __super::EventType_End,
25+
26+ EventType_End,
27+ };
28+
29+protected:
2230 bool isPressed_;
2331
2432 };
--- a/mg/container.cpp
+++ b/mg/container.cpp
@@ -2,33 +2,42 @@
22
33 #include "container.h"
44
5+namespace {
6+
7+size_t s_nElementEntries;
8+MG::Element* s_elementPtrs[128];
9+
10+} // anonymous namespace
11+
512 namespace MG {
613
7-Container::Container(Element** buff, size_t maxLength)
14+Container::Container(size_t nMaxEvents, size_t nMaxChildren)
815 :
9- buff_(buff),
10- maxLength_(maxLength),
11- length_(0)
16+ Element(nMaxEvents),
17+ clickedElementIndex_(0)
1218 {
19+ vElements_.buff_ = &s_elementPtrs[s_nElementEntries];
20+ vElements_.maxLength_ = nMaxChildren;
21+ s_nElementEntries += nMaxChildren;
22+ assert(s_nElementEntries < countof(s_elementPtrs));
1323 }
1424
1525 Container::~Container()
1626 {
1727 }
1828
19-void Container::Add(Element& e)
29+void Container::AddChild(Element& e)
2030 {
21- assert(length_ < maxLength_);
22- buff_[length_] = &e;
23- ++length_;
31+ vElements_.push_back(&e);
32+ e.SetParent(this);
2433 }
2534
26-void Container::Remove(Element& e)
35+void Container::RemoveChild(Element& e)
2736 {
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);
3241 break;
3342 }
3443 }
@@ -43,8 +52,8 @@ void Container::Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer)
4352
4453 int16_t x = rect.x + offsetX;
4554 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];
4857 if (e && e->needsToDraw) {
4958 e->Draw(x, y, renderer);
5059 e->needsToDraw = false;
@@ -61,8 +70,8 @@ void Container::OnMouseDown(int16_t x, int16_t y)
6170 {
6271 int16_t ox = x - rect.x;
6372 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];
6675 if (e) {
6776 if (1
6877 && e->IsClickable()
@@ -81,23 +90,22 @@ void Container::OnMouseUp(int16_t x, int16_t y)
8190 {
8291 int16_t ox = x - rect.x;
8392 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+ }
8797 }
8898
8999 void Container::OnMouseMove(int16_t x, int16_t y)
90100 {
91101 int16_t ox = x - rect.x;
92102 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+ }
96107 }
97108
98109
99110 } // namespace MG
100111
101-
102-
103-
--- a/mg/container.h
+++ b/mg/container.h
@@ -1,17 +1,20 @@
11 #pragma once
22
33 #include "element.h"
4+#include "varray.h"
45
56 namespace MG {
67
7-class Container : public Element
8+class Container
9+ :
10+ public Element
811 {
912 public:
10- Container(Element** buff, size_t maxLength);
13+ Container(size_t nMaxEvents, size_t nMaxChildren);
1114 virtual ~Container();
1215
13- void Add(Element& e);
14- void Remove(Element& e);
16+ void AddChild(Element& e);
17+ void RemoveChild(Element& e);
1518
1619 virtual void Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer);
1720 virtual bool HitTest(int16_t x, int16_t y) const;
@@ -19,11 +22,10 @@ public:
1922 virtual void OnMouseUp(int16_t x, int16_t y);
2023 virtual void OnMouseMove(int16_t x, int16_t y);
2124
22-private:
23- Element** buff_;
24- size_t maxLength_;
25- size_t length_;
25+protected:
2626 size_t clickedElementIndex_;
27+ varray<Element*> vElements_;
28+
2729 };
2830
2931 } // namespace MG
--- a/mg/element.cpp
+++ b/mg/element.cpp
@@ -1,9 +1,30 @@
11 #include "stdafx.h"
22
33 #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
412
513 namespace MG {
614
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+
728 // virtual
829 void Element::Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer)
930 {
@@ -11,15 +32,9 @@ void Element::Draw(int16_t offsetX, int16_t offsetY, IRenderer& renderer)
1132 r.x += offsetX;
1233 r.y += offsetY;
1334
14- if (bg.color) {
15- Color c = *bg.color;
16- renderer.FillRectangle(r, c);
35+ if (pBG) {
36+ pBG->Draw(r, renderer);
1737 }
18- if (bg.image.pBitmap) {
19- const Bitmap& bmp = *bg.image.pBitmap;
20- renderer.DrawBitmap(bmp, bg.image.GetRect(), r);
21- }
22-
2338 }
2439
2540
--- a/mg/element.h
+++ b/mg/element.h
@@ -2,24 +2,18 @@
22
33 #include "renderer.h"
44 #include "optional.h"
5+#include "callback.hpp"
6+#include "varray.h"
57
68 namespace MG {
79
810 class Element
911 {
1012 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;
1914
20- virtual ~Element()
21- {
22- }
15+ Element(size_t nMaxEvents);
16+ virtual ~Element() {}
2317
2418 bool IsClickable() const {
2519 return bClickable_;
@@ -31,17 +25,45 @@ public:
3125 virtual void OnMouseUp(int16_t x, int16_t y) {}
3226 virtual void OnMouseMove(int16_t x, int16_t y) {}
3327
34- Rectangle rect;
28+ Rectangle rect; // positioning, size
3529 bool needsToDraw;
3630
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+
4362 protected:
4463 bool bClickable_;
64+ Element* pParent_;
65+
66+ varray<EventListenerEntry> eventEntries_;
4567 };
4668
4769 } // namespace MG
--- /dev/null
+++ b/mg/radioButton.h
@@ -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+