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