Dali 3D User Interface Engine
utc-Dali-Constraint.cpp
Go to the documentation of this file.
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>
22 #include <dali-test-suite-utils.h>
23 
24 using namespace Dali;
25 
28 {
30 }
31 
33 {
35 }
37 
39 namespace
40 {
41 
45 template< typename T >
46 void BasicFunction( T& /* current */, const PropertyInputContainer& /* inputs */ )
47 {
48 }
49 
53 template< typename T >
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 
69 template< typename T >
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 
85 template< typename T >
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
100 
102 // Constraint::New(
103 // Handle,
104 // Property::Index,
105 // void( *function )( T&, const PropertyInputContainer& ) )
107 namespace UtcDaliConstraintNewFunction
108 {
110 void ConstraintFunction( Vector3& /* current */, const PropertyInputContainer& /* inputs */ )
111 {
113 }
114 } // namespace UtcDaliConstraintNewFunction
115 
117 {
118  // Ensure that we can create a constraint using a C function and that it is called.
119 
120  TestApplication application;
122 
123  Actor actor = Actor::New();
124  Stage::GetCurrent().Add( actor );
125 
126  application.SendNotification();
127  application.Render();
128 
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 
140 
141  END_TEST;
142 }
143 
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 }
164 
166 // Constraint::New(
167 // Handle,
168 // Property::Index,
169 // const T& object )
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 
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 }
220 
222 // Constraint::New(
223 // Handle,
224 // Property::Index,
225 // const T& object,
226 // void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
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 
250 };
251 } // namespace UtcDaliConstraintNewFunctorMember
252 
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,
274  UtcDaliConstraintNewFunctorMember::Functor( positionFunctorCalled, sizeFunctorCalled ),
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,
289  UtcDaliConstraintNewFunctorMember::Functor( positionFunctorCalled, sizeFunctorCalled ),
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 
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(),
317  UtcDaliConstraintNewFunctorMember::Functor( positionFunctorCalled, sizeFunctorCalled ),
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 }
329 
331 // Constraint::Clone
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 
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 
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 );
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 }
469 
471 // Constraint::Constraint( const Constraint& )
472 // Constraint::operator=
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 }
495 
497 // Constraint::DownCast
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 }
523 
525 // Constraint::GetTargetObject
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 
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 }
561 
563 // Constraint::GetTargetProperty
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 
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 }
597 
599 // Constraint::SetTag
600 // Constraint::GetTag
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 
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 
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 
659 
661 // Constraint::SetRemoveAction
662 // Constraint::GetRemoveAction
665 {
666  TestApplication application;
667 
668  Actor actor = Actor::New();
669  Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &BasicFunction< Vector3 > );
671 
672  constraint.SetRemoveAction( Constraint::Discard );
674 
675  constraint.SetRemoveAction( Constraint::Bake );
677 
678  END_TEST;
679 }
680 
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 
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 
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 
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 
801 
803 // Constraint::Apply
804 // Constraint::Remove
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 
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 
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 
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 
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 
1018 
1020 // Constraint::AddSource
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 
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 ) );
1047  constraint.AddSource( LocalSource( Actor::Property::COLOR ) );
1049  constraint.Apply();
1050 
1051  application.SendNotification();
1052  application.Render();
1053 
1054  END_TEST;
1055 }
1056 
1058 {
1059  // Attempt to set from uninitialised constraint
1060 
1061  TestApplication application;
1062 
1063  Constraint constraint;
1064  try
1065  {
1067  DALI_TEST_CHECK( false ); // Should not reach here!
1068  }
1069  catch( ... )
1070  {
1071  DALI_TEST_CHECK( true );
1072  }
1073 
1074  END_TEST;
1075 }
1077 
1079 namespace TestChaining
1080 {
1081 
1083 void Function1( Vector3& current, const PropertyInputContainer& /* inputs */ )
1084 {
1085  // current is original position
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
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
1113 
1114  current = gFunction4Output;
1115 }
1116 
1117 void Function5( Vector3& current, const PropertyInputContainer& /* inputs */ )
1118 {
1119  // current is output from Function4
1121 
1122  current = Vector3::ZERO;
1123 }
1124 
1125 } // namespace TestChaining
1126 
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 }
1154 
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 
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 
1204 
Dali Docs Home
Read more about Dali