1 /*
2 	Copyright (C) 2005-2007 Feeling Software Inc.
3 	Portions of the code are:
4 	Copyright (C) 2005-2007 Sony Computer Entertainment America
5 
6 	MIT License: http://www.opensource.org/licenses/mit-license.php
7 */
8 
9 #include "StdAfx.h"
10 #include "FUTestBed.h"
11 #include "FUEvent.h"
12 
13 ///////////////////////////////////////////////////////////////////////////////
14 class FUTCaller
15 {
16 public:
17 	FUEvent0* event0;
18 	FUEvent2<long, long>* event2;
19 
FUTCaller()20 	FUTCaller()
21 	{
22 		event0 = new FUEvent0();
23 		event2 = new FUEvent2<long, long>();
24 	}
25 
~FUTCaller()26 	~FUTCaller()
27 	{
28 		SAFE_DELETE(event0);
29 		SAFE_DELETE(event2);
30 	}
31 };
32 
33 class FUTCallee
34 {
35 public:
36 	bool isCallback0_1Called;
37 	bool isCallback0_2Called;
38 	bool isCallback2Called;
39 
40 	long callback2Data1;
41 	long callback2Data2;
42 
FUTCallee()43 	FUTCallee()
44 	{
45 		isCallback0_1Called = false;
46 		isCallback0_2Called = false;
47 		isCallback2Called = false;
48 
49 		callback2Data1 = -1;
50 		callback2Data2 = -1;
51 	}
52 
Callback0_1()53 	void Callback0_1()
54 	{
55 		isCallback0_1Called = true;
56 	}
57 
Callback0_2()58 	void Callback0_2()
59 	{
60 		isCallback0_2Called = true;
61 	}
62 
Callback2(long data1,long data2)63 	void Callback2(long data1, long data2)
64 	{
65 		isCallback2Called = true;
66 		callback2Data1 = data1;
67 		callback2Data2 = data2;
68 	}
69 };
70 
71 class FUTDumbCaller
72 {
73 public:
74 	FUEvent0 event0;
75 	FUEvent1<FUTDumbCaller*> event1;
76 	FUEvent2<FUTDumbCaller*, long> event2;
77 };
78 
79 // Test release of event handlers while an event is happening.
80 class FUTAntisocialCallee
81 {
82 public:
83 	FUTDumbCaller* caller;
84 	bool c0, c1, c2;	// have the callbacks been called?
85 
FUTAntisocialCallee()86 	FUTAntisocialCallee()
87 	{
88 		caller = NULL;
89 		c0 = c1 = c2 = false;
90 	}
91 
Callback0()92 	void Callback0()
93 	{
94 		caller->event0.ReleaseHandler(this, &FUTAntisocialCallee::Callback0);
95 		c0 = true;
96 	}
97 
Callback1(FUTDumbCaller * caller2)98 	void Callback1(FUTDumbCaller* caller2)
99 	{
100 		caller2->event1.ReleaseHandler(this, &FUTAntisocialCallee::Callback1);
101 		c1 = true;
102 	}
103 
Callback2(FUTDumbCaller * caller2,long)104 	void Callback2(FUTDumbCaller* caller2, long /* data2 */)
105 	{
106 		caller2->event2.ReleaseHandler(this, &FUTAntisocialCallee::Callback2);
107 		c2 = true;
108 	}
109 
isSuccess()110 	bool isSuccess()
111 	{
112 		return c0 && c1 && c2;
113 	}
114 };
115 
116 
117 ///////////////////////////////////////////////////////////////////////////////
118 TESTSUITE_START(FUEvent)
119 
120 TESTSUITE_TEST(0, Callback0)
121 	FUTCaller caller;
122 	FUTCallee callee;
123 	FailIf(caller.event0->GetHandlerCount() != 0);
124 	caller.event0->InsertHandler(&callee, &FUTCallee::Callback0_1);
125 	FailIf(caller.event0->GetHandlerCount() != 1);
126 
127 	(*(caller.event0))();
128 
129 	FailIf(!callee.isCallback0_1Called);
130 	caller.event0->ReleaseHandler(&callee, &FUTCallee::Callback0_1);
131 
132 TESTSUITE_TEST(1, Callback2)
133 	FUTCaller caller;
134 	FUTCallee callee;
135 	caller.event2->InsertHandler(&callee, &FUTCallee::Callback2);
136 
137 	(*(caller.event2))(72, 55);
138 	FailIf(!callee.isCallback2Called);
139 	FailIf(callee.callback2Data1 != 72);
140 	FailIf(callee.callback2Data2 != 55);
141 
142 	callee.isCallback2Called = false;
143 	(*(caller.event2))(44, 79);
144 	FailIf(!callee.isCallback2Called);
145 	FailIf(callee.callback2Data1 != 44);
146 	FailIf(callee.callback2Data2 != 79);
147 	caller.event2->ReleaseHandler(&callee, &FUTCallee::Callback2);
148 
149 TESTSUITE_TEST(2, MultipleCallback0)
150 	FUTCaller caller;
151 	FUTCallee callee;
152 	caller.event0->InsertHandler(&callee, &FUTCallee::Callback0_1);
153 	caller.event0->InsertHandler(&callee, &FUTCallee::Callback0_2);
154 	FailIf(caller.event0->GetHandlerCount() != 2);
155 
156 	callee.isCallback0_1Called = false;
157 	callee.isCallback0_2Called = false;
158 	(*(caller.event0))();
159 	FailIf(!callee.isCallback0_1Called);
160 	FailIf(!callee.isCallback0_2Called);
161 
162 	FailIf(caller.event0->GetHandlerCount() != 2);
163 	caller.event0->ReleaseHandler(&callee, &FUTCallee::Callback0_1);
164 	FailIf(caller.event0->GetHandlerCount() != 1);
165 	caller.event0->ReleaseHandler(&callee, &FUTCallee::Callback0_2);
166 	FailIf(caller.event0->GetHandlerCount() != 0);
167 
168 TESTSUITE_TEST(3, CallbacksThatReleaseImmediately)
169 	FUTDumbCaller caller;
170 	FUTAntisocialCallee callee;
171 	callee.caller = &caller;
172 
173 	caller.event0.InsertHandler(&callee, &FUTAntisocialCallee::Callback0);
174 	caller.event1.InsertHandler(&callee, &FUTAntisocialCallee::Callback1);
175 	caller.event2.InsertHandler(&callee, &FUTAntisocialCallee::Callback2);
176 
177 	FailIf(caller.event0.GetHandlerCount() != 1);
178 	FailIf(caller.event1.GetHandlerCount() != 1);
179 	FailIf(caller.event2.GetHandlerCount() != 1);
180 
181 	// Test the callbacks
182 	(caller.event0)();
183 	(caller.event1)(&caller);
184 	(caller.event2)(&caller, 42);
185 
186 	FailIf(!callee.isSuccess());
187 	FailIf(caller.event0.GetHandlerCount() != 0);
188 	FailIf(caller.event1.GetHandlerCount() != 0);
189 	FailIf(caller.event2.GetHandlerCount() != 0);
190 
191 TESTSUITE_END
192