Revert "License conversion from Flora to Apache 2.0"
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-SignalTemplatesFunctors.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://floralicense.org/license/
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 // EXTERNAL INCLUDES
18 #include <iostream>
19 #include <stdlib.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/dali.h>
23 #include <dali-test-suite-utils.h>
24
25 using namespace Dali;
26
27 void utc_dali_signal_templates_functors_startup(void)
28 {
29   test_return_value = TET_UNDEF;
30 }
31
32 void utc_dali_signal_templates_functors_cleanup(void)
33 {
34   test_return_value = TET_PASS;
35 }
36
37 namespace
38 {
39
40 class TestSignals
41 {
42 public:
43
44   typedef SignalV2<void ()> VoidSignalVoid;
45   typedef SignalV2<void (float)> VoidSignalFloat;
46
47   typedef SignalV2<float ()> FloatSignalVoid;
48   typedef SignalV2<float (float)> FloatSignalFloat;
49
50   TestSignals()
51   {
52   }
53
54   void CheckNoConnections()
55   {
56     DALI_TEST_EQUALS( mVoidSignalVoid.GetConnectionCount(), 0u, TEST_LOCATION );
57     DALI_TEST_EQUALS( mVoidSignalFloat.GetConnectionCount(), 0u, TEST_LOCATION );
58
59     DALI_TEST_EQUALS( mFloatSignalVoid.GetConnectionCount(), 0u, TEST_LOCATION );
60     DALI_TEST_EQUALS( mFloatSignalFloat.GetConnectionCount(), 0u, TEST_LOCATION );
61   }
62
63   VoidSignalVoid mVoidSignalVoid;
64   VoidSignalFloat mVoidSignalFloat;
65
66   FloatSignalVoid mFloatSignalVoid;
67   FloatSignalFloat mFloatSignalFloat;
68 };
69
70 class TestConnectionTracker : public ConnectionTracker
71 {
72 public:
73
74   TestConnectionTracker()
75   {
76   }
77 };
78
79 struct VoidFunctorVoid
80 {
81   VoidFunctorVoid()
82   {
83     ++mTotalInstanceCount;
84     ++mCurrentInstanceCount;
85   }
86
87   VoidFunctorVoid( const VoidFunctorVoid& copyMe )
88   {
89     ++mTotalInstanceCount;
90     ++mCurrentInstanceCount;
91   }
92
93   ~VoidFunctorVoid()
94   {
95     --mCurrentInstanceCount;
96   }
97
98   void operator()()
99   {
100     ++mCallbackCount;
101   }
102
103   static int mTotalInstanceCount;
104   static int mCurrentInstanceCount;
105   static int mCallbackCount;
106 };
107
108 struct VoidFunctorFloat
109 {
110   VoidFunctorFloat( float* lastReceivedValue )
111   : mLastReceivedValue( lastReceivedValue )
112   {
113     ++mTotalInstanceCount;
114     ++mCurrentInstanceCount;
115   }
116
117   VoidFunctorFloat( const VoidFunctorFloat& copyMe )
118   : mLastReceivedValue( copyMe.mLastReceivedValue )
119   {
120     ++mTotalInstanceCount;
121     ++mCurrentInstanceCount;
122   }
123
124   ~VoidFunctorFloat()
125   {
126     --mCurrentInstanceCount;
127   }
128
129   void operator()(float value)
130   {
131     ++mCallbackCount;
132
133     if( mLastReceivedValue )
134     {
135       *mLastReceivedValue = value;
136     }
137   }
138
139   float* mLastReceivedValue;
140
141   static int mTotalInstanceCount;
142   static int mCurrentInstanceCount;
143   static int mCallbackCount;
144 };
145
146 struct FloatFunctorVoid
147 {
148   static float DEFAULT_RETURN_VALUE;
149
150   FloatFunctorVoid()
151   {
152     ++mTotalInstanceCount;
153     ++mCurrentInstanceCount;
154   }
155
156   FloatFunctorVoid( const FloatFunctorVoid& copyMe )
157   {
158     ++mTotalInstanceCount;
159     ++mCurrentInstanceCount;
160   }
161
162   ~FloatFunctorVoid()
163   {
164     --mCurrentInstanceCount;
165   }
166
167   float operator()()
168   {
169     ++mCallbackCount;
170
171     return DEFAULT_RETURN_VALUE;
172   }
173
174   static int mTotalInstanceCount;
175   static int mCurrentInstanceCount;
176   static int mCallbackCount;
177 };
178
179 float FloatFunctorVoid::DEFAULT_RETURN_VALUE = 5.0f;
180
181 struct FloatFunctorFloat
182 {
183   FloatFunctorFloat()
184   : mLastReceivedValue()
185   {
186     ++mTotalInstanceCount;
187     ++mCurrentInstanceCount;
188   }
189
190   FloatFunctorFloat( const FloatFunctorFloat& copyMe )
191   {
192     ++mTotalInstanceCount;
193     ++mCurrentInstanceCount;
194   }
195
196   ~FloatFunctorFloat()
197   {
198     --mCurrentInstanceCount;
199   }
200
201   float operator()(float value)
202   {
203     ++mCallbackCount;
204
205     return value + 1.0f;
206   }
207
208   float* mLastReceivedValue;
209
210   static int mTotalInstanceCount;
211   static int mCurrentInstanceCount;
212   static int mCallbackCount;
213 };
214
215 static void ResetFunctorCounts()
216 {
217   VoidFunctorVoid::mTotalInstanceCount   = 0;
218   VoidFunctorVoid::mCurrentInstanceCount = 0;
219   VoidFunctorVoid::mCallbackCount        = 0;
220
221   VoidFunctorFloat::mTotalInstanceCount   = 0;
222   VoidFunctorFloat::mCurrentInstanceCount = 0;
223   VoidFunctorFloat::mCallbackCount        = 0;
224
225   FloatFunctorVoid::mTotalInstanceCount   = 0;
226   FloatFunctorVoid::mCurrentInstanceCount = 0;
227   FloatFunctorVoid::mCallbackCount        = 0;
228
229   FloatFunctorFloat::mTotalInstanceCount   = 0;
230   FloatFunctorFloat::mCurrentInstanceCount = 0;
231   FloatFunctorFloat::mCallbackCount        = 0;
232 }
233
234 int VoidFunctorVoid::mTotalInstanceCount   = 0;
235 int VoidFunctorVoid::mCurrentInstanceCount = 0;
236 int VoidFunctorVoid::mCallbackCount        = 0;
237
238 int VoidFunctorFloat::mTotalInstanceCount   = 0;
239 int VoidFunctorFloat::mCurrentInstanceCount = 0;
240 int VoidFunctorFloat::mCallbackCount        = 0;
241
242 int FloatFunctorVoid::mTotalInstanceCount   = 0;
243 int FloatFunctorVoid::mCurrentInstanceCount = 0;
244 int FloatFunctorVoid::mCallbackCount        = 0;
245
246 int FloatFunctorFloat::mTotalInstanceCount   = 0;
247 int FloatFunctorFloat::mCurrentInstanceCount = 0;
248 int FloatFunctorFloat::mCallbackCount        = 0;
249
250 } // anon namespace
251
252
253 int UtcDaliSignalFunctorsEmptyCheck(void)
254 {
255   // Test that Empty() check works before & after signal connection
256
257   ResetFunctorCounts();
258
259   {
260     TestSignals::VoidSignalVoid signal;
261     DALI_TEST_CHECK( signal.Empty() );
262     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
263     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
264     TestConnectionTracker tracker;
265     signal.Connect( &tracker, VoidFunctorVoid() );
266     DALI_TEST_CHECK( ! signal.Empty() );
267     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
268     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 1, TEST_LOCATION );
269   }
270   // TestConnectionTracker should auto-disconnect
271   DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
272   DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
273
274   {
275     TestSignals::VoidSignalFloat signal;
276     DALI_TEST_CHECK( signal.Empty() );
277     DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION );
278     DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
279     TestConnectionTracker tracker;
280     signal.Connect( &tracker, VoidFunctorFloat(NULL) );
281     DALI_TEST_CHECK( ! signal.Empty() );
282     DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
283     DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 1, TEST_LOCATION );
284   }
285   // TestConnectionTracker should auto-disconnect
286   DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
287   DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
288   END_TEST;
289 }
290
291 int UtcDaliSignalFunctorsEmit(void)
292 {
293   // Test basic signal emission for each functor type
294
295   ResetFunctorCounts();
296
297   TestSignals signals;
298
299   {
300     TestConnectionTracker tracker;
301
302     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
303     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
304
305     signals.mVoidSignalVoid.Connect( &tracker, VoidFunctorVoid() );
306     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
307     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 1, TEST_LOCATION );
308     DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
309
310     signals.mVoidSignalVoid.Emit();
311     DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
312
313     // Test double emission
314     signals.mVoidSignalVoid.Emit();
315     DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
316   }
317   // TestConnectionTracker should auto-disconnect
318   DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
319   DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
320   DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
321   signals.CheckNoConnections();
322
323   {
324     TestConnectionTracker tracker;
325     float lastReceivedValue( 0.0f );
326
327     DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION );
328     DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
329
330     signals.mVoidSignalFloat.Connect( &tracker, VoidFunctorFloat(&lastReceivedValue) );
331     DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
332     DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 1, TEST_LOCATION );
333     DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 0, TEST_LOCATION );
334
335     signals.mVoidSignalFloat.Emit( 3.5f );
336     DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 1, TEST_LOCATION );
337     DALI_TEST_EQUALS( lastReceivedValue, 3.5f, TEST_LOCATION );
338
339     // Test double emission
340     signals.mVoidSignalFloat.Emit( 7.0f );
341     DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 2, TEST_LOCATION );
342     DALI_TEST_EQUALS( lastReceivedValue, 7.0f, TEST_LOCATION );
343   }
344   // TestConnectionTracker should auto-disconnect
345   DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
346   DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
347   DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 2, TEST_LOCATION );
348   signals.CheckNoConnections();
349   END_TEST;
350 }
351
352 int UtcDaliSignalFunctorsEmitReturn(void)
353 {
354   // Test signals with return values
355
356   ResetFunctorCounts();
357
358   TestSignals signals;
359
360   {
361     TestConnectionTracker tracker;
362
363     DALI_TEST_EQUALS( FloatFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
364     DALI_TEST_EQUALS( FloatFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
365
366     signals.mFloatSignalVoid.Connect( &tracker, FloatFunctorVoid() );
367     DALI_TEST_EQUALS( FloatFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
368     DALI_TEST_EQUALS( FloatFunctorVoid::mCurrentInstanceCount, 1, TEST_LOCATION );
369     DALI_TEST_EQUALS( FloatFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
370
371     float returnValue = signals.mFloatSignalVoid.Emit();
372     DALI_TEST_EQUALS( FloatFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
373     DALI_TEST_EQUALS( returnValue, FloatFunctorVoid::DEFAULT_RETURN_VALUE, TEST_LOCATION );
374
375     // Test double emission
376     returnValue = 0.0f;
377     returnValue = signals.mFloatSignalVoid.Emit();
378     DALI_TEST_EQUALS( FloatFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
379     DALI_TEST_EQUALS( returnValue, FloatFunctorVoid::DEFAULT_RETURN_VALUE, TEST_LOCATION );
380   }
381   // TestConnectionTracker should auto-disconnect
382   DALI_TEST_EQUALS( FloatFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
383   DALI_TEST_EQUALS( FloatFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
384   DALI_TEST_EQUALS( FloatFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
385   signals.CheckNoConnections();
386
387   {
388     TestConnectionTracker tracker;
389
390     DALI_TEST_EQUALS( FloatFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION );
391     DALI_TEST_EQUALS( FloatFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
392
393     signals.mFloatSignalFloat.Connect( &tracker, FloatFunctorFloat() );
394     DALI_TEST_EQUALS( FloatFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
395     DALI_TEST_EQUALS( FloatFunctorFloat::mCurrentInstanceCount, 1, TEST_LOCATION );
396     DALI_TEST_EQUALS( FloatFunctorFloat::mCallbackCount, 0, TEST_LOCATION );
397
398     float returnValue = signals.mFloatSignalFloat.Emit( 0.1f );
399     DALI_TEST_EQUALS( FloatFunctorFloat::mCallbackCount, 1, TEST_LOCATION );
400     DALI_TEST_EQUALS( returnValue, 1.0f + 0.1f, TEST_LOCATION );
401
402     // Test double emission
403     returnValue = signals.mFloatSignalFloat.Emit( 0.2f );
404     DALI_TEST_EQUALS( FloatFunctorFloat::mCallbackCount, 2, TEST_LOCATION );
405     DALI_TEST_EQUALS( returnValue, 1.0f + 0.2f, TEST_LOCATION );
406   }
407   // TestConnectionTracker should auto-disconnect
408   DALI_TEST_EQUALS( FloatFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
409   DALI_TEST_EQUALS( FloatFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
410   DALI_TEST_EQUALS( FloatFunctorFloat::mCallbackCount, 2, TEST_LOCATION );
411   signals.CheckNoConnections();
412   END_TEST;
413 }
414
415 int UtcDaliSignalFunctorsDisconnectBeforeEmit(void)
416 {
417   // Test explicit disconnect using ConnectionTracker
418
419   ResetFunctorCounts();
420
421   TestSignals signals;
422
423   {
424     TestConnectionTracker tracker;
425
426     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
427     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
428
429     signals.mVoidSignalVoid.Connect( &tracker, VoidFunctorVoid() );
430     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
431     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 1, TEST_LOCATION );
432
433     tracker.DisconnectAll();
434     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
435     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
436
437     signals.mVoidSignalVoid.Emit();
438     DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
439
440     // Test double emission
441     signals.mVoidSignalVoid.Emit();
442     DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
443   }
444   END_TEST;
445 }
446
447 int UtcDaliSignalFunctorsDestroySignal(void)
448 {
449   // Test destruction of signal before slot
450
451   ResetFunctorCounts();
452
453   TestConnectionTracker tracker;
454
455   {
456     TestSignals signals;
457
458     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
459     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
460
461     signals.mVoidSignalVoid.Connect( &tracker, VoidFunctorVoid() );
462     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
463     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 1, TEST_LOCATION );
464
465     signals.mVoidSignalVoid.Emit();
466     DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount,1, TEST_LOCATION );
467
468     DALI_TEST_EQUALS( tracker.GetConnectionCount(), 1u, TEST_LOCATION );
469   }
470
471   // Functor should have been deleted with signal
472   DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
473   DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
474   DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
475
476   DALI_TEST_EQUALS( tracker.GetConnectionCount(), 0u, TEST_LOCATION );
477   END_TEST;
478 }
479
480 int UtcDaliSignalConnectVoidFunctor(void)
481 {
482   // Test connecting a functor using the VoidFunctor wrapper
483
484   ResetFunctorCounts();
485
486   TestSignals signals;
487
488   {
489     TestConnectionTracker tracker;
490
491     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
492     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
493
494     signals.mVoidSignalVoid.Connect( &tracker, FunctorDelegate::New( VoidFunctorVoid() ) );
495     DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
496     DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 1, TEST_LOCATION );
497     DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
498
499     signals.mVoidSignalVoid.Emit();
500     DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
501
502     // Test double emission
503     signals.mVoidSignalVoid.Emit();
504     DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
505   }
506   // TestConnectionTracker should auto-disconnect
507   DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
508   DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
509   DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
510   signals.CheckNoConnections();
511   END_TEST;
512 }