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