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