2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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.
22 #include <dali/dali.h>
23 #include <dali-test-suite-utils.h>
27 void utc_dali_signal_templates_functors_startup(void)
29 test_return_value = TET_UNDEF;
32 void utc_dali_signal_templates_functors_cleanup(void)
34 test_return_value = TET_PASS;
44 typedef SignalV2<void ()> VoidSignalVoid;
45 typedef SignalV2<void (float)> VoidSignalFloat;
47 typedef SignalV2<float ()> FloatSignalVoid;
48 typedef SignalV2<float (float)> FloatSignalFloat;
54 void CheckNoConnections()
56 DALI_TEST_EQUALS( mVoidSignalVoid.GetConnectionCount(), 0u, TEST_LOCATION );
57 DALI_TEST_EQUALS( mVoidSignalFloat.GetConnectionCount(), 0u, TEST_LOCATION );
59 DALI_TEST_EQUALS( mFloatSignalVoid.GetConnectionCount(), 0u, TEST_LOCATION );
60 DALI_TEST_EQUALS( mFloatSignalFloat.GetConnectionCount(), 0u, TEST_LOCATION );
63 VoidSignalVoid mVoidSignalVoid;
64 VoidSignalFloat mVoidSignalFloat;
66 FloatSignalVoid mFloatSignalVoid;
67 FloatSignalFloat mFloatSignalFloat;
70 class TestConnectionTracker : public ConnectionTracker
74 TestConnectionTracker()
79 struct VoidFunctorVoid
83 ++mTotalInstanceCount;
84 ++mCurrentInstanceCount;
87 VoidFunctorVoid( const VoidFunctorVoid& copyMe )
89 ++mTotalInstanceCount;
90 ++mCurrentInstanceCount;
95 --mCurrentInstanceCount;
103 static int mTotalInstanceCount;
104 static int mCurrentInstanceCount;
105 static int mCallbackCount;
108 struct VoidFunctorFloat
110 VoidFunctorFloat( float* lastReceivedValue )
111 : mLastReceivedValue( lastReceivedValue )
113 ++mTotalInstanceCount;
114 ++mCurrentInstanceCount;
117 VoidFunctorFloat( const VoidFunctorFloat& copyMe )
118 : mLastReceivedValue( copyMe.mLastReceivedValue )
120 ++mTotalInstanceCount;
121 ++mCurrentInstanceCount;
126 --mCurrentInstanceCount;
129 void operator()(float value)
133 if( mLastReceivedValue )
135 *mLastReceivedValue = value;
139 float* mLastReceivedValue;
141 static int mTotalInstanceCount;
142 static int mCurrentInstanceCount;
143 static int mCallbackCount;
146 struct FloatFunctorVoid
148 static float DEFAULT_RETURN_VALUE;
152 ++mTotalInstanceCount;
153 ++mCurrentInstanceCount;
156 FloatFunctorVoid( const FloatFunctorVoid& copyMe )
158 ++mTotalInstanceCount;
159 ++mCurrentInstanceCount;
164 --mCurrentInstanceCount;
171 return DEFAULT_RETURN_VALUE;
174 static int mTotalInstanceCount;
175 static int mCurrentInstanceCount;
176 static int mCallbackCount;
179 float FloatFunctorVoid::DEFAULT_RETURN_VALUE = 5.0f;
181 struct FloatFunctorFloat
184 : mLastReceivedValue()
186 ++mTotalInstanceCount;
187 ++mCurrentInstanceCount;
190 FloatFunctorFloat( const FloatFunctorFloat& copyMe )
192 ++mTotalInstanceCount;
193 ++mCurrentInstanceCount;
198 --mCurrentInstanceCount;
201 float operator()(float value)
208 float* mLastReceivedValue;
210 static int mTotalInstanceCount;
211 static int mCurrentInstanceCount;
212 static int mCallbackCount;
215 static void ResetFunctorCounts()
217 VoidFunctorVoid::mTotalInstanceCount = 0;
218 VoidFunctorVoid::mCurrentInstanceCount = 0;
219 VoidFunctorVoid::mCallbackCount = 0;
221 VoidFunctorFloat::mTotalInstanceCount = 0;
222 VoidFunctorFloat::mCurrentInstanceCount = 0;
223 VoidFunctorFloat::mCallbackCount = 0;
225 FloatFunctorVoid::mTotalInstanceCount = 0;
226 FloatFunctorVoid::mCurrentInstanceCount = 0;
227 FloatFunctorVoid::mCallbackCount = 0;
229 FloatFunctorFloat::mTotalInstanceCount = 0;
230 FloatFunctorFloat::mCurrentInstanceCount = 0;
231 FloatFunctorFloat::mCallbackCount = 0;
234 int VoidFunctorVoid::mTotalInstanceCount = 0;
235 int VoidFunctorVoid::mCurrentInstanceCount = 0;
236 int VoidFunctorVoid::mCallbackCount = 0;
238 int VoidFunctorFloat::mTotalInstanceCount = 0;
239 int VoidFunctorFloat::mCurrentInstanceCount = 0;
240 int VoidFunctorFloat::mCallbackCount = 0;
242 int FloatFunctorVoid::mTotalInstanceCount = 0;
243 int FloatFunctorVoid::mCurrentInstanceCount = 0;
244 int FloatFunctorVoid::mCallbackCount = 0;
246 int FloatFunctorFloat::mTotalInstanceCount = 0;
247 int FloatFunctorFloat::mCurrentInstanceCount = 0;
248 int FloatFunctorFloat::mCallbackCount = 0;
253 int UtcDaliSignalFunctorsEmptyCheck(void)
255 // Test that Empty() check works before & after signal connection
257 ResetFunctorCounts();
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 );
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 );
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 );
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 );
291 int UtcDaliSignalFunctorsEmit(void)
293 // Test basic signal emission for each functor type
295 ResetFunctorCounts();
300 TestConnectionTracker tracker;
302 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
303 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
310 signals.mVoidSignalVoid.Emit();
311 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
313 // Test double emission
314 signals.mVoidSignalVoid.Emit();
315 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
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();
324 TestConnectionTracker tracker;
325 float lastReceivedValue( 0.0f );
327 DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION );
328 DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
335 signals.mVoidSignalFloat.Emit( 3.5f );
336 DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 1, TEST_LOCATION );
337 DALI_TEST_EQUALS( lastReceivedValue, 3.5f, TEST_LOCATION );
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 );
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();
352 int UtcDaliSignalFunctorsEmitReturn(void)
354 // Test signals with return values
356 ResetFunctorCounts();
361 TestConnectionTracker tracker;
363 DALI_TEST_EQUALS( FloatFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
364 DALI_TEST_EQUALS( FloatFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
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 );
375 // Test double emission
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 );
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();
388 TestConnectionTracker tracker;
390 DALI_TEST_EQUALS( FloatFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION );
391 DALI_TEST_EQUALS( FloatFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
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 );
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 );
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();
415 int UtcDaliSignalFunctorsDisconnectBeforeEmit(void)
417 // Test explicit disconnect using ConnectionTracker
419 ResetFunctorCounts();
424 TestConnectionTracker tracker;
426 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
427 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
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 );
437 signals.mVoidSignalVoid.Emit();
438 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
440 // Test double emission
441 signals.mVoidSignalVoid.Emit();
442 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
447 int UtcDaliSignalFunctorsDestroySignal(void)
449 // Test destruction of signal before slot
451 ResetFunctorCounts();
453 TestConnectionTracker tracker;
458 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
459 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
465 signals.mVoidSignalVoid.Emit();
466 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount,1, TEST_LOCATION );
468 DALI_TEST_EQUALS( tracker.GetConnectionCount(), 1u, TEST_LOCATION );
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 );
476 DALI_TEST_EQUALS( tracker.GetConnectionCount(), 0u, TEST_LOCATION );
480 int UtcDaliSignalConnectVoidFunctor(void)
482 // Test connecting a functor using the VoidFunctor wrapper
484 ResetFunctorCounts();
489 TestConnectionTracker tracker;
491 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
492 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
499 signals.mVoidSignalVoid.Emit();
500 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
502 // Test double emission
503 signals.mVoidSignalVoid.Emit();
504 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
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();