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