2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <dali/public-api/dali-core.h>
24 #include <dali-test-suite-utils.h>
28 void utc_dali_signal_templates_functors_startup(void)
30 test_return_value = TET_UNDEF;
33 void utc_dali_signal_templates_functors_cleanup(void)
35 test_return_value = TET_PASS;
45 typedef Signal<void ()> VoidSignalVoid;
46 typedef Signal<void (float)> VoidSignalFloat;
48 typedef Signal<float ()> FloatSignalVoid;
49 typedef Signal<float (float)> FloatSignalFloat;
55 void CheckNoConnections()
57 DALI_TEST_EQUALS( mVoidSignalVoid.GetConnectionCount(), 0u, TEST_LOCATION );
58 DALI_TEST_EQUALS( mVoidSignalFloat.GetConnectionCount(), 0u, TEST_LOCATION );
60 DALI_TEST_EQUALS( mFloatSignalVoid.GetConnectionCount(), 0u, TEST_LOCATION );
61 DALI_TEST_EQUALS( mFloatSignalFloat.GetConnectionCount(), 0u, TEST_LOCATION );
64 VoidSignalVoid mVoidSignalVoid;
65 VoidSignalFloat mVoidSignalFloat;
67 FloatSignalVoid mFloatSignalVoid;
68 FloatSignalFloat mFloatSignalFloat;
71 class TestConnectionTracker : public ConnectionTracker
75 TestConnectionTracker()
80 struct VoidFunctorVoid
84 ++mTotalInstanceCount;
85 ++mCurrentInstanceCount;
88 VoidFunctorVoid( const VoidFunctorVoid& copyMe )
90 ++mTotalInstanceCount;
91 ++mCurrentInstanceCount;
96 --mCurrentInstanceCount;
104 static int mTotalInstanceCount;
105 static int mCurrentInstanceCount;
106 static int mCallbackCount;
109 struct VoidFunctorFloat
111 VoidFunctorFloat( float* lastReceivedValue )
112 : mLastReceivedValue( lastReceivedValue )
114 ++mTotalInstanceCount;
115 ++mCurrentInstanceCount;
118 VoidFunctorFloat( const VoidFunctorFloat& copyMe )
119 : mLastReceivedValue( copyMe.mLastReceivedValue )
121 ++mTotalInstanceCount;
122 ++mCurrentInstanceCount;
127 --mCurrentInstanceCount;
130 void operator()(float value)
134 if( mLastReceivedValue )
136 *mLastReceivedValue = value;
140 float* mLastReceivedValue;
142 static int mTotalInstanceCount;
143 static int mCurrentInstanceCount;
144 static int mCallbackCount;
147 struct FloatFunctorVoid
149 static float DEFAULT_RETURN_VALUE;
153 ++mTotalInstanceCount;
154 ++mCurrentInstanceCount;
157 FloatFunctorVoid( const FloatFunctorVoid& copyMe )
159 ++mTotalInstanceCount;
160 ++mCurrentInstanceCount;
165 --mCurrentInstanceCount;
172 return DEFAULT_RETURN_VALUE;
175 static int mTotalInstanceCount;
176 static int mCurrentInstanceCount;
177 static int mCallbackCount;
180 float FloatFunctorVoid::DEFAULT_RETURN_VALUE = 5.0f;
182 struct FloatFunctorFloat
185 : mLastReceivedValue()
187 ++mTotalInstanceCount;
188 ++mCurrentInstanceCount;
191 FloatFunctorFloat( const FloatFunctorFloat& copyMe )
192 : mLastReceivedValue (copyMe.mLastReceivedValue )
194 ++mTotalInstanceCount;
195 ++mCurrentInstanceCount;
200 --mCurrentInstanceCount;
203 float operator()(float value)
210 float* mLastReceivedValue;
212 static int mTotalInstanceCount;
213 static int mCurrentInstanceCount;
214 static int mCallbackCount;
217 static void ResetFunctorCounts()
219 VoidFunctorVoid::mTotalInstanceCount = 0;
220 VoidFunctorVoid::mCurrentInstanceCount = 0;
221 VoidFunctorVoid::mCallbackCount = 0;
223 VoidFunctorFloat::mTotalInstanceCount = 0;
224 VoidFunctorFloat::mCurrentInstanceCount = 0;
225 VoidFunctorFloat::mCallbackCount = 0;
227 FloatFunctorVoid::mTotalInstanceCount = 0;
228 FloatFunctorVoid::mCurrentInstanceCount = 0;
229 FloatFunctorVoid::mCallbackCount = 0;
231 FloatFunctorFloat::mTotalInstanceCount = 0;
232 FloatFunctorFloat::mCurrentInstanceCount = 0;
233 FloatFunctorFloat::mCallbackCount = 0;
236 int VoidFunctorVoid::mTotalInstanceCount = 0;
237 int VoidFunctorVoid::mCurrentInstanceCount = 0;
238 int VoidFunctorVoid::mCallbackCount = 0;
240 int VoidFunctorFloat::mTotalInstanceCount = 0;
241 int VoidFunctorFloat::mCurrentInstanceCount = 0;
242 int VoidFunctorFloat::mCallbackCount = 0;
244 int FloatFunctorVoid::mTotalInstanceCount = 0;
245 int FloatFunctorVoid::mCurrentInstanceCount = 0;
246 int FloatFunctorVoid::mCallbackCount = 0;
248 int FloatFunctorFloat::mTotalInstanceCount = 0;
249 int FloatFunctorFloat::mCurrentInstanceCount = 0;
250 int FloatFunctorFloat::mCallbackCount = 0;
255 int UtcDaliSignalFunctorsEmptyCheck(void)
257 // Test that Empty() check works before & after signal connection
259 ResetFunctorCounts();
262 TestSignals::VoidSignalVoid signal;
263 DALI_TEST_CHECK( signal.Empty() );
264 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
265 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
266 TestConnectionTracker tracker;
267 signal.Connect( &tracker, VoidFunctorVoid() );
268 DALI_TEST_CHECK( ! signal.Empty() );
269 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
270 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 1, TEST_LOCATION );
272 // TestConnectionTracker should auto-disconnect
273 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
274 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
277 TestSignals::VoidSignalFloat signal;
278 DALI_TEST_CHECK( signal.Empty() );
279 DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION );
280 DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
281 TestConnectionTracker tracker;
282 signal.Connect( &tracker, VoidFunctorFloat(NULL) );
283 DALI_TEST_CHECK( ! signal.Empty() );
284 DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
285 DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 1, TEST_LOCATION );
287 // TestConnectionTracker should auto-disconnect
288 DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
289 DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
293 int UtcDaliSignalFunctorsEmit(void)
295 // Test basic signal emission for each functor type
297 ResetFunctorCounts();
302 TestConnectionTracker tracker;
304 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
305 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
307 signals.mVoidSignalVoid.Connect( &tracker, VoidFunctorVoid() );
308 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
309 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 1, TEST_LOCATION );
310 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
312 signals.mVoidSignalVoid.Emit();
313 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
315 // Test double emission
316 signals.mVoidSignalVoid.Emit();
317 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
319 // TestConnectionTracker should auto-disconnect
320 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
321 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
322 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
323 signals.CheckNoConnections();
326 TestConnectionTracker tracker;
327 float lastReceivedValue( 0.0f );
329 DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION );
330 DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
332 signals.mVoidSignalFloat.Connect( &tracker, VoidFunctorFloat(&lastReceivedValue) );
333 DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
334 DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 1, TEST_LOCATION );
335 DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 0, TEST_LOCATION );
337 signals.mVoidSignalFloat.Emit( 3.5f );
338 DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 1, TEST_LOCATION );
339 DALI_TEST_EQUALS( lastReceivedValue, 3.5f, TEST_LOCATION );
341 // Test double emission
342 signals.mVoidSignalFloat.Emit( 7.0f );
343 DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 2, TEST_LOCATION );
344 DALI_TEST_EQUALS( lastReceivedValue, 7.0f, TEST_LOCATION );
346 // TestConnectionTracker should auto-disconnect
347 DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
348 DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
349 DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 2, TEST_LOCATION );
350 signals.CheckNoConnections();
354 int UtcDaliSignalFunctorsEmitReturn(void)
356 // Test signals with return values
358 ResetFunctorCounts();
363 TestConnectionTracker tracker;
365 DALI_TEST_EQUALS( FloatFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
366 DALI_TEST_EQUALS( FloatFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
368 signals.mFloatSignalVoid.Connect( &tracker, FloatFunctorVoid() );
369 DALI_TEST_EQUALS( FloatFunctorVoid::mTotalInstanceCount, 2/*temporary copy + signal copy*/, TEST_LOCATION );
370 DALI_TEST_EQUALS( FloatFunctorVoid::mCurrentInstanceCount, 1, TEST_LOCATION );
371 DALI_TEST_EQUALS( FloatFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
373 float returnValue = signals.mFloatSignalVoid.Emit();
374 DALI_TEST_EQUALS( FloatFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
375 DALI_TEST_EQUALS( returnValue, FloatFunctorVoid::DEFAULT_RETURN_VALUE, TEST_LOCATION );
377 // Test double emission
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 );
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();
389 TestConnectionTracker tracker;
391 DALI_TEST_EQUALS( FloatFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION );
392 DALI_TEST_EQUALS( FloatFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
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 );
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 );
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();
416 int UtcDaliSignalFunctorsDisconnectBeforeEmit(void)
418 // Test explicit disconnect using ConnectionTracker
420 ResetFunctorCounts();
425 TestConnectionTracker tracker;
427 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
428 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
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 );
438 signals.mVoidSignalVoid.Emit();
439 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
441 // Test double emission
442 signals.mVoidSignalVoid.Emit();
443 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION );
448 int UtcDaliSignalFunctorsDestroySignal(void)
450 // Test destruction of signal before slot
452 ResetFunctorCounts();
454 TestConnectionTracker tracker;
459 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
460 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
466 signals.mVoidSignalVoid.Emit();
467 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount,1, TEST_LOCATION );
469 DALI_TEST_EQUALS( tracker.GetConnectionCount(), 1u, TEST_LOCATION );
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 );
477 DALI_TEST_EQUALS( tracker.GetConnectionCount(), 0u, TEST_LOCATION );
481 int UtcDaliSignalConnectVoidFunctor(void)
483 // Test connecting a functor using the VoidFunctor wrapper
485 ResetFunctorCounts();
490 TestConnectionTracker tracker;
492 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
493 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
500 signals.mVoidSignalVoid.Emit();
501 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
503 // Test double emission
504 signals.mVoidSignalVoid.Emit();
505 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
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();