Revert "[Tizen] Appendix log for ttrace + Print keycode and timestamp"
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-FrameCallbackInterface.cpp
1 /*
2  * Copyright (c) 2023 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 #include <dali-test-suite-utils.h>
19 #include <dali/devel-api/actors/actor-devel.h>
20 #include <dali/devel-api/common/map-wrapper.h>
21 #include <dali/devel-api/common/stage-devel.h>
22 #include <dali/devel-api/update/frame-callback-interface.h>
23 #include <dali/devel-api/update/update-proxy.h>
24 #include <dali/public-api/dali-core.h>
25 #include <stdlib.h>
26
27 #include <iostream>
28
29 using namespace Dali;
30
31 void utc_dali_frame_callback_interface_startup(void)
32 {
33   test_return_value = TET_UNDEF;
34 }
35
36 void utc_dali_frame_callback_interface_cleanup(void)
37 {
38   test_return_value = TET_PASS;
39 }
40
41 ///////////////////////////////////////////////////////////////////////////////
42 namespace
43 {
44 class FrameCallbackBasic : public FrameCallbackInterface
45 {
46 public:
47   FrameCallbackBasic() = default;
48
49   virtual void Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds)
50   {
51     mCalled = true;
52   }
53
54   virtual void Reset()
55   {
56     mCalled = false;
57   }
58
59   bool mCalled{false};
60 };
61
62 class FrameCallbackOneActor : public FrameCallbackBasic
63 {
64 public:
65   FrameCallbackOneActor(unsigned int actorId)
66   : mActorId(actorId)
67   {
68   }
69
70   virtual void Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds) override
71   {
72     FrameCallbackBasic::Update(updateProxy, elapsedSeconds);
73     updateProxy.GetPosition(mActorId, mPositionGetPositionCall);
74     updateProxy.GetPositionAndSize(mActorId, mPositionGetPositionAndSizeCall, mSizeGetPositionAndSizeCall);
75     updateProxy.GetSize(mActorId, mSizeGetSizeCall);
76     updateProxy.GetOrientation(mActorId, mOrientation);
77     updateProxy.GetColor(mActorId, mColor);
78     updateProxy.GetScale(mActorId, mScale);
79
80     updateProxy.GetWorldPositionScaleAndSize(mActorId, mWorldPosition, mWorldScale, mSizeGetWorldPositionAndSizeCall);
81     updateProxy.GetWorldTransformAndSize(mActorId, mWorldTransformPosition, mWorldTransformScale, mWorldTransformOrientation, mSizeGetWorldTransform);
82   }
83
84   const unsigned int mActorId;
85
86   Vector3    mPositionGetPositionCall;
87   Vector3    mPositionGetPositionAndSizeCall;
88   Vector3    mSizeGetSizeCall;
89   Vector3    mSizeGetPositionAndSizeCall;
90   Vector4    mColor;
91   Vector3    mScale;
92   Quaternion mOrientation;
93
94   Vector3 mWorldPosition;
95   Vector3 mWorldScale;
96   Vector3 mSizeGetWorldPositionAndSizeCall;
97
98   Vector3    mWorldTransformPosition;
99   Vector3    mWorldTransformScale;
100   Quaternion mWorldTransformOrientation;
101   Vector3    mSizeGetWorldTransform;
102 };
103
104 class FrameCallbackSetter : public FrameCallbackBasic
105 {
106 public:
107   FrameCallbackSetter(
108     unsigned int      actorId,
109     const Vector3&    sizeToSet,
110     const Vector3&    positionToSet,
111     const Vector4&    colorToSet,
112     const Vector3&    scaleToSet,
113     const Quaternion& orientationToSet)
114   : mActorId(actorId),
115     mSizeToSet(sizeToSet),
116     mPositionToSet(positionToSet),
117     mColorToSet(colorToSet),
118     mScaleToSet(scaleToSet),
119     mOrientationToSet(orientationToSet)
120   {
121   }
122
123   virtual void Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds) override
124   {
125     Vector3 size;
126     FrameCallbackBasic::Update(updateProxy, elapsedSeconds);
127     updateProxy.SetSize(mActorId, mSizeToSet);
128     updateProxy.SetPosition(mActorId, mPositionToSet);
129     updateProxy.SetOrientation(mActorId, mOrientationToSet);
130     updateProxy.SetColor(mActorId, mColorToSet);
131     updateProxy.SetScale(mActorId, mScaleToSet);
132     updateProxy.GetSize(mActorId, mSizeAfterSetting);
133     updateProxy.GetPosition(mActorId, mPositionAfterSetting);
134     updateProxy.GetColor(mActorId, mColorAfterSetting);
135     updateProxy.GetScale(mActorId, mScaleAfterSetting);
136     updateProxy.GetOrientation(mActorId, mOrientationAfterSetting);
137   }
138
139   const unsigned int mActorId;
140   const Vector3&     mSizeToSet;
141   const Vector3&     mPositionToSet;
142   const Vector4&     mColorToSet;
143   const Vector3&     mScaleToSet;
144   const Quaternion&  mOrientationToSet;
145
146   Vector3    mSizeAfterSetting;
147   Vector3    mPositionAfterSetting;
148   Vector4    mColorAfterSetting;
149   Vector3    mScaleAfterSetting;
150   Quaternion mOrientationAfterSetting;
151 };
152
153 class FrameCallbackBaker : public FrameCallbackBasic
154 {
155 public:
156   FrameCallbackBaker(
157     unsigned int      actorId,
158     const Vector3&    sizeToSet,
159     const Vector3&    positionToSet,
160     const Vector4&    colorToSet,
161     const Vector3&    scaleToSet,
162     const Quaternion& orientationToSet)
163   : mActorId(actorId),
164     mSizeToSet(sizeToSet),
165     mPositionToSet(positionToSet),
166     mColorToSet(colorToSet),
167     mScaleToSet(scaleToSet),
168     mOrientationToSet(orientationToSet)
169   {
170   }
171
172   virtual void Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds) override
173   {
174     Vector3 size;
175     FrameCallbackBasic::Update(updateProxy, elapsedSeconds);
176     updateProxy.BakeSize(mActorId, mSizeToSet);
177     updateProxy.BakePosition(mActorId, mPositionToSet);
178     updateProxy.BakeColor(mActorId, mColorToSet);
179     updateProxy.BakeScale(mActorId, mScaleToSet);
180     updateProxy.BakeOrientation(mActorId, mOrientationToSet);
181     updateProxy.GetSize(mActorId, mSizeAfterSetting);
182     updateProxy.GetPosition(mActorId, mPositionAfterSetting);
183     updateProxy.GetColor(mActorId, mColorAfterSetting);
184     updateProxy.GetScale(mActorId, mScaleAfterSetting);
185     updateProxy.GetOrientation(mActorId, mOrientationAfterSetting);
186   }
187
188   const unsigned int mActorId;
189   const Vector3&     mSizeToSet;
190   const Vector3&     mPositionToSet;
191   const Vector4&     mColorToSet;
192   const Vector3&     mScaleToSet;
193   const Quaternion&  mOrientationToSet;
194
195   Vector3    mSizeAfterSetting;
196   Vector3    mPositionAfterSetting;
197   Vector4    mColorAfterSetting;
198   Vector3    mScaleAfterSetting;
199   Quaternion mOrientationAfterSetting;
200 };
201
202 class FrameCallbackMultipleActors : public FrameCallbackBasic
203 {
204 public:
205   FrameCallbackMultipleActors()
206   {
207   }
208
209   virtual void Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds) override
210   {
211     FrameCallbackBasic::Update(updateProxy, elapsedSeconds);
212     for(auto&& i : mActorIds)
213     {
214       Vector3 position;
215       Vector3 size;
216       updateProxy.GetPositionAndSize(i, position, size);
217       mPositions[i] = position;
218       mSizes[i]     = size;
219     }
220   }
221
222   Vector<unsigned int> mActorIds;
223
224   std::map<unsigned int, Vector3> mPositions;
225   std::map<unsigned int, Vector3> mSizes;
226 };
227
228 class FrameCallbackActorIdCheck : public FrameCallbackBasic
229 {
230 public:
231   FrameCallbackActorIdCheck(unsigned int actorId)
232   : mActorId(actorId)
233   {
234   }
235
236   virtual void Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds) override
237   {
238     FrameCallbackBasic::Update(updateProxy, elapsedSeconds);
239     Vector3    vec3;
240     Vector4    vec4;
241     Quaternion quat;
242
243     mGetSizeCallSuccess                      = updateProxy.GetSize(mActorId, vec3);
244     mGetPositionCallSuccess                  = updateProxy.GetPosition(mActorId, vec3);
245     mGetColorCallSuccess                     = updateProxy.GetColor(mActorId, vec4);
246     mGetScaleCallSuccess                     = updateProxy.GetScale(mActorId, vec3);
247     mGetPositionAndSizeCallSuccess           = updateProxy.GetPositionAndSize(mActorId, vec3, vec3);
248     mGetWorldPositionScaleAndSizeCallSuccess = updateProxy.GetWorldPositionScaleAndSize(mActorId, vec3, vec3, vec3);
249     mSetSizeCallSuccess                      = updateProxy.SetSize(mActorId, vec3);
250     mSetPositionCallSuccess                  = updateProxy.SetPosition(mActorId, vec3);
251     mSetColorCallSuccess                     = updateProxy.SetColor(mActorId, vec4);
252     mSetScaleCallSuccess                     = updateProxy.SetScale(mActorId, vec3);
253     mBakeSizeCallSuccess                     = updateProxy.BakeSize(mActorId, vec3);
254     mBakePositionCallSuccess                 = updateProxy.BakePosition(mActorId, vec3);
255     mBakeColorCallSuccess                    = updateProxy.BakeColor(mActorId, vec4);
256     mBakeScaleCallSuccess                    = updateProxy.BakeScale(mActorId, vec3);
257
258     mGetOrientationCallSuccess    = updateProxy.GetOrientation(mActorId, quat);
259     mSetOrientationCallSuccess    = updateProxy.SetOrientation(mActorId, quat);
260     mBakeOrientationCallSuccess   = updateProxy.BakeOrientation(mActorId, quat);
261     mGetWorldTransformCallSuccess = updateProxy.GetWorldTransformAndSize(mActorId, vec3, vec3, quat, vec3);
262   }
263
264   virtual void Reset() override
265   {
266     // Up-call
267     FrameCallbackBasic::Reset();
268
269     mGetSizeCallSuccess                      = false;
270     mGetPositionCallSuccess                  = false;
271     mGetColorCallSuccess                     = false;
272     mGetScaleCallSuccess                     = false;
273     mGetPositionAndSizeCallSuccess           = false;
274     mGetWorldPositionScaleAndSizeCallSuccess = false;
275     mSetSizeCallSuccess                      = false;
276     mSetPositionCallSuccess                  = false;
277     mSetColorCallSuccess                     = false;
278     mSetScaleCallSuccess                     = false;
279     mBakeSizeCallSuccess                     = false;
280     mBakePositionCallSuccess                 = false;
281     mBakeColorCallSuccess                    = false;
282     mBakeScaleCallSuccess                    = false;
283
284     mSetOrientationCallSuccess  = false;
285     mGetOrientationCallSuccess  = false;
286     mBakeOrientationCallSuccess = false;
287
288     mGetWorldTransformCallSuccess = false;
289   }
290
291   const uint32_t mActorId;
292
293   bool mGetSizeCallSuccess{false};
294   bool mGetPositionCallSuccess{false};
295   bool mGetOrientationCallSuccess{false};
296   bool mGetColorCallSuccess{false};
297   bool mGetScaleCallSuccess{false};
298   bool mGetPositionAndSizeCallSuccess{false};
299   bool mGetWorldPositionScaleAndSizeCallSuccess{false};
300   bool mSetSizeCallSuccess{false};
301   bool mSetPositionCallSuccess{false};
302   bool mSetColorCallSuccess{false};
303   bool mSetScaleCallSuccess{false};
304   bool mSetOrientationCallSuccess{false};
305   bool mBakeSizeCallSuccess{false};
306   bool mBakePositionCallSuccess{false};
307   bool mBakeColorCallSuccess{false};
308   bool mBakeScaleCallSuccess{false};
309   bool mBakeOrientationCallSuccess{false};
310   bool mGetWorldTransformCallSuccess{false};
311 };
312
313 } // namespace
314
315 ///////////////////////////////////////////////////////////////////////////////
316
317 int UtcDaliFrameCallbackCheckInstallationAndRemoval(void)
318 {
319   // Basic test to check that the frame-callback can be installed and removed correctly
320
321   TestApplication application;
322
323   FrameCallbackBasic frameCallback;
324
325   Stage stage = Stage::GetCurrent();
326   DevelStage::AddFrameCallback(stage, frameCallback, stage.GetRootLayer());
327
328   application.SendNotification();
329   application.Render();
330
331   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
332
333   frameCallback.mCalled = false;
334
335   DevelStage::RemoveFrameCallback(stage, frameCallback);
336
337   application.SendNotification();
338   application.Render();
339
340   DALI_TEST_EQUALS(frameCallback.mCalled, false, TEST_LOCATION);
341
342   END_TEST;
343 }
344
345 int UtcDaliFrameCallbackGetters(void)
346 {
347   // Test to see that the Getters all return the expected values
348
349   TestApplication application;
350
351   Vector2    actorSize(200, 300);
352   Vector4    color(0.5f, 0.6f, 0.7f, 0.8f);
353   Vector3    position(10.0f, 20.0f, 30.0f);
354   Vector3    scale(2.0f, 4.0f, 6.0f);
355   Quaternion orientation; //(Radian(Math::PI_2), Vector3::ZAXIS);
356   Actor      actor = Actor::New();
357   actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
358   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
359   actor.SetProperty(Actor::Property::SIZE, actorSize);
360   actor.SetProperty(Actor::Property::COLOR, color);
361   actor.SetProperty(Actor::Property::POSITION, position);
362   actor.SetProperty(Actor::Property::SCALE, scale);
363   actor.SetProperty(Actor::Property::ORIENTATION, orientation);
364
365   Stage stage = Stage::GetCurrent();
366   stage.Add(actor);
367
368   FrameCallbackOneActor frameCallback(actor.GetProperty<int>(Actor::Property::ID));
369   DevelStage::AddFrameCallback(stage, frameCallback, stage.GetRootLayer());
370
371   application.SendNotification();
372   application.Render();
373
374   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
375   DALI_TEST_EQUALS(frameCallback.mSizeGetSizeCall, Vector3(actorSize.width, actorSize.height, 0.0f), TEST_LOCATION);
376   DALI_TEST_EQUALS(frameCallback.mPositionGetPositionCall, position, TEST_LOCATION);
377   DALI_TEST_EQUALS(frameCallback.mPositionGetPositionAndSizeCall, position, TEST_LOCATION);
378   DALI_TEST_EQUALS(frameCallback.mSizeGetPositionAndSizeCall, Vector3(actorSize.width, actorSize.height, 0.0f), TEST_LOCATION);
379
380   DALI_TEST_EQUALS(frameCallback.mColor, color, TEST_LOCATION);
381   DALI_TEST_EQUALS(frameCallback.mScale, scale, TEST_LOCATION);
382   DALI_TEST_EQUALS(frameCallback.mOrientation, orientation, TEST_LOCATION);
383
384   frameCallback.Reset();
385
386   application.SendNotification();
387   application.Render();
388
389   Vector3    worldPosition, worldScale;
390   Quaternion worldRotation;
391   Matrix     worldTransform = DevelActor::GetWorldTransform(actor);
392   worldTransform.GetTransformComponents(worldPosition, worldRotation, worldScale);
393
394   // World position and scale values are updated after FrameCallbackInterface::Update()
395   // So test them after the second rendering
396   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
397
398   DALI_TEST_EQUALS(frameCallback.mSizeGetWorldTransform, Vector3(actorSize.width, actorSize.height, 0.0f), TEST_LOCATION);
399   DALI_TEST_EQUALS(frameCallback.mWorldPosition, worldPosition, TEST_LOCATION);
400   DALI_TEST_EQUALS(frameCallback.mWorldScale, worldScale, TEST_LOCATION);
401   DALI_TEST_EQUALS(frameCallback.mSizeGetWorldPositionAndSizeCall, Vector3(actorSize), TEST_LOCATION);
402   DALI_TEST_EQUALS(frameCallback.mWorldTransformPosition, worldPosition, TEST_LOCATION);
403   DALI_TEST_EQUALS(frameCallback.mWorldTransformScale, worldScale, TEST_LOCATION);
404   DALI_TEST_EQUALS(frameCallback.mWorldTransformOrientation, worldRotation, TEST_LOCATION);
405
406   END_TEST;
407 }
408
409 int UtcDaliFrameCallbackSetters(void)
410 {
411   // Test to see that the setters set the values appropriately
412
413   TestApplication application;
414   Vector2         actorSize(200, 300);
415
416   Actor actor = Actor::New();
417   actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
418   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
419   actor.SetProperty(Actor::Property::SIZE, actorSize);
420
421   Stage stage = Stage::GetCurrent();
422   stage.Add(actor);
423
424   Vector3    sizeToSet(1.0f, 2.0f, 3.0f);
425   Vector3    positionToSet(10.0f, 20.0f, 30.0f);
426   Vector4    colorToSet(Color::MAGENTA);
427   Vector3    scaleToSet(1.0f, 3.0f, 5.0f);
428   Quaternion orientationToSet(Radian(Math::PI_2), Vector3::ZAXIS);
429
430   FrameCallbackSetter frameCallback(actor.GetProperty<int>(Actor::Property::ID), sizeToSet, positionToSet, colorToSet, scaleToSet, orientationToSet);
431   DevelStage::AddFrameCallback(stage, frameCallback, stage.GetRootLayer());
432
433   application.SendNotification();
434   application.Render();
435
436   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
437   DALI_TEST_EQUALS(frameCallback.mSizeAfterSetting, sizeToSet, TEST_LOCATION);
438   DALI_TEST_EQUALS(frameCallback.mPositionAfterSetting, positionToSet, TEST_LOCATION);
439   DALI_TEST_EQUALS(frameCallback.mColorAfterSetting, colorToSet, TEST_LOCATION);
440   DALI_TEST_EQUALS(frameCallback.mScaleAfterSetting, scaleToSet, TEST_LOCATION);
441   DALI_TEST_EQUALS(frameCallback.mOrientationAfterSetting, orientationToSet, TEST_LOCATION);
442
443   // Ensure the actual actor values haven't changed as we didn't bake the values after removing the callback
444   DevelStage::RemoveFrameCallback(stage, frameCallback);
445
446   application.SendNotification();
447   application.Render();
448
449   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::POSITION).Get<Vector3>(), Vector3::ZERO, TEST_LOCATION);
450   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::SIZE).Get<Vector3>(), Vector3(actorSize), TEST_LOCATION);
451   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::COLOR).Get<Vector4>(), Color::WHITE, TEST_LOCATION);
452   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::SCALE).Get<Vector3>(), Vector3::ONE, TEST_LOCATION);
453   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::ORIENTATION).Get<Quaternion>(), Quaternion(Radian(0.0f), Vector3::ZAXIS), TEST_LOCATION);
454
455   // Render for a couple more frames to ensure the values are reset properly (some values are double-buffered)
456
457   application.SendNotification();
458   application.Render();
459
460   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::POSITION).Get<Vector3>(), Vector3::ZERO, TEST_LOCATION);
461   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::SIZE).Get<Vector3>(), Vector3(actorSize), TEST_LOCATION);
462   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::COLOR).Get<Vector4>(), Color::WHITE, TEST_LOCATION);
463   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::SCALE).Get<Vector3>(), Vector3::ONE, TEST_LOCATION);
464   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::ORIENTATION).Get<Quaternion>(), Quaternion(Radian(0.0f), Vector3::ZAXIS), TEST_LOCATION);
465
466   application.SendNotification();
467   application.Render();
468
469   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::POSITION).Get<Vector3>(), Vector3::ZERO, TEST_LOCATION);
470   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::SIZE).Get<Vector3>(), Vector3(actorSize), TEST_LOCATION);
471   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::COLOR).Get<Vector4>(), Color::WHITE, TEST_LOCATION);
472   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::SCALE).Get<Vector3>(), Vector3::ONE, TEST_LOCATION);
473   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::ORIENTATION).Get<Quaternion>(), Quaternion(Radian(0.0f), Vector3::ZAXIS), TEST_LOCATION);
474
475   END_TEST;
476 }
477
478 int UtcDaliFrameCallbackBake(void)
479 {
480   // Test to see that the bake methods bake the values
481
482   TestApplication application;
483   Vector2         actorSize(200, 300);
484
485   Actor actor = Actor::New();
486   actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
487   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
488   actor.SetProperty(Actor::Property::SIZE, actorSize);
489
490   Stage stage = Stage::GetCurrent();
491   stage.Add(actor);
492
493   Vector3    sizeToSet(1.0f, 2.0f, 3.0f);
494   Vector3    positionToSet(10.0f, 20.0f, 30.0f);
495   Vector4    colorToSet(Color::MAGENTA);
496   Vector3    scaleToSet(1.0f, 3.0f, 5.0f);
497   Quaternion orientationToSet(Radian(Math::PI * 0.3), Vector3::YAXIS);
498
499   FrameCallbackBaker frameCallback(actor.GetProperty<int>(Actor::Property::ID), sizeToSet, positionToSet, colorToSet, scaleToSet, orientationToSet);
500   DevelStage::AddFrameCallback(stage, frameCallback, stage.GetRootLayer());
501
502   application.SendNotification();
503   application.Render();
504
505   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
506   DALI_TEST_EQUALS(frameCallback.mSizeAfterSetting, sizeToSet, TEST_LOCATION);
507   DALI_TEST_EQUALS(frameCallback.mPositionAfterSetting, positionToSet, TEST_LOCATION);
508   DALI_TEST_EQUALS(frameCallback.mColorAfterSetting, colorToSet, TEST_LOCATION);
509   DALI_TEST_EQUALS(frameCallback.mScaleAfterSetting, scaleToSet, TEST_LOCATION);
510   DALI_TEST_EQUALS(frameCallback.mOrientationAfterSetting, orientationToSet, TEST_LOCATION);
511
512   // Ensure the new values are saved after removing the callback
513   DevelStage::RemoveFrameCallback(stage, frameCallback);
514
515   application.SendNotification();
516   application.Render();
517
518   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::POSITION).Get<Vector3>(), positionToSet, TEST_LOCATION);
519   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::SIZE).Get<Vector3>(), sizeToSet, TEST_LOCATION);
520   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::COLOR).Get<Vector4>(), colorToSet, TEST_LOCATION);
521   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::SCALE).Get<Vector3>(), scaleToSet, TEST_LOCATION);
522   DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::ORIENTATION).Get<Quaternion>(), orientationToSet, TEST_LOCATION);
523
524   END_TEST;
525 }
526
527 int UtcDaliFrameCallbackMultipleActors(void)
528 {
529   /**
530    * Test to check that the frame callback behaves appropriately with multiple actors
531    *
532    * Tree:
533    *              root-layer
534    *              /        \
535    *             /          \
536    *            /            \
537    *           /              \
538    *        actorA           actorE
539    *         / \              / \
540    *        /   \            /   \
541    *    actorB  actorD   actorF actorG
542    *      /                        \
543    *   actorC                     actorH
544    *
545    *  Screen positions (with minor alterations due to local position):
546    *  -----------------------
547    *  |actorA|actorD        |
548    *  |      actorB         |
549    *  |      actorC         |
550    *  |                     |
551    *  |                     |
552    *  |                     |
553    *  |                     |
554    *  |                     |
555    *  |actorF       actorH  |
556    *  |actorE|actorG        |
557    *  -----------------------
558    */
559
560   TestApplication application;
561   Stage           stage = Stage::GetCurrent();
562
563   std::map<char, Vector3> sizes;
564   sizes['A'] = Vector3(50.0f, 50.0f, 0.0f);
565   sizes['B'] = Vector3(100.0f, 100.0f, 0.0f);
566   sizes['C'] = Vector3(150.0f, 150.0f, 0.0f);
567   sizes['D'] = Vector3(200.0f, 200.0f, 0.0f);
568   sizes['E'] = Vector3(250.0f, 250.0f, 0.0f);
569   sizes['F'] = Vector3(300.0f, 300.0f, 0.0f);
570   sizes['G'] = Vector3(350.0f, 350.0f, 0.0f);
571   sizes['H'] = Vector3(400.0f, 350.0f, 0.0f);
572
573   std::map<char, Vector3> positions;
574   positions['A'] = Vector3(0.0f, 1.0f, 2.0f);
575   positions['B'] = Vector3(2.0f, 3.0f, 4.0f);
576   positions['C'] = Vector3(5.0f, 6.0f, 7.0f);
577   positions['D'] = Vector3(8.0f, 9.0f, 10.0f);
578   positions['E'] = Vector3(11.0f, 12.0f, 13.0f);
579   positions['F'] = Vector3(14.0f, 15.0f, 16.0f);
580   positions['G'] = Vector3(17.0f, 18.0f, 19.0f);
581   positions['H'] = Vector3(20.0f, 21.0f, 22.0f);
582
583   Actor actorA = Actor::New();
584   actorA.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
585   actorA.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
586   actorA.SetProperty(Actor::Property::SIZE, sizes['A']);
587   actorA.SetProperty(Actor::Property::POSITION, positions['A']);
588   stage.Add(actorA);
589
590   Actor actorB = Actor::New();
591   actorB.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_RIGHT);
592   actorB.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
593   actorB.SetProperty(Actor::Property::SIZE, sizes['B']);
594   actorB.SetProperty(Actor::Property::POSITION, positions['B']);
595   actorA.Add(actorB);
596
597   Actor actorC = Actor::New();
598   actorC.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
599   actorC.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
600   actorC.SetProperty(Actor::Property::SIZE, sizes['C']);
601   actorC.SetProperty(Actor::Property::POSITION, positions['C']);
602   actorB.Add(actorC);
603
604   Actor actorD = Actor::New();
605   actorD.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER_RIGHT);
606   actorD.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER_LEFT);
607   actorD.SetProperty(Actor::Property::SIZE, sizes['D']);
608   actorD.SetProperty(Actor::Property::POSITION, positions['D']);
609   actorA.Add(actorD);
610
611   Actor actorE = Actor::New();
612   actorE.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_LEFT);
613   actorE.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_LEFT);
614   actorE.SetProperty(Actor::Property::SIZE, sizes['E']);
615   actorE.SetProperty(Actor::Property::POSITION, positions['E']);
616   stage.Add(actorE);
617
618   Actor actorF = Actor::New();
619   actorF.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
620   actorF.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
621   actorF.SetProperty(Actor::Property::SIZE, sizes['F']);
622   actorF.SetProperty(Actor::Property::POSITION, positions['F']);
623   actorE.Add(actorF);
624
625   Actor actorG = Actor::New();
626   actorG.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER_RIGHT);
627   actorG.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER_LEFT);
628   actorG.SetProperty(Actor::Property::SIZE, sizes['G']);
629   actorG.SetProperty(Actor::Property::POSITION, positions['G']);
630   actorE.Add(actorG);
631
632   Actor actorH = Actor::New();
633   actorH.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT);
634   actorH.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_LEFT);
635   actorH.SetProperty(Actor::Property::SIZE, sizes['H']);
636   actorH.SetProperty(Actor::Property::POSITION, positions['H']);
637   actorG.Add(actorH);
638
639   std::map<char, unsigned int> actorIds;
640   actorIds['A'] = actorA.GetProperty<int>(Actor::Property::ID);
641   actorIds['B'] = actorB.GetProperty<int>(Actor::Property::ID);
642   actorIds['C'] = actorC.GetProperty<int>(Actor::Property::ID);
643   actorIds['D'] = actorD.GetProperty<int>(Actor::Property::ID);
644   actorIds['E'] = actorE.GetProperty<int>(Actor::Property::ID);
645   actorIds['F'] = actorF.GetProperty<int>(Actor::Property::ID);
646   actorIds['G'] = actorG.GetProperty<int>(Actor::Property::ID);
647   actorIds['H'] = actorH.GetProperty<int>(Actor::Property::ID);
648
649   FrameCallbackMultipleActors frameCallback;
650   for(auto&& i : actorIds)
651   {
652     frameCallback.mActorIds.PushBack(i.second);
653   }
654
655   DevelStage::AddFrameCallback(stage, frameCallback, stage.GetRootLayer());
656
657   application.SendNotification();
658   application.Render();
659
660   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
661
662   for(char i = 'A'; i <= 'H'; ++i)
663   {
664     DALI_TEST_EQUALS(frameCallback.mPositions[actorIds[i]], positions[i], TEST_LOCATION);
665     DALI_TEST_EQUALS(frameCallback.mSizes[actorIds[i]], sizes[i], TEST_LOCATION);
666   }
667
668   // Render again to make sure it still gets called and gives the correct values (in case any optimisations break this)
669   frameCallback.mCalled = false;
670
671   application.SendNotification();
672   application.Render();
673
674   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
675
676   for(char i = 'A'; i <= 'H'; ++i)
677   {
678     DALI_TEST_EQUALS(frameCallback.mPositions[actorIds[i]], positions[i], TEST_LOCATION);
679     DALI_TEST_EQUALS(frameCallback.mSizes[actorIds[i]], sizes[i], TEST_LOCATION);
680   }
681
682   END_TEST;
683 }
684
685 int UtcDaliFrameCallbackCheckActorNotAdded(void)
686 {
687   TestApplication application;
688
689   Actor actor = Actor::New();
690   actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
691   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
692   actor.SetProperty(Actor::Property::SIZE, Vector2(200, 300));
693
694   Stage                 stage = Stage::GetCurrent();
695   FrameCallbackOneActor frameCallback(actor.GetProperty<int>(Actor::Property::ID));
696   DevelStage::AddFrameCallback(stage, frameCallback, stage.GetRootLayer());
697
698   application.SendNotification();
699   application.Render();
700
701   // All should be default constructed objects
702   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
703   DALI_TEST_EQUALS(frameCallback.mPositionGetPositionCall, Vector3::ZERO, TEST_LOCATION);
704   DALI_TEST_EQUALS(frameCallback.mWorldPosition, Vector3::ZERO, TEST_LOCATION);
705   DALI_TEST_EQUALS(frameCallback.mSizeGetSizeCall, Vector3::ZERO, TEST_LOCATION);
706   DALI_TEST_EQUALS(frameCallback.mColor, Vector4::ZERO, TEST_LOCATION);
707   DALI_TEST_EQUALS(frameCallback.mScale, Vector3::ZERO, TEST_LOCATION);
708   DALI_TEST_EQUALS(frameCallback.mWorldScale, Vector3::ZERO, TEST_LOCATION);
709   DALI_TEST_EQUALS(frameCallback.mOrientation, Quaternion::IDENTITY, TEST_LOCATION);
710
711   END_TEST;
712 }
713
714 int UtcDaliFrameCallbackInvalidActorId(void)
715 {
716   // Test to ensure that there are no issues when trying to use the update-proxy methods with an invalid actor ID.
717
718   TestApplication application;
719   Stage           stage = Stage::GetCurrent();
720
721   FrameCallbackActorIdCheck frameCallback(10000);
722   DevelStage::AddFrameCallback(stage, frameCallback, stage.GetRootLayer());
723
724   application.SendNotification();
725   application.Render();
726
727   // Invalid Actor ID so all the methods should not return successfully.
728
729   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
730   DALI_TEST_EQUALS(frameCallback.mGetSizeCallSuccess, false, TEST_LOCATION);
731   DALI_TEST_EQUALS(frameCallback.mGetPositionCallSuccess, false, TEST_LOCATION);
732   DALI_TEST_EQUALS(frameCallback.mGetColorCallSuccess, false, TEST_LOCATION);
733   DALI_TEST_EQUALS(frameCallback.mGetScaleCallSuccess, false, TEST_LOCATION);
734   DALI_TEST_EQUALS(frameCallback.mGetPositionAndSizeCallSuccess, false, TEST_LOCATION);
735   DALI_TEST_EQUALS(frameCallback.mGetWorldPositionScaleAndSizeCallSuccess, false, TEST_LOCATION);
736   DALI_TEST_EQUALS(frameCallback.mSetSizeCallSuccess, false, TEST_LOCATION);
737   DALI_TEST_EQUALS(frameCallback.mSetPositionCallSuccess, false, TEST_LOCATION);
738   DALI_TEST_EQUALS(frameCallback.mSetColorCallSuccess, false, TEST_LOCATION);
739   DALI_TEST_EQUALS(frameCallback.mSetScaleCallSuccess, false, TEST_LOCATION);
740   DALI_TEST_EQUALS(frameCallback.mBakeSizeCallSuccess, false, TEST_LOCATION);
741   DALI_TEST_EQUALS(frameCallback.mBakePositionCallSuccess, false, TEST_LOCATION);
742   DALI_TEST_EQUALS(frameCallback.mBakeColorCallSuccess, false, TEST_LOCATION);
743   DALI_TEST_EQUALS(frameCallback.mBakeScaleCallSuccess, false, TEST_LOCATION);
744
745   DALI_TEST_EQUALS(frameCallback.mGetOrientationCallSuccess, false, TEST_LOCATION);
746   DALI_TEST_EQUALS(frameCallback.mSetOrientationCallSuccess, false, TEST_LOCATION);
747   DALI_TEST_EQUALS(frameCallback.mBakeOrientationCallSuccess, false, TEST_LOCATION);
748
749   DALI_TEST_EQUALS(frameCallback.mGetWorldTransformCallSuccess, false, TEST_LOCATION);
750
751   END_TEST;
752 }
753
754 int UtcDaliFrameCallbackActorRemovedAndAdded(void)
755 {
756   // Test to ensure that we do not call methods on actors that have been removed on the stage
757   // and then re-start calling the required methods if that actor is re-added back to the stage
758
759   TestApplication application;
760   Stage           stage = Stage::GetCurrent();
761
762   Actor actor = Actor::New();
763   stage.Add(actor);
764
765   FrameCallbackActorIdCheck frameCallback(actor.GetProperty<int>(Actor::Property::ID));
766   DevelStage::AddFrameCallback(stage, frameCallback, stage.GetRootLayer());
767
768   application.SendNotification();
769   application.Render();
770
771   // All methods should return successfully.
772
773   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
774   DALI_TEST_EQUALS(frameCallback.mGetSizeCallSuccess, true, TEST_LOCATION);
775   DALI_TEST_EQUALS(frameCallback.mGetPositionCallSuccess, true, TEST_LOCATION);
776   DALI_TEST_EQUALS(frameCallback.mGetColorCallSuccess, true, TEST_LOCATION);
777   DALI_TEST_EQUALS(frameCallback.mGetScaleCallSuccess, true, TEST_LOCATION);
778   DALI_TEST_EQUALS(frameCallback.mGetPositionAndSizeCallSuccess, true, TEST_LOCATION);
779   DALI_TEST_EQUALS(frameCallback.mGetWorldPositionScaleAndSizeCallSuccess, true, TEST_LOCATION);
780   DALI_TEST_EQUALS(frameCallback.mSetSizeCallSuccess, true, TEST_LOCATION);
781   DALI_TEST_EQUALS(frameCallback.mSetPositionCallSuccess, true, TEST_LOCATION);
782   DALI_TEST_EQUALS(frameCallback.mSetColorCallSuccess, true, TEST_LOCATION);
783   DALI_TEST_EQUALS(frameCallback.mSetScaleCallSuccess, true, TEST_LOCATION);
784   DALI_TEST_EQUALS(frameCallback.mBakeSizeCallSuccess, true, TEST_LOCATION);
785   DALI_TEST_EQUALS(frameCallback.mBakePositionCallSuccess, true, TEST_LOCATION);
786   DALI_TEST_EQUALS(frameCallback.mBakeColorCallSuccess, true, TEST_LOCATION);
787   DALI_TEST_EQUALS(frameCallback.mBakeScaleCallSuccess, true, TEST_LOCATION);
788   DALI_TEST_EQUALS(frameCallback.mGetOrientationCallSuccess, true, TEST_LOCATION);
789   DALI_TEST_EQUALS(frameCallback.mSetOrientationCallSuccess, true, TEST_LOCATION);
790   DALI_TEST_EQUALS(frameCallback.mBakeOrientationCallSuccess, true, TEST_LOCATION);
791   DALI_TEST_EQUALS(frameCallback.mGetWorldTransformCallSuccess, true, TEST_LOCATION);
792
793   frameCallback.Reset();
794
795   // Remove the actor from stage, the methods should not return successfully.
796
797   stage.Remove(actor);
798
799   application.SendNotification();
800   application.Render();
801
802   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
803   DALI_TEST_EQUALS(frameCallback.mGetSizeCallSuccess, false, TEST_LOCATION);
804   DALI_TEST_EQUALS(frameCallback.mGetPositionCallSuccess, false, TEST_LOCATION);
805   DALI_TEST_EQUALS(frameCallback.mGetColorCallSuccess, false, TEST_LOCATION);
806   DALI_TEST_EQUALS(frameCallback.mGetScaleCallSuccess, false, TEST_LOCATION);
807   DALI_TEST_EQUALS(frameCallback.mGetPositionAndSizeCallSuccess, false, TEST_LOCATION);
808   DALI_TEST_EQUALS(frameCallback.mGetWorldPositionScaleAndSizeCallSuccess, false, TEST_LOCATION);
809   DALI_TEST_EQUALS(frameCallback.mSetSizeCallSuccess, false, TEST_LOCATION);
810   DALI_TEST_EQUALS(frameCallback.mSetPositionCallSuccess, false, TEST_LOCATION);
811   DALI_TEST_EQUALS(frameCallback.mSetColorCallSuccess, false, TEST_LOCATION);
812   DALI_TEST_EQUALS(frameCallback.mSetScaleCallSuccess, false, TEST_LOCATION);
813   DALI_TEST_EQUALS(frameCallback.mBakeSizeCallSuccess, false, TEST_LOCATION);
814   DALI_TEST_EQUALS(frameCallback.mBakePositionCallSuccess, false, TEST_LOCATION);
815   DALI_TEST_EQUALS(frameCallback.mBakeColorCallSuccess, false, TEST_LOCATION);
816   DALI_TEST_EQUALS(frameCallback.mBakeScaleCallSuccess, false, TEST_LOCATION);
817   DALI_TEST_EQUALS(frameCallback.mGetOrientationCallSuccess, false, TEST_LOCATION);
818   DALI_TEST_EQUALS(frameCallback.mSetOrientationCallSuccess, false, TEST_LOCATION);
819   DALI_TEST_EQUALS(frameCallback.mBakeOrientationCallSuccess, false, TEST_LOCATION);
820   DALI_TEST_EQUALS(frameCallback.mGetWorldTransformCallSuccess, false, TEST_LOCATION);
821
822   frameCallback.Reset();
823
824   // Re-add the actor back to the stage, all the methods should once again, return successfully.
825
826   stage.Add(actor);
827
828   application.SendNotification();
829   application.Render();
830
831   DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
832   DALI_TEST_EQUALS(frameCallback.mGetSizeCallSuccess, true, TEST_LOCATION);
833   DALI_TEST_EQUALS(frameCallback.mGetPositionCallSuccess, true, TEST_LOCATION);
834   DALI_TEST_EQUALS(frameCallback.mGetColorCallSuccess, true, TEST_LOCATION);
835   DALI_TEST_EQUALS(frameCallback.mGetScaleCallSuccess, true, TEST_LOCATION);
836   DALI_TEST_EQUALS(frameCallback.mGetPositionAndSizeCallSuccess, true, TEST_LOCATION);
837   DALI_TEST_EQUALS(frameCallback.mGetWorldPositionScaleAndSizeCallSuccess, true, TEST_LOCATION);
838   DALI_TEST_EQUALS(frameCallback.mSetSizeCallSuccess, true, TEST_LOCATION);
839   DALI_TEST_EQUALS(frameCallback.mSetPositionCallSuccess, true, TEST_LOCATION);
840   DALI_TEST_EQUALS(frameCallback.mSetColorCallSuccess, true, TEST_LOCATION);
841   DALI_TEST_EQUALS(frameCallback.mSetScaleCallSuccess, true, TEST_LOCATION);
842   DALI_TEST_EQUALS(frameCallback.mBakeSizeCallSuccess, true, TEST_LOCATION);
843   DALI_TEST_EQUALS(frameCallback.mBakePositionCallSuccess, true, TEST_LOCATION);
844   DALI_TEST_EQUALS(frameCallback.mBakeColorCallSuccess, true, TEST_LOCATION);
845   DALI_TEST_EQUALS(frameCallback.mBakeScaleCallSuccess, true, TEST_LOCATION);
846   DALI_TEST_EQUALS(frameCallback.mGetOrientationCallSuccess, true, TEST_LOCATION);
847   DALI_TEST_EQUALS(frameCallback.mSetOrientationCallSuccess, true, TEST_LOCATION);
848   DALI_TEST_EQUALS(frameCallback.mBakeOrientationCallSuccess, true, TEST_LOCATION);
849   DALI_TEST_EQUALS(frameCallback.mGetWorldTransformCallSuccess, true, TEST_LOCATION);
850
851   END_TEST;
852 }
853
854 int UtcDaliFrameCallbackMultipleCallbacks(void)
855 {
856   // Test to ensure multiple frame-callbacks work as expected
857
858   TestApplication application;
859   Stage           stage = Stage::GetCurrent();
860
861   Actor actor = Actor::New();
862   stage.Add(actor);
863
864   FrameCallbackBasic frameCallback1;
865   FrameCallbackBasic frameCallback2;
866   DevelStage::AddFrameCallback(stage, frameCallback1, stage.GetRootLayer());
867   DevelStage::AddFrameCallback(stage, frameCallback2, stage.GetRootLayer());
868
869   application.SendNotification();
870   application.Render();
871
872   DALI_TEST_EQUALS(frameCallback1.mCalled, true, TEST_LOCATION);
873   DALI_TEST_EQUALS(frameCallback2.mCalled, true, TEST_LOCATION);
874   frameCallback1.Reset();
875   frameCallback2.Reset();
876
877   // Remove the second frame-callback, only the first should be called
878
879   DevelStage::RemoveFrameCallback(stage, frameCallback2);
880
881   application.SendNotification();
882   application.Render();
883
884   DALI_TEST_EQUALS(frameCallback1.mCalled, true, TEST_LOCATION);
885   DALI_TEST_EQUALS(frameCallback2.mCalled, false, TEST_LOCATION);
886   frameCallback1.Reset();
887   frameCallback2.Reset();
888
889   // Re-add the second frame-callback and remove the first, only the second should be called
890
891   DevelStage::AddFrameCallback(stage, frameCallback2, stage.GetRootLayer());
892   DevelStage::RemoveFrameCallback(stage, frameCallback1);
893
894   application.SendNotification();
895   application.Render();
896
897   DALI_TEST_EQUALS(frameCallback1.mCalled, false, TEST_LOCATION);
898   DALI_TEST_EQUALS(frameCallback2.mCalled, true, TEST_LOCATION);
899   frameCallback1.Reset();
900   frameCallback2.Reset();
901
902   // Attempt removal of the first frame-callback again, should be a no-op and yield the exact same results as the last run
903   DevelStage::RemoveFrameCallback(stage, frameCallback1);
904
905   application.SendNotification();
906   application.Render();
907
908   DALI_TEST_EQUALS(frameCallback1.mCalled, false, TEST_LOCATION);
909   DALI_TEST_EQUALS(frameCallback2.mCalled, true, TEST_LOCATION);
910   frameCallback1.Reset();
911   frameCallback2.Reset();
912
913   // Remove the second frame-callback as well, neither should be called
914   DevelStage::RemoveFrameCallback(stage, frameCallback2);
915
916   application.SendNotification();
917   application.Render();
918
919   DALI_TEST_EQUALS(frameCallback1.mCalled, false, TEST_LOCATION);
920   DALI_TEST_EQUALS(frameCallback2.mCalled, false, TEST_LOCATION);
921
922   END_TEST;
923 }
924
925 int UtcDaliFrameCallbackActorDestroyed(void)
926 {
927   // Test to ensure that the frame-callback behaves gracefully if the connected root-actor is destroyed
928
929   TestApplication application;
930   Stage           stage = Stage::GetCurrent();
931
932   Actor actor = Actor::New();
933   stage.Add(actor);
934
935   FrameCallbackBasic frameCallback1;
936   FrameCallbackBasic frameCallback2;
937   DevelStage::AddFrameCallback(stage, frameCallback1, actor);
938   DevelStage::AddFrameCallback(stage, frameCallback2, actor);
939
940   application.SendNotification();
941   application.Render();
942
943   DALI_TEST_EQUALS(frameCallback1.mCalled, true, TEST_LOCATION);
944   DALI_TEST_EQUALS(frameCallback2.mCalled, true, TEST_LOCATION);
945   frameCallback1.Reset();
946   frameCallback2.Reset();
947
948   // Remove the second frame-callback, only the first should be called
949
950   DevelStage::RemoveFrameCallback(stage, frameCallback2);
951
952   application.SendNotification();
953   application.Render();
954
955   DALI_TEST_EQUALS(frameCallback1.mCalled, true, TEST_LOCATION);
956   DALI_TEST_EQUALS(frameCallback2.mCalled, false, TEST_LOCATION);
957   frameCallback1.Reset();
958   frameCallback2.Reset();
959
960   // Remove and destroy the actor, the first one should not be called either
961   stage.Remove(actor);
962   actor.Reset();
963
964   application.SendNotification();
965   application.Render();
966
967   DALI_TEST_EQUALS(frameCallback1.mCalled, false, TEST_LOCATION);
968   DALI_TEST_EQUALS(frameCallback2.mCalled, false, TEST_LOCATION);
969
970   END_TEST;
971 }
972
973 int UtcDaliFrameCallbackDestroyedBeforeRemoving(void)
974 {
975   // Ensure there's no segmentation fault if the callback is deleted without being removed
976
977   TestApplication application;
978   Stage           stage = Stage::GetCurrent();
979
980   Actor actor = Actor::New();
981   stage.Add(actor);
982
983   {
984     FrameCallbackBasic frameCallback;
985     DevelStage::AddFrameCallback(stage, frameCallback, actor);
986
987     application.SendNotification();
988     application.Render();
989
990     DALI_TEST_EQUALS(frameCallback.mCalled, true, TEST_LOCATION);
991     frameCallback.Reset();
992   }
993
994   // frameCallback has now been destroyed but not removed
995
996   application.SendNotification();
997   application.Render();
998   DALI_TEST_CHECK(true); // If it runs to here then there's no segmentation fault
999
1000   END_TEST;
1001 }
1002
1003 int UtcDaliFrameCallbackDoubleAddition(void)
1004 {
1005   // Ensure we don't connect the same frame-callback twice
1006
1007   TestApplication application;
1008   Stage           stage     = Stage::GetCurrent();
1009   Actor           rootActor = stage.GetRootLayer();
1010
1011   FrameCallbackBasic frameCallback;
1012   DevelStage::AddFrameCallback(stage, frameCallback, rootActor);
1013
1014   try
1015   {
1016     DevelStage::AddFrameCallback(stage, frameCallback, rootActor);
1017   }
1018   catch(...)
1019   {
1020     DALI_TEST_CHECK(true);
1021   }
1022
1023   END_TEST;
1024 }