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