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/dali.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 SignalV2<void ()> VoidSignalVoid;
46 typedef SignalV2<void (float)> VoidSignalFloat;
48 typedef SignalV2<float ()> FloatSignalVoid;
49 typedef SignalV2<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 )
193 ++mTotalInstanceCount;
194 ++mCurrentInstanceCount;
199 --mCurrentInstanceCount;
202 float operator()(float value)
209 float* mLastReceivedValue;
211 static int mTotalInstanceCount;
212 static int mCurrentInstanceCount;
213 static int mCallbackCount;
216 static void ResetFunctorCounts()
218 VoidFunctorVoid::mTotalInstanceCount = 0;
219 VoidFunctorVoid::mCurrentInstanceCount = 0;
220 VoidFunctorVoid::mCallbackCount = 0;
222 VoidFunctorFloat::mTotalInstanceCount = 0;
223 VoidFunctorFloat::mCurrentInstanceCount = 0;
224 VoidFunctorFloat::mCallbackCount = 0;
226 FloatFunctorVoid::mTotalInstanceCount = 0;
227 FloatFunctorVoid::mCurrentInstanceCount = 0;
228 FloatFunctorVoid::mCallbackCount = 0;
230 FloatFunctorFloat::mTotalInstanceCount = 0;
231 FloatFunctorFloat::mCurrentInstanceCount = 0;
232 FloatFunctorFloat::mCallbackCount = 0;
235 int VoidFunctorVoid::mTotalInstanceCount = 0;
236 int VoidFunctorVoid::mCurrentInstanceCount = 0;
237 int VoidFunctorVoid::mCallbackCount = 0;
239 int VoidFunctorFloat::mTotalInstanceCount = 0;
240 int VoidFunctorFloat::mCurrentInstanceCount = 0;
241 int VoidFunctorFloat::mCallbackCount = 0;
243 int FloatFunctorVoid::mTotalInstanceCount = 0;
244 int FloatFunctorVoid::mCurrentInstanceCount = 0;
245 int FloatFunctorVoid::mCallbackCount = 0;
247 int FloatFunctorFloat::mTotalInstanceCount = 0;
248 int FloatFunctorFloat::mCurrentInstanceCount = 0;
249 int FloatFunctorFloat::mCallbackCount = 0;
254 int UtcDaliSignalFunctorsEmptyCheck(void)
256 // Test that Empty() check works before & after signal connection
258 ResetFunctorCounts();
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 );
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 );
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 );
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 );
292 int UtcDaliSignalFunctorsEmit(void)
294 // Test basic signal emission for each functor type
296 ResetFunctorCounts();
301 TestConnectionTracker tracker;
303 DALI_TEST_EQUALS( VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
304 DALI_TEST_EQUALS( VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
311 signals.mVoidSignalVoid.Emit();
312 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION );
314 // Test double emission
315 signals.mVoidSignalVoid.Emit();
316 DALI_TEST_EQUALS( VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION );
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();
325 TestConnectionTracker tracker;
326 float lastReceivedValue( 0.0f );
328 DALI_TEST_EQUALS( VoidFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION );
329 DALI_TEST_EQUALS( VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
336 signals.mVoidSignalFloat.Emit( 3.5f );
337 DALI_TEST_EQUALS( VoidFunctorFloat::mCallbackCount, 1, TEST_LOCATION );
338 DALI_TEST_EQUALS( lastReceivedValue, 3.5f, TEST_LOCATION );
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 );
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();
353 int UtcDaliSignalFunctorsEmitReturn(void)
355 // Test signals with return values
357 ResetFunctorCounts();
362 TestConnectionTracker tracker;
364 DALI_TEST_EQUALS( FloatFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION );
365 DALI_TEST_EQUALS( FloatFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION );
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 );
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 );
376 // 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();