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.
24 #include <dali-test-suite-utils.h>
25 #include <dali/public-api/dali-core.h>
29 void utc_dali_signal_templates_functors_startup(void)
31 test_return_value = TET_UNDEF;
34 void utc_dali_signal_templates_functors_cleanup(void)
36 test_return_value = TET_PASS;
44 typedef Signal<void()> VoidSignalVoid;
45 typedef Signal<void(float)> VoidSignalFloat;
47 typedef Signal<float()> FloatSignalVoid;
48 typedef Signal<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
73 TestConnectionTracker()
78 struct VoidFunctorVoid
82 ++mTotalInstanceCount;
83 ++mCurrentInstanceCount;
86 VoidFunctorVoid(const VoidFunctorVoid& copyMe)
88 ++mTotalInstanceCount;
89 ++mCurrentInstanceCount;
94 --mCurrentInstanceCount;
102 static int mTotalInstanceCount;
103 static int mCurrentInstanceCount;
104 static int mCallbackCount;
107 struct VoidFunctorFloat
109 VoidFunctorFloat(float* lastReceivedValue)
110 : mLastReceivedValue(lastReceivedValue)
112 ++mTotalInstanceCount;
113 ++mCurrentInstanceCount;
116 VoidFunctorFloat(const VoidFunctorFloat& copyMe)
117 : mLastReceivedValue(copyMe.mLastReceivedValue)
119 ++mTotalInstanceCount;
120 ++mCurrentInstanceCount;
125 --mCurrentInstanceCount;
128 void operator()(float value)
132 if(mLastReceivedValue)
134 *mLastReceivedValue = value;
138 float* mLastReceivedValue;
140 static int mTotalInstanceCount;
141 static int mCurrentInstanceCount;
142 static int mCallbackCount;
145 struct FloatFunctorVoid
147 static float DEFAULT_RETURN_VALUE;
151 ++mTotalInstanceCount;
152 ++mCurrentInstanceCount;
155 FloatFunctorVoid(const FloatFunctorVoid& copyMe)
157 ++mTotalInstanceCount;
158 ++mCurrentInstanceCount;
163 --mCurrentInstanceCount;
170 return DEFAULT_RETURN_VALUE;
173 static int mTotalInstanceCount;
174 static int mCurrentInstanceCount;
175 static int mCallbackCount;
178 float FloatFunctorVoid::DEFAULT_RETURN_VALUE = 5.0f;
180 struct FloatFunctorFloat
183 : mLastReceivedValue()
185 ++mTotalInstanceCount;
186 ++mCurrentInstanceCount;
189 FloatFunctorFloat(const FloatFunctorFloat& copyMe)
190 : mLastReceivedValue(copyMe.mLastReceivedValue)
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;
252 int UtcDaliSignalFunctorsEmptyCheck(void)
254 // Test that Empty() check works before & after signal connection
256 ResetFunctorCounts();
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);
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);
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);
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);
290 int UtcDaliSignalFunctorsEmit(void)
292 // Test basic signal emission for each functor type
294 ResetFunctorCounts();
299 TestConnectionTracker tracker;
301 DALI_TEST_EQUALS(VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION);
302 DALI_TEST_EQUALS(VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION);
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);
309 signals.mVoidSignalVoid.Emit();
310 DALI_TEST_EQUALS(VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION);
312 // Test double emission
313 signals.mVoidSignalVoid.Emit();
314 DALI_TEST_EQUALS(VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION);
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();
323 TestConnectionTracker tracker;
324 float lastReceivedValue(0.0f);
326 DALI_TEST_EQUALS(VoidFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION);
327 DALI_TEST_EQUALS(VoidFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION);
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);
334 signals.mVoidSignalFloat.Emit(3.5f);
335 DALI_TEST_EQUALS(VoidFunctorFloat::mCallbackCount, 1, TEST_LOCATION);
336 DALI_TEST_EQUALS(lastReceivedValue, 3.5f, TEST_LOCATION);
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);
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();
351 int UtcDaliSignalFunctorsEmitReturn(void)
353 // Test signals with return values
355 ResetFunctorCounts();
360 TestConnectionTracker tracker;
362 DALI_TEST_EQUALS(FloatFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION);
363 DALI_TEST_EQUALS(FloatFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION);
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);
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);
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);
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();
386 TestConnectionTracker tracker;
388 DALI_TEST_EQUALS(FloatFunctorFloat::mTotalInstanceCount, 0, TEST_LOCATION);
389 DALI_TEST_EQUALS(FloatFunctorFloat::mCurrentInstanceCount, 0, TEST_LOCATION);
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);
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);
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);
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();
413 int UtcDaliSignalFunctorsDisconnectBeforeEmit(void)
415 // Test explicit disconnect using ConnectionTracker
417 ResetFunctorCounts();
422 TestConnectionTracker tracker;
424 DALI_TEST_EQUALS(VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION);
425 DALI_TEST_EQUALS(VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION);
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);
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);
435 signals.mVoidSignalVoid.Emit();
436 DALI_TEST_EQUALS(VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION);
438 // Test double emission
439 signals.mVoidSignalVoid.Emit();
440 DALI_TEST_EQUALS(VoidFunctorVoid::mCallbackCount, 0, TEST_LOCATION);
445 int UtcDaliSignalFunctorsDestroySignal(void)
447 // Test destruction of signal before slot
449 ResetFunctorCounts();
451 TestConnectionTracker tracker;
456 DALI_TEST_EQUALS(VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION);
457 DALI_TEST_EQUALS(VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION);
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);
463 signals.mVoidSignalVoid.Emit();
464 DALI_TEST_EQUALS(VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION);
466 DALI_TEST_EQUALS(tracker.GetConnectionCount(), 1u, TEST_LOCATION);
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);
474 DALI_TEST_EQUALS(tracker.GetConnectionCount(), 0u, TEST_LOCATION);
478 int UtcDaliSignalConnectVoidFunctor(void)
480 // Test connecting a functor using the VoidFunctor wrapper
482 ResetFunctorCounts();
487 TestConnectionTracker tracker;
489 DALI_TEST_EQUALS(VoidFunctorVoid::mTotalInstanceCount, 0, TEST_LOCATION);
490 DALI_TEST_EQUALS(VoidFunctorVoid::mCurrentInstanceCount, 0, TEST_LOCATION);
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);
497 signals.mVoidSignalVoid.Emit();
498 DALI_TEST_EQUALS(VoidFunctorVoid::mCallbackCount, 1, TEST_LOCATION);
500 // Test double emission
501 signals.mVoidSignalVoid.Emit();
502 DALI_TEST_EQUALS(VoidFunctorVoid::mCallbackCount, 2, TEST_LOCATION);
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();