814c453ce4ee6cd5e166bd2272899af952399c98
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Constraint.cpp
1 /*
2  * Copyright (c) 2014 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-test-suite-utils.h>
23
24 using namespace Dali;
25
26 ///////////////////////////////////////////////////////////////////////////////
27 void utc_dali_constraint_startup(void)
28 {
29   test_return_value = TET_UNDEF;
30 }
31
32 void utc_dali_constraint_cleanup(void)
33 {
34   test_return_value = TET_PASS;
35 }
36 ///////////////////////////////////////////////////////////////////////////////
37
38 ///////////////////////////////////////////////////////////////////////////////
39 namespace
40 {
41
42 /**
43  * A function to use for a constraint, no data collected.
44  */
45 template< typename T >
46 void BasicFunction( T& /* current */, const PropertyInputContainer& /* inputs */ )
47 {
48 }
49
50 /**
51  * A functor which sets a given boolean when the functor is called.
52  */
53 template< typename T >
54 struct BasicCalledFunctor
55 {
56   BasicCalledFunctor( bool& functorCalled ) : mCalled( functorCalled ) { }
57
58   void operator()( T& /* current */, const PropertyInputContainer& /* inputs */ )
59   {
60     mCalled = true;
61   }
62
63   bool& mCalled;
64 };
65
66 /**
67  * A functor which increments a given integer when the functor is called.
68  */
69 template< typename T >
70 struct CalledCountFunctor
71 {
72   CalledCountFunctor( int& callCount ) : mCallCount( callCount ) { }
73
74   void operator()( T& /* current */, const PropertyInputContainer& /* inputs */ )
75   {
76     ++mCallCount;
77   }
78
79   int& mCallCount;
80 };
81
82 /**
83  * A functor which sets the given value as the value required when the functor is called.
84  */
85 template< typename T >
86 struct SetValueFunctor
87 {
88   SetValueFunctor( const T& value ) : mValue( value ) { }
89
90   void operator()( T& current, const PropertyInputContainer& /* inputs */ )
91   {
92     current = mValue;
93   }
94
95   T mValue;
96 };
97
98 } // unnamed namespace
99 ///////////////////////////////////////////////////////////////////////////////
100
101 ///////////////////////////////////////////////////////////////////////////////
102 // Constraint::New(
103 //   Handle,
104 //   Property::Index,
105 //   void( *function )( T&, const PropertyInputContainer& ) )
106 ///////////////////////////////////////////////////////////////////////////////
107 namespace UtcDaliConstraintNewFunction
108 {
109 bool gConstraintFunctionCalled = false;
110 void ConstraintFunction( Vector3& /* current */, const PropertyInputContainer& /* inputs */ )
111 {
112   gConstraintFunctionCalled = true;
113 }
114 } // namespace UtcDaliConstraintNewFunction
115
116 int UtcDaliConstraintNewFunctionP(void)
117 {
118   // Ensure that we can create a constraint using a C function and that it is called.
119
120   TestApplication application;
121   UtcDaliConstraintNewFunction::gConstraintFunctionCalled = false;
122
123   Actor actor = Actor::New();
124   Stage::GetCurrent().Add( actor );
125
126   application.SendNotification();
127   application.Render();
128
129   DALI_TEST_EQUALS( UtcDaliConstraintNewFunction::gConstraintFunctionCalled, false, TEST_LOCATION );
130
131   // Add a constraint
132   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &UtcDaliConstraintNewFunction::ConstraintFunction );
133   DALI_TEST_CHECK( constraint );
134   constraint.Apply();
135
136   application.SendNotification();
137   application.Render();
138
139   DALI_TEST_EQUALS( UtcDaliConstraintNewFunction::gConstraintFunctionCalled, true, TEST_LOCATION );
140
141   END_TEST;
142 }
143
144 int UtcDaliConstraintNewFunctionN(void)
145 {
146   // Create a constraint with an uninitialised handle
147
148   TestApplication application;
149
150   // Add a constraint with an uninitialised handle
151   try
152   {
153     Constraint constraint = Constraint::New< Vector3 >( Actor(), Actor::Property::POSITION, &UtcDaliConstraintNewFunction::ConstraintFunction );
154     DALI_TEST_CHECK( false ); // Should not reach here
155   }
156   catch ( ... )
157   {
158     DALI_TEST_CHECK( true ); // Should assert!
159   }
160
161   END_TEST;
162 }
163
164 // helper for next test
165 void StringConstraintFunction( std::string& /* current */, const PropertyInputContainer& /* inputs */ )
166 {
167 }
168
169 int UtcDaliConstraintNewFunctionNonConstrainableTypeN(void)
170 {
171   // Ensure that we can create a constraint using a C function and that it is called.
172
173   TestApplication application;
174   UtcDaliConstraintNewFunction::gConstraintFunctionCalled = false;
175
176   Actor actor = Actor::New();
177   Stage::GetCurrent().Add( actor );
178
179   application.SendNotification();
180   application.Render();
181
182   try
183   {
184     // Add a constraint
185     Constraint constraint = Constraint::New< std::string >( actor, Actor::Property::COLOR_MODE, &StringConstraintFunction );
186     DALI_TEST_CHECK( constraint );
187     constraint.Apply();
188     tet_result(TET_FAIL);
189   }
190   catch ( Dali::DaliException& e )
191   {
192     DALI_TEST_ASSERT( e, "Property not constrainable", TEST_LOCATION );
193   }
194
195   END_TEST;
196 }
197
198 ///////////////////////////////////////////////////////////////////////////////
199
200 ///////////////////////////////////////////////////////////////////////////////
201 // Constraint::New(
202 //   Handle,
203 //   Property::Index,
204 //   const T& object )
205 ///////////////////////////////////////////////////////////////////////////////
206 int UtcDaliConstraintNewFunctorP(void)
207 {
208   // Ensure that we can create a constraint using a functor and that it is called.
209
210   TestApplication application;
211   bool functorCalled = false;
212
213   Actor actor = Actor::New();
214   Stage::GetCurrent().Add( actor );
215
216   application.SendNotification();
217   application.Render();
218
219   DALI_TEST_EQUALS( functorCalled, false, TEST_LOCATION );
220
221   // Add a constraint
222   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, BasicCalledFunctor< Vector3 >( functorCalled ) );
223   DALI_TEST_CHECK( constraint );
224   constraint.Apply();
225
226   application.SendNotification();
227   application.Render();
228
229   DALI_TEST_EQUALS( functorCalled, true, TEST_LOCATION );
230
231   END_TEST;
232 }
233
234 int UtcDaliConstraintNewFunctorN(void)
235 {
236   // Create a constraint with an uninitialised handle
237
238   TestApplication application;
239   bool functorCalled = false;
240
241   // Add a constraint with an uninitialised handle
242   try
243   {
244     Constraint constraint = Constraint::New< Vector3 >( Actor(), Actor::Property::POSITION, BasicCalledFunctor< Vector3 >( functorCalled ) );
245     DALI_TEST_CHECK( false ); // Should not reach here
246   }
247   catch ( ... )
248   {
249     DALI_TEST_CHECK( true ); // Should assert!
250   }
251
252   END_TEST;
253 }
254 ///////////////////////////////////////////////////////////////////////////////
255
256 ///////////////////////////////////////////////////////////////////////////////
257 // Constraint::New(
258 //   Handle,
259 //   Property::Index,
260 //   const T& object,
261 //   void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
262 ///////////////////////////////////////////////////////////////////////////////
263 namespace UtcDaliConstraintNewFunctorMember
264 {
265 struct Functor
266 {
267   Functor( bool& positionCalled, bool& scaleCalled )
268   : mPositionCalled( positionCalled ),
269     mScaleCalled( scaleCalled )
270   {
271   }
272
273   void Position( Vector3& /* current */, const PropertyInputContainer& /* inputs */ )
274   {
275     mPositionCalled = true;
276   }
277
278   void Scale( Vector3& /* current */, const PropertyInputContainer& /* inputs */ )
279   {
280     mScaleCalled = true;
281   }
282
283   bool& mPositionCalled;
284   bool& mScaleCalled;
285 };
286 } // namespace UtcDaliConstraintNewFunctorMember
287
288 int UtcDaliConstraintNewFunctorMemberP(void)
289 {
290   // Ensure that we can create a constraint using a functor and that it is called.
291
292   TestApplication application;
293   bool positionFunctorCalled = false;
294   bool sizeFunctorCalled = false;
295
296   Actor actor = Actor::New();
297   Stage::GetCurrent().Add( actor );
298
299   application.SendNotification();
300   application.Render();
301
302   DALI_TEST_EQUALS( positionFunctorCalled, false, TEST_LOCATION );
303   DALI_TEST_EQUALS( sizeFunctorCalled, false, TEST_LOCATION );
304
305   // Add a constraint that calls Functor::Position
306   Constraint constraint = Constraint::New< Vector3 >(
307       actor,
308       Actor::Property::POSITION,
309       UtcDaliConstraintNewFunctorMember::Functor( positionFunctorCalled, sizeFunctorCalled ),
310       &UtcDaliConstraintNewFunctorMember::Functor::Position );
311   DALI_TEST_CHECK( constraint );
312   constraint.Apply();
313
314   application.SendNotification();
315   application.Render();
316
317   DALI_TEST_EQUALS( positionFunctorCalled, true, TEST_LOCATION );
318   DALI_TEST_EQUALS( sizeFunctorCalled, false, TEST_LOCATION );
319
320   // Add another constraint that calls Functor::Size
321   Constraint constraint2 = Constraint::New< Vector3 >(
322       actor,
323       Actor::Property::SCALE,
324       UtcDaliConstraintNewFunctorMember::Functor( positionFunctorCalled, sizeFunctorCalled ),
325       &UtcDaliConstraintNewFunctorMember::Functor::Scale );
326   DALI_TEST_CHECK( constraint2 );
327   constraint2.Apply();
328
329   application.SendNotification();
330   application.Render();
331
332   DALI_TEST_EQUALS( positionFunctorCalled, true, TEST_LOCATION );
333   DALI_TEST_EQUALS( sizeFunctorCalled, true, TEST_LOCATION );
334
335   END_TEST;
336 }
337
338 int UtcDaliConstraintNewFunctorMemberN(void)
339 {
340   // Create a constraint with an uninitialised handle
341
342   TestApplication application;
343   bool positionFunctorCalled = false;
344   bool sizeFunctorCalled = false;
345
346   // Add a constraint with an uninitialised handle
347   try
348   {
349     Constraint constraint = Constraint::New< Vector3 >(
350         Actor(),
351         Actor::Property::POSITION,
352         UtcDaliConstraintNewFunctorMember::Functor( positionFunctorCalled, sizeFunctorCalled ),
353         &UtcDaliConstraintNewFunctorMember::Functor::Position );
354     DALI_TEST_CHECK( false ); // Should not reach here
355   }
356   catch ( Dali::DaliException& e )
357   {
358     DALI_TEST_CHECK( true ); // Should assert!
359   }
360
361   END_TEST;
362 }
363 ///////////////////////////////////////////////////////////////////////////////
364
365 ///////////////////////////////////////////////////////////////////////////////
366 // Constraint::Clone
367 ///////////////////////////////////////////////////////////////////////////////
368 int UtcDaliConstraintCloneP(void)
369 {
370   // Ensure we can clone for another actor and it's called appropriately
371
372   TestApplication application;
373   int calledCount = 0;
374
375   Actor actor = Actor::New();
376   Actor clone = Actor::New();
377
378   Stage stage = Stage::GetCurrent();
379   stage.Add( actor );
380   stage.Add( clone );
381
382   application.SendNotification();
383   application.Render();
384
385   DALI_TEST_EQUALS( calledCount, 0, TEST_LOCATION );
386
387   // Add a constraint to actor
388   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, CalledCountFunctor< Vector3 >( calledCount ) );
389   DALI_TEST_CHECK( constraint );
390   constraint.Apply();
391
392   // Create a clone but don't apply
393   Constraint constraintClone = constraint.Clone( clone );
394
395   application.SendNotification();
396   application.Render();
397
398   DALI_TEST_EQUALS( calledCount, 1, TEST_LOCATION );
399
400   // Reset
401   calledCount = 0;
402
403   application.SendNotification();
404   application.Render();
405
406   DALI_TEST_EQUALS( calledCount, 1, TEST_LOCATION );
407
408   // Apply the clone constraint
409   constraintClone.Apply();
410
411   application.SendNotification();
412   application.Render();
413
414   // Should be called once for the new constraint clone and once for the original constraint
415   DALI_TEST_EQUALS( calledCount, 3, TEST_LOCATION );
416
417   // Reset
418   calledCount = 0;
419
420   // Change the position of both actors
421   actor.SetPosition( 100.0f, 100.0f );
422   clone.SetPosition( 100.0f, 100.0f );
423
424   application.SendNotification();
425   application.Render();
426
427   // Functor should have been called twice
428   DALI_TEST_EQUALS( calledCount, 2, TEST_LOCATION );
429
430   END_TEST;
431 }
432
433 int UtcDaliConstraintCloneN(void)
434 {
435   // Attempt to clone an uninitialised constraint should cause an assert
436
437   TestApplication application;
438
439   Constraint constraint;
440
441   try
442   {
443     Actor actor = Actor::New();
444     Constraint clone = constraint.Clone( actor );
445     DALI_TEST_CHECK( false );
446   }
447   catch ( ... )
448   {
449     DALI_TEST_CHECK( true );
450   }
451
452   END_TEST;
453 }
454
455 namespace UtcDaliConstraintClone
456 {
457 void Function( Vector3& /* current */, const PropertyInputContainer& inputs )
458 {
459   DALI_TEST_EQUALS( inputs[0]->GetType(), Property::VECTOR3, TEST_LOCATION );
460   DALI_TEST_EQUALS( inputs[1]->GetType(), Property::ROTATION, TEST_LOCATION );
461   DALI_TEST_EQUALS( inputs[2]->GetType(), Property::VECTOR4, TEST_LOCATION );
462   DALI_TEST_EQUALS( inputs[3]->GetType(), Property::BOOLEAN, TEST_LOCATION );
463 }
464 } // namespace UtcDaliConstraintClone
465
466 int UtcDaliConstraintCloneCheckSourcesAndSetters(void)
467 {
468   // Ensure all sources, the tag and remove-action are cloned appropriately
469
470   TestApplication application;
471
472   Actor actor = Actor::New();
473   Actor clone = Actor::New();
474
475   Stage stage = Stage::GetCurrent();
476   stage.Add( actor );
477   stage.Add( clone );
478
479   application.SendNotification();
480   application.Render();
481
482   // Create a constraint, DON'T Apply it though
483   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &UtcDaliConstraintClone::Function );
484   constraint.AddSource( LocalSource( Actor::Property::SIZE ) );
485   constraint.AddSource( LocalSource( Actor::Property::ORIENTATION ) );
486   constraint.AddSource( LocalSource( Actor::Property::COLOR ) );
487   constraint.AddSource( LocalSource( Actor::Property::VISIBLE ) );
488   constraint.SetRemoveAction( Constraint::Discard );
489   constraint.SetTag( 123 );
490
491   // Clone the constraint & apply the clone
492   Constraint constraintClone = constraint.Clone( clone );
493   constraintClone.Apply();
494
495   application.SendNotification();
496   application.Render();
497
498   DALI_TEST_EQUALS( constraint.GetRemoveAction(), constraintClone.GetRemoveAction(), TEST_LOCATION );
499   DALI_TEST_EQUALS( constraint.GetTag(),          constraintClone.GetTag(),          TEST_LOCATION );
500
501   END_TEST;
502 }
503 ///////////////////////////////////////////////////////////////////////////////
504
505 ///////////////////////////////////////////////////////////////////////////////
506 // Constraint::Constraint( const Constraint& )
507 // Constraint::operator=
508 ///////////////////////////////////////////////////////////////////////////////
509 int UtcDaliConstraintCopyAndAssignment(void)
510 {
511   // Ensure copy constructor & assignment operators work
512
513   TestApplication application;
514
515   Actor actor = Actor::New();
516   Stage::GetCurrent().Add( actor );
517
518   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &BasicFunction< Vector3 > );
519   Constraint copied( constraint );
520   Constraint assigned;
521   DALI_TEST_CHECK( constraint == copied );
522   DALI_TEST_CHECK( copied != assigned );
523
524   assigned = constraint;
525   DALI_TEST_CHECK( constraint == assigned );
526
527   END_TEST;
528 }
529 ///////////////////////////////////////////////////////////////////////////////
530
531 ///////////////////////////////////////////////////////////////////////////////
532 // Constraint::DownCast
533 ///////////////////////////////////////////////////////////////////////////////
534 int UtcDaliConstraintDownCast(void)
535 {
536   // Ensure DownCast works as expected
537
538   TestApplication application;
539
540   Actor actor = Actor::New();
541   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &BasicFunction< Vector3 > );
542
543   // Another BaseHandle type
544   Constraint downCast = Constraint::DownCast( actor );
545   DALI_TEST_CHECK( ! downCast );
546
547   // A constraint
548   downCast = Constraint::DownCast( constraint );
549   DALI_TEST_CHECK( downCast );
550
551   // An empty constraint
552   downCast = Constraint::DownCast( Constraint() );
553   DALI_TEST_CHECK( ! downCast );
554
555   END_TEST;
556 }
557 ///////////////////////////////////////////////////////////////////////////////
558
559 ///////////////////////////////////////////////////////////////////////////////
560 // Constraint::GetTargetObject
561 ///////////////////////////////////////////////////////////////////////////////
562 int UtcDaliConstraintGetTargetObjectP(void)
563 {
564   TestApplication application;
565
566   Actor actor = Actor::New();
567   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &BasicFunction< Vector3 > );
568   DALI_TEST_CHECK( constraint.GetTargetObject() == actor );
569
570   Actor actor2 = Actor::New();
571   DALI_TEST_CHECK( constraint.GetTargetObject() != actor2 );
572
573   END_TEST;
574 }
575
576 int UtcDaliConstraintGetTargetObjectN(void)
577 {
578   // Attempt to retrieve from uninitialised constraint
579
580   TestApplication application;
581
582   Constraint constraint;
583   try
584   {
585     Handle handle = constraint.GetTargetObject();
586     DALI_TEST_CHECK( false ); // Should not reach here!
587   }
588   catch( ... )
589   {
590     DALI_TEST_CHECK( true );
591   }
592
593   END_TEST;
594 }
595 ///////////////////////////////////////////////////////////////////////////////
596
597 ///////////////////////////////////////////////////////////////////////////////
598 // Constraint::GetTargetProperty
599 ///////////////////////////////////////////////////////////////////////////////
600 int UtcDaliConstraintGetTargetPropertyP(void)
601 {
602   TestApplication application;
603
604   Actor actor = Actor::New();
605   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &BasicFunction< Vector3 > );
606   DALI_TEST_EQUALS( constraint.GetTargetProperty(), (Property::Index)Actor::Property::POSITION, TEST_LOCATION );
607
608   END_TEST;
609 }
610
611 int UtcDaliConstraintGetTargetPropertyN(void)
612 {
613   // Attempt to retrieve from uninitialised constraint
614
615   TestApplication application;
616
617   Constraint constraint;
618   try
619   {
620     Property::Index propertyIndex = constraint.GetTargetProperty();
621     ( void )propertyIndex;
622     DALI_TEST_CHECK( false ); // Should not reach here!
623   }
624   catch( ... )
625   {
626     DALI_TEST_CHECK( true );
627   }
628
629   END_TEST;
630 }
631 ///////////////////////////////////////////////////////////////////////////////
632
633 ///////////////////////////////////////////////////////////////////////////////
634 // Constraint::SetTag
635 // Constraint::GetTag
636 ///////////////////////////////////////////////////////////////////////////////
637 int UtcDaliConstraintTagP(void)
638 {
639   TestApplication application;
640
641   Actor actor = Actor::New();
642   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &BasicFunction< Vector3 > );
643   DALI_TEST_EQUALS( constraint.GetTag(), 0u, TEST_LOCATION );
644
645   const unsigned int tag = 123;
646   constraint.SetTag( tag );
647   DALI_TEST_EQUALS( constraint.GetTag(), tag, TEST_LOCATION );
648
649   END_TEST;
650 }
651
652 int UtcDaliConstraintSetTagN(void)
653 {
654   // Attempt to set from uninitialised constraint
655
656   TestApplication application;
657
658   Constraint constraint;
659   try
660   {
661     constraint.SetTag( 123 );
662     DALI_TEST_CHECK( false ); // Should not reach here!
663   }
664   catch( ... )
665   {
666     DALI_TEST_CHECK( true );
667   }
668
669   END_TEST;
670 }
671
672 int UtcDaliConstraintGetTagN(void)
673 {
674   // Attempt to retrieve from uninitialised constraint
675
676   TestApplication application;
677
678   Constraint constraint;
679   try
680   {
681     int tag = constraint.GetTag();
682     ( void )tag;
683     DALI_TEST_CHECK( false ); // Should not reach here!
684   }
685   catch( ... )
686   {
687     DALI_TEST_CHECK( true );
688   }
689
690   END_TEST;
691 }
692
693 ///////////////////////////////////////////////////////////////////////////////
694
695 ///////////////////////////////////////////////////////////////////////////////
696 // Constraint::SetRemoveAction
697 // Constraint::GetRemoveAction
698 ///////////////////////////////////////////////////////////////////////////////
699 int UtcDaliConstraintRemoveActionP(void)
700 {
701   TestApplication application;
702
703   Actor actor = Actor::New();
704   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &BasicFunction< Vector3 > );
705   DALI_TEST_EQUALS( constraint.GetRemoveAction(), Constraint::DEFAULT_REMOVE_ACTION, TEST_LOCATION );
706
707   constraint.SetRemoveAction( Constraint::Discard );
708   DALI_TEST_EQUALS( constraint.GetRemoveAction(), Constraint::Discard, TEST_LOCATION );
709
710   constraint.SetRemoveAction( Constraint::Bake );
711   DALI_TEST_EQUALS( constraint.GetRemoveAction(), Constraint::Bake, TEST_LOCATION );
712
713   END_TEST;
714 }
715
716 int UtcDaliConstraintSetRemoveActionN(void)
717 {
718   // Attempt to set from uninitialised constraint
719
720   TestApplication application;
721
722   Constraint constraint;
723   try
724   {
725     constraint.SetRemoveAction( Constraint::Discard );
726     DALI_TEST_CHECK( false ); // Should not reach here!
727   }
728   catch( ... )
729   {
730     DALI_TEST_CHECK( true );
731   }
732
733   END_TEST;
734 }
735
736 int UtcDaliConstraintGetRemoveActionN(void)
737 {
738   // Attempt to retrieve from uninitialised constraint
739
740   TestApplication application;
741
742   Constraint constraint;
743   try
744   {
745     Constraint::RemoveAction removeAction = constraint.GetRemoveAction();
746     ( void )removeAction;
747     DALI_TEST_CHECK( false ); // Should not reach here!
748   }
749   catch( ... )
750   {
751     DALI_TEST_CHECK( true );
752   }
753
754   END_TEST;
755 }
756
757 int UtcDaliConstraintBakeRemoveAction(void)
758 {
759   // Ensure value is baked when constraint is removed
760
761   TestApplication application;
762
763   Actor actor = Actor::New();
764   Stage::GetCurrent().Add( actor );
765
766   application.SendNotification();
767   application.Render();
768
769   // Should not equal position by default
770   Vector3 position( 10.0f, 20.0f, 30.0f );
771   DALI_TEST_CHECK( actor.GetCurrentPosition() != position );
772
773   // Create a constraint that constrains to position
774   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, SetValueFunctor< Vector3 >( position ) );
775   constraint.SetRemoveAction( Constraint::Bake );
776   constraint.Apply();
777
778   application.SendNotification();
779   application.Render();
780
781   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
782
783   // Remove the constraint, it should still be at position
784   constraint.Remove();
785
786   application.SendNotification();
787   application.Render();
788
789   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
790
791   END_TEST;
792 }
793
794 int UtcDaliConstraintDiscardRemoveAction(void)
795 {
796   // Ensure value is baked when constraint is removed
797
798   TestApplication application;
799
800   Actor actor = Actor::New();
801   Stage::GetCurrent().Add( actor );
802
803   application.SendNotification();
804   application.Render();
805
806   // Get and store current position
807   Vector3 originalPosition = actor.GetCurrentPosition();
808
809   // Should not equal position by default
810   Vector3 position( 10.0f, 20.0f, 30.0f );
811   DALI_TEST_CHECK( actor.GetCurrentPosition() != position );
812
813   // Create a constraint that constrains to position
814   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, SetValueFunctor< Vector3 >( position ) );
815   constraint.SetRemoveAction( Constraint::Discard );
816   constraint.Apply();
817
818   application.SendNotification();
819   application.Render();
820
821   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
822
823   // Remove the constraint, it should still be at position
824   constraint.Remove();
825
826   application.SendNotification();
827   application.Render();
828
829   DALI_TEST_EQUALS( actor.GetCurrentPosition(), originalPosition, TEST_LOCATION );
830   DALI_TEST_CHECK( actor.GetCurrentPosition() != position );
831
832   END_TEST;
833 }
834
835 ///////////////////////////////////////////////////////////////////////////////
836
837 ///////////////////////////////////////////////////////////////////////////////
838 // Constraint::Apply
839 // Constraint::Remove
840 ///////////////////////////////////////////////////////////////////////////////
841 int UtcDaliConstraintApplyRemove(void)
842 {
843   // Ensure constraint functors are called appropriately
844
845   TestApplication application;
846   bool functorCalled = false;
847
848   Actor actor = Actor::New();
849   Stage::GetCurrent().Add( actor );
850
851   application.SendNotification();
852   application.Render();
853
854   DALI_TEST_EQUALS( functorCalled, false, TEST_LOCATION );
855
856   // Create a constraint and apply, functor should be called
857   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, BasicCalledFunctor< Vector3 >( functorCalled ) );
858   constraint.Apply();
859
860   application.SendNotification();
861   application.Render();
862
863   DALI_TEST_EQUALS( functorCalled, true, TEST_LOCATION );
864
865   // Reset
866   functorCalled = false;
867
868   // Remove the constraint, functor should not be called
869   constraint.Remove();
870
871   application.SendNotification();
872   application.Render();
873
874   DALI_TEST_EQUALS( functorCalled, false, TEST_LOCATION );
875
876   // Re-apply the constraint, functor should be called again
877   constraint.Apply();
878
879   application.SendNotification();
880   application.Render();
881
882   DALI_TEST_EQUALS( functorCalled, true, TEST_LOCATION );
883
884   END_TEST;
885 }
886
887 int UtcDaliConstraintApplyBeforeAddedToStage(void)
888 {
889   // Constraint gets applied to an off-stage actor.
890   // Constraint should be automatically applied when the actor is added to the stage and not before
891
892   TestApplication application;
893   bool functorCalled = false;
894
895   // Create an actor and a constraint and apply, DON'T add to stage just yet
896   Actor actor = Actor::New();
897   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, BasicCalledFunctor< Vector3 >( functorCalled ) );
898   constraint.Apply();
899
900   application.SendNotification();
901   application.Render();
902
903   // Should NOT be called
904   DALI_TEST_EQUALS( functorCalled, false, TEST_LOCATION );
905
906   // Add actor to stage
907   Stage::GetCurrent().Add( actor );
908
909   application.SendNotification();
910   application.Render();
911
912   // Should now be called
913   DALI_TEST_EQUALS( functorCalled, true, TEST_LOCATION );
914
915   END_TEST;
916 }
917
918 int UtcDaliConstraintApplyAndRemoveBeforeAddedToStage(void)
919 {
920   // Constraint gets applied to an off-stage actor, then gets removed before it's added to the stage
921   // Constraint should NOT be called at all
922
923   TestApplication application;
924   bool functorCalled = false;
925
926   // Create an actor and a constraint and apply, DON'T add to stage just yet
927   Actor actor = Actor::New();
928   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, BasicCalledFunctor< Vector3 >( functorCalled ) );
929   constraint.Apply();
930
931   application.SendNotification();
932   application.Render();
933
934   // Should NOT be called
935   DALI_TEST_EQUALS( functorCalled, false, TEST_LOCATION );
936
937   // Remove the constraint
938   constraint.Remove();
939
940   // Add actor to stage
941   Stage::GetCurrent().Add( actor );
942
943   application.SendNotification();
944   application.Render();
945
946   // Still should NOT be called
947   DALI_TEST_EQUALS( functorCalled, false, TEST_LOCATION );
948
949   END_TEST;
950 }
951
952 int UtcDaliConstraintApplyActorStagedUnstaged(void)
953 {
954   // Apply a constraint to an actor which is staged and unstaged.
955   // Functor should only be called while the actor is staged.
956
957   TestApplication application;
958   bool functorCalled = false;
959
960   // Create an actor and add to stage
961   Actor actor = Actor::New();
962   Stage stage = Stage::GetCurrent();
963   stage.Add( actor );
964
965   // Create a constraint and apply
966   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, BasicCalledFunctor< Vector3 >( functorCalled ) );
967   constraint.Apply();
968
969   application.SendNotification();
970   application.Render();
971
972   // Constraint should be called
973   DALI_TEST_EQUALS( functorCalled, true, TEST_LOCATION );
974
975   // Reset
976   functorCalled = false;
977
978   // Remove actor from stage
979   stage.Remove( actor );
980
981   application.SendNotification();
982   application.Render();
983
984   // Constraint should NOT be called
985   DALI_TEST_EQUALS( functorCalled, false, TEST_LOCATION );
986
987   // Re-add to stage
988   stage.Add( actor );
989
990   application.SendNotification();
991   application.Render();
992
993   // Constraint should be called
994   DALI_TEST_EQUALS( functorCalled, true, TEST_LOCATION );
995
996   END_TEST;
997 }
998
999 int UtcDaliConstraintApplySeveralTimes(void)
1000 {
1001   // Apply the same constraint several times.
1002   // Should not cause any problems (subsequent attempts should be no-ops)
1003
1004   TestApplication application;
1005   int count = 0;
1006
1007   // Create an actor and add to stage
1008   Actor actor = Actor::New();
1009   Stage stage = Stage::GetCurrent();
1010   stage.Add( actor );
1011
1012   // Create a constraint and apply
1013   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, CalledCountFunctor< Vector3 >( count ) );
1014   constraint.Apply();
1015
1016   // Apply again
1017   constraint.Apply(); // no-op
1018
1019   application.SendNotification();
1020   application.Render();
1021
1022   // Should only have been called once
1023   DALI_TEST_EQUALS( count, 1, TEST_LOCATION );
1024
1025   // Reset
1026   count = 0;
1027
1028   // Apply again
1029   constraint.Apply(); // no-op
1030
1031   application.SendNotification();
1032   application.Render();
1033
1034   DALI_TEST_EQUALS( count, 1, TEST_LOCATION );
1035
1036   // Reset
1037   count = 0;
1038
1039   // Change the position property, apply again
1040   actor.SetPosition( 10.0f, 10.0f );
1041   constraint.Apply();
1042
1043   application.SendNotification();
1044   application.Render();
1045
1046   // Constraint should have been called once
1047   DALI_TEST_EQUALS( count, 1, TEST_LOCATION );
1048
1049   END_TEST;
1050 }
1051
1052 ///////////////////////////////////////////////////////////////////////////////
1053
1054 ///////////////////////////////////////////////////////////////////////////////
1055 // Constraint::AddSource
1056 ///////////////////////////////////////////////////////////////////////////////
1057 namespace UtcDaliConstraintAddSource
1058 {
1059 void Function( Vector3& /* current */, const PropertyInputContainer& inputs )
1060 {
1061   DALI_TEST_EQUALS( inputs.Size(), 4u, TEST_LOCATION );
1062   DALI_TEST_EQUALS( inputs[0]->GetType(), Property::VECTOR3, TEST_LOCATION );
1063   DALI_TEST_EQUALS( inputs[1]->GetType(), Property::ROTATION, TEST_LOCATION );
1064   DALI_TEST_EQUALS( inputs[2]->GetType(), Property::VECTOR4, TEST_LOCATION );
1065   DALI_TEST_EQUALS( inputs[3]->GetType(), Property::BOOLEAN, TEST_LOCATION );
1066 }
1067 } // namespace UtcDaliConstraintAddSource
1068
1069 int UtcDaliConstraintAddSourceP(void)
1070 {
1071   // Ensure all sources are in the correct order in the functor
1072
1073   TestApplication application;
1074
1075   Actor actor = Actor::New();
1076   Stage::GetCurrent().Add( actor );
1077
1078   // Create a constraint, add sources
1079   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &UtcDaliConstraintAddSource::Function );
1080   constraint.AddSource( LocalSource( Actor::Property::SIZE ) );
1081   constraint.AddSource( LocalSource( Actor::Property::ORIENTATION ) );
1082   constraint.AddSource( LocalSource( Actor::Property::COLOR ) );
1083   constraint.AddSource( LocalSource( Actor::Property::VISIBLE ) );
1084   constraint.Apply();
1085
1086   application.SendNotification();
1087   application.Render();
1088
1089   END_TEST;
1090 }
1091
1092 int UtcDaliConstraintAddSourceN(void)
1093 {
1094   // Attempt to set from uninitialised constraint
1095
1096   TestApplication application;
1097
1098   Constraint constraint;
1099   try
1100   {
1101     constraint.AddSource( LocalSource( Actor::Property::POSITION ) );
1102     DALI_TEST_CHECK( false ); // Should not reach here!
1103   }
1104   catch( ... )
1105   {
1106     DALI_TEST_CHECK( true );
1107   }
1108
1109   END_TEST;
1110 }
1111 ///////////////////////////////////////////////////////////////////////////////
1112
1113 ///////////////////////////////////////////////////////////////////////////////
1114 namespace TestChaining
1115 {
1116
1117 const Vector3 gFunction1Output( Vector3::ONE );
1118 void Function1( Vector3& current, const PropertyInputContainer& /* inputs */ )
1119 {
1120   // current is original position
1121   DALI_TEST_EQUALS( current, Vector3::ZERO, TEST_LOCATION );
1122   current = gFunction1Output;
1123 }
1124
1125 const Vector3 gFunction2Output( 10.0f, 20.0f, 30.0f );
1126 void Function2( Vector3& current, const PropertyInputContainer& /* inputs */ )
1127 {
1128   // current is output from Function1
1129   DALI_TEST_EQUALS( current, gFunction1Output, TEST_LOCATION );
1130
1131   current = gFunction2Output;
1132 }
1133
1134 const Vector3 gFunction3Output( 10.0f, 20.0f, 30.0f );
1135 void Function3( Vector3& current, const PropertyInputContainer& /* inputs */ )
1136 {
1137   // current is output from Function2
1138   DALI_TEST_EQUALS( current, gFunction2Output, TEST_LOCATION );
1139
1140   current = gFunction3Output;
1141 }
1142
1143 const Vector3 gFunction4Output( 10.0f, 20.0f, 30.0f );
1144 void Function4( Vector3& current, const PropertyInputContainer& /* inputs */ )
1145 {
1146   // current is output from Function3
1147   DALI_TEST_EQUALS( current, gFunction3Output, TEST_LOCATION );
1148
1149   current = gFunction4Output;
1150 }
1151
1152 void Function5( Vector3& current, const PropertyInputContainer& /* inputs */ )
1153 {
1154   // current is output from Function4
1155   DALI_TEST_EQUALS( current, gFunction4Output, TEST_LOCATION );
1156
1157   current = Vector3::ZERO;
1158 }
1159
1160 } // namespace TestChaining
1161
1162 int UtcDaliConstraintChaining(void)
1163 {
1164   // Apply several constraints to the same property and ensure the functors are called in the correct order.
1165
1166   TestApplication application;
1167
1168   Actor actor = Actor::New();
1169   Stage::GetCurrent().Add( actor );
1170
1171   Constraint constraint1 = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &TestChaining::Function1 );
1172   Constraint constraint2 = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &TestChaining::Function2 );
1173   Constraint constraint3 = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &TestChaining::Function3 );
1174   Constraint constraint4 = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &TestChaining::Function4 );
1175   Constraint constraint5 = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &TestChaining::Function5 );
1176
1177   constraint1.Apply();
1178   constraint2.Apply();
1179   constraint3.Apply();
1180   constraint4.Apply();
1181   constraint5.Apply();
1182
1183   application.SendNotification();
1184   application.Render();
1185
1186   END_TEST;
1187 }
1188 ///////////////////////////////////////////////////////////////////////////////
1189
1190 ///////////////////////////////////////////////////////////////////////////////
1191 namespace TestPropertyTypes
1192 {
1193 template< typename T >
1194 void Execute( T value )
1195 {
1196   TestApplication application;
1197   bool functorCalled = false;
1198
1199   Actor actor = Actor::New();
1200   Property::Index index = actor.RegisterProperty( "TEMP_PROPERTY_NAME", value );
1201
1202   Stage::GetCurrent().Add( actor );
1203
1204   application.SendNotification();
1205   application.Render();
1206
1207   DALI_TEST_EQUALS( functorCalled, false, TEST_LOCATION );
1208
1209   // Add a constraint
1210   Constraint constraint = Constraint::New< T >( actor, index, BasicCalledFunctor< T >( functorCalled ) );
1211   DALI_TEST_CHECK( constraint );
1212   constraint.Apply();
1213
1214   application.SendNotification();
1215   application.Render();
1216
1217   DALI_TEST_EQUALS( functorCalled, true, TEST_LOCATION );
1218 }
1219 } // namespace UtcDaliConstraintNewFunctor
1220
1221 int UtcDaliConstraintTestPropertyTypesP(void)
1222 {
1223   // Ensure we can use a constraint functor with all supported property types
1224
1225   TestPropertyTypes::Execute< bool >( false );
1226   TestPropertyTypes::Execute< int >( 0 );
1227   TestPropertyTypes::Execute< float >( 0.0f );
1228   TestPropertyTypes::Execute< Vector2 >( Vector2::ZERO );
1229   TestPropertyTypes::Execute< Vector3 >( Vector3::ZERO );
1230   TestPropertyTypes::Execute< Vector4 >( Vector4::ZERO );
1231   TestPropertyTypes::Execute< Quaternion >( Quaternion::IDENTITY );
1232   TestPropertyTypes::Execute< Matrix >( Matrix::IDENTITY );
1233   TestPropertyTypes::Execute< Matrix3 >( Matrix3::IDENTITY );
1234
1235   END_TEST;
1236 }
1237
1238 ///////////////////////////////////////////////////////////////////////////////
1239