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