Dali 3D User Interface Engine
utc-Dali-Handle.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/dali-test-suite-utils.h"
23 #include <mesh-builder.h>
24 
25 using namespace Dali;
26 
28 {
30 }
31 
33 {
35 }
36 
37 namespace
38 {
39 
41 class BaseObjectType : public BaseObject
42 {
43 public:
45  {
46  }
47 };
48 
50 {
51  // object + copy + passedByValue, ref count == 3
52  DALI_TEST_CHECK(passedByValue);
53  if (passedByValue)
54  {
56  }
57 
58  return passedByValue;
59 }
60 
61 } // anon namespace
62 
63 
65 {
66  TestApplication application;
67  tet_infoline("Testing Dali::Handle::Handle()");
68 
69  Handle object;
70 
71  DALI_TEST_CHECK(!object);
72 
73  END_TEST;
74 }
75 
77 {
78  TestApplication application;
79  tet_infoline("Testing Dali::Handle::Handle(const Handle&)");
80 
81  // Initialize an object, ref count == 1
82  Handle object = Actor::New();
83 
84  DALI_TEST_EQUALS(1, object.GetBaseObject().ReferenceCount(), TEST_LOCATION);
85 
86  // Copy the object, ref count == 2
87  Handle copy(object);
88  DALI_TEST_CHECK(copy);
89  if (copy)
90  {
92  }
93 
94  {
95  // Pass by value, and return another copy, ref count == 3
96  Handle anotherCopy = ImplicitCopyConstructor(copy);
97 
98  DALI_TEST_CHECK(anotherCopy);
99  if (anotherCopy)
100  {
102  }
103  }
104 
105  // anotherCopy out of scope, ref count == 2
106  DALI_TEST_CHECK(copy);
107  if (copy)
108  {
110  }
111  END_TEST;
112 }
113 
115 {
116  TestApplication application;
117  tet_infoline("Testing Dali::Handle::operator=");
118 
119  Handle object = Actor::New();
120 
121  DALI_TEST_CHECK(object);
122  DALI_TEST_EQUALS(1, object.GetBaseObject().ReferenceCount(), TEST_LOCATION);
123 
124  Handle copy;
125  DALI_TEST_CHECK(!copy);
126 
127  copy = object;
128  DALI_TEST_CHECK(copy);
130  DALI_TEST_CHECK(&(copy.GetBaseObject()) == &(object.GetBaseObject()));
131  END_TEST;
132 }
133 
135 {
136  tet_infoline("Positive Test Dali::Handle::Supports()");
137  TestApplication application;
138 
139  Actor actor = Actor::New();
141  END_TEST;
142 }
143 
145 {
146  tet_infoline("Positive Test Dali::Handle::GetPropertyCount()");
147  TestApplication application;
148 
149  Actor actor = Actor::New();
150  int defaultPropertyCount( actor.GetPropertyCount() );
151 
152  // Register a dynamic property
153  actor.RegisterProperty( "testProperty", float(123.0f) );
154  DALI_TEST_CHECK( (defaultPropertyCount + 1u) == actor.GetPropertyCount() );
155  END_TEST;
156 }
157 
159 {
160  tet_infoline("Positive Test Dali::Handle::GetPropertyName()");
161  TestApplication application;
162 
163  Actor actor = Actor::New();
164  DALI_TEST_CHECK( "parentOrigin" == actor.GetPropertyName( Actor::Property::PARENT_ORIGIN ) );
165 
166  // Register a dynamic property
167  std::string name("thisNameShouldMatch");
168  Property::Index index = actor.RegisterProperty( name, float(123.0f) );
169  DALI_TEST_CHECK( name == actor.GetPropertyName( index ) );
170 
171  END_TEST;
172 }
173 
175 {
176  tet_infoline("Positive Test Dali::Handle::GetPropertyIndex()");
177  TestApplication application;
178 
179  Actor actor = Actor::New();
181 
182  // Register a dynamic property
183  std::string name("thisNameShouldMatch");
184  Property::Index index = actor.RegisterProperty( name, float(123.0f) );
185  DALI_TEST_CHECK( index == actor.GetPropertyIndex( name ) );
186  END_TEST;
187 }
188 
190 {
191  tet_infoline("Positive Test Dali::Handle::IsPropertyWritable()");
192  TestApplication application;
193 
194  Actor actor = Actor::New();
195 
196  // Actor properties which are writable:
224 
225  // World-properties are not writable:
233 
234  END_TEST;
235 }
236 
238 {
239  tet_infoline("Positive Test Dali::Handle::IsPropertyAnimatable()");
240  TestApplication application;
241 
242  Actor actor = Actor::New();
243 
244  // Actor properties which are animatable:
272 
273  // World-properties can not be animated
281 
282  END_TEST;
283 }
284 
286 {
287  TestApplication application;
288 
289  Actor actor = Actor::New();
290 
291  // Actor properties which can be used as a constraint input:
326 
327  // Actor properties that cannot be used as a constraint input
337 
338  END_TEST;
339 }
340 
341 
343 {
344  tet_infoline("Positive Test Dali::Handle::GetPropertyType()");
345  TestApplication application;
346 
347  Actor actor = Actor::New();
356 
357  // Register some dynamic properties
358  Property::Index boolIndex = actor.RegisterProperty( "boolProperty", bool(true) );
359  Property::Index floatIndex = actor.RegisterProperty( "floatProperty", float(123.0f) );
360  Property::Index intIndex = actor.RegisterProperty( "intProperty", 123 );
361  Property::Index vector2Index = actor.RegisterProperty( "vector2Property", Vector2(1.0f, 2.0f) );
362  Property::Index vector3Index = actor.RegisterProperty( "vector3Property", Vector3(1.0f, 2.0f, 3.0f) );
363  Property::Index vector4Index = actor.RegisterProperty( "vector4Property", Vector4(1.0f, 2.0f, 3.0f, 4.0f) );
364  Property::Index rotationIndex = actor.RegisterProperty( "rotationProperty", AngleAxis(Degree(180.0f), Vector3::YAXIS) );
365 
366  DALI_TEST_CHECK( Property::BOOLEAN == actor.GetPropertyType( boolIndex ) );
367  DALI_TEST_CHECK( Property::FLOAT == actor.GetPropertyType( floatIndex ) );
368  DALI_TEST_CHECK( Property::INTEGER == actor.GetPropertyType( intIndex ) );
369  DALI_TEST_CHECK( Property::VECTOR2 == actor.GetPropertyType( vector2Index ) );
370  DALI_TEST_CHECK( Property::VECTOR3 == actor.GetPropertyType( vector3Index ) );
371  DALI_TEST_CHECK( Property::VECTOR4 == actor.GetPropertyType( vector4Index ) );
372  DALI_TEST_CHECK( Property::ROTATION == actor.GetPropertyType( rotationIndex ) );
373 
374  // Non animatable properties
375  Property::Index nonAnimStringIndex = actor.RegisterProperty( "manFromDelmonte", std::string("yes"), Property::READ_WRITE);
376  Property::Index nonAnimV2Index = actor.RegisterProperty( "v2", Vector2(1.f, 2.f), Property::READ_WRITE);
377  Property::Index nonAnimV3Index = actor.RegisterProperty( "v3", Vector3(1.f, 2.f, 3.f), Property::READ_WRITE);
378  Property::Index nonAnimV4Index = actor.RegisterProperty( "v4", Vector4(1.f, 2.f, 3.f, 4.f), Property::READ_WRITE);
379  Property::Index nonAnimBooleanIndex = actor.RegisterProperty( "bool", true, Property::READ_WRITE);
380  Property::Index nonAnimFloatIndex = actor.RegisterProperty( "float", 0.f, Property::READ_WRITE);
381  Property::Index nonAnimIntegerIndex = actor.RegisterProperty( "int", 0, Property::READ_WRITE);
382 
383  DALI_TEST_CHECK( nonAnimStringIndex != Property::INVALID_INDEX );
384  DALI_TEST_CHECK( nonAnimV2Index != Property::INVALID_INDEX );
385  DALI_TEST_CHECK( nonAnimV3Index != Property::INVALID_INDEX );
386  DALI_TEST_CHECK( nonAnimV4Index != Property::INVALID_INDEX );
387  DALI_TEST_CHECK( nonAnimBooleanIndex != Property::INVALID_INDEX );
388  DALI_TEST_CHECK( nonAnimFloatIndex != Property::INVALID_INDEX );
389  DALI_TEST_CHECK( nonAnimIntegerIndex != Property::INVALID_INDEX );
390 
391  DALI_TEST_CHECK( Property::STRING == actor.GetPropertyType( nonAnimStringIndex ) );
392  DALI_TEST_CHECK( Property::VECTOR2 == actor.GetPropertyType( nonAnimV2Index ) );
393  DALI_TEST_CHECK( Property::VECTOR3 == actor.GetPropertyType( nonAnimV3Index ) );
394  DALI_TEST_CHECK( Property::VECTOR4 == actor.GetPropertyType( nonAnimV4Index ) );
395  DALI_TEST_CHECK( Property::BOOLEAN == actor.GetPropertyType( nonAnimBooleanIndex ) );
396  DALI_TEST_CHECK( Property::FLOAT == actor.GetPropertyType( nonAnimFloatIndex ) );
397  DALI_TEST_CHECK( Property::INTEGER == actor.GetPropertyType( nonAnimIntegerIndex ) );
398 
399  DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimStringIndex ) );
400  DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimV2Index ) );
401  DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimV3Index ) );
402  DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimV4Index ) );
403  DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimBooleanIndex ) );
404  DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimFloatIndex ) );
405  DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimIntegerIndex ) );
406 
407  DALI_TEST_EQUALS( "yes" , actor.GetProperty( nonAnimStringIndex ).Get<std::string>(), TEST_LOCATION );
408  DALI_TEST_EQUALS( Vector2(1.f, 2.f) , actor.GetProperty( nonAnimV2Index ).Get<Vector2>(), TEST_LOCATION );
409  DALI_TEST_EQUALS( Vector3(1.f, 2.f, 3.f) , actor.GetProperty( nonAnimV3Index ).Get<Vector3>(), TEST_LOCATION );
410  DALI_TEST_EQUALS( Vector4(1.f, 2.f, 3.f, 4.f) , actor.GetProperty( nonAnimV4Index ).Get<Vector4>(), TEST_LOCATION );
411  DALI_TEST_EQUALS( true, actor.GetProperty( nonAnimBooleanIndex ).Get<bool>(), TEST_LOCATION );
412  DALI_TEST_EQUALS( 0.f, actor.GetProperty( nonAnimFloatIndex ).Get<float>(), TEST_LOCATION );
413  DALI_TEST_EQUALS( 0, actor.GetProperty( nonAnimIntegerIndex ).Get<int>(), TEST_LOCATION );
414 
415  END_TEST;
416 }
417 
419 {
420  tet_infoline("Test Non Animatable Properties");
421  TestApplication application;
422 
423  Actor actor = Actor::New();
424 
425  Property::Index nonAnimStringIndex = actor.RegisterProperty( "manFromDelmonte", std::string("no"), Property::READ_WRITE);
426 
428  try
429  {
430  actor.SetProperty( nonAnimStringIndex, Property::Value("yes") );
431  }
432  catch (Dali::DaliException& e)
433  {
434  DALI_TEST_CHECK(!"exception");
435  }
436 
437  DALI_TEST_CHECK( "yes" == actor.GetProperty( nonAnimStringIndex ).Get<std::string>() );
438 
440  Property::Index readonly = actor.RegisterProperty( "float", 0.f, Property::READ_ONLY);
441 
442  DALI_TEST_CHECK(!actor.IsPropertyAnimatable(readonly));
443  DALI_TEST_CHECK(!actor.IsPropertyWritable(readonly));
444 
445  bool exception = false;
446  try
447  {
448  actor.SetProperty( readonly, Property::Value(1.f) );
449  }
450  catch (Dali::DaliException& e)
451  {
452  exception = true;
453  }
454 
455  DALI_TEST_CHECK(!exception);// trying to set a read-only property is a no-op
456 
457  DALI_TEST_EQUALS( 0.f, actor.GetProperty( readonly ).Get<float>(), TEST_LOCATION );
458 
460  Property::Index write_anim = actor.RegisterProperty( "write_float", 0.f, Property::ANIMATABLE);
461 
462  DALI_TEST_CHECK(actor.IsPropertyAnimatable(write_anim));
463  DALI_TEST_CHECK(actor.IsPropertyWritable(write_anim));
464 
465  exception = false;
466  try
467  {
468  actor.SetProperty( write_anim, Property::Value(1.f) );
469  }
470  catch (Dali::DaliException& e)
471  {
472  exception = true;
473  }
474 
475  DALI_TEST_CHECK(!exception);
476 
478  float durationSeconds(2.0f);
479  Animation animation = Animation::New(durationSeconds);
480  bool relativeValue(true);
481 
482  exception = false;
483 
484  try
485  {
486  animation.AnimateBy(Property(actor, nonAnimStringIndex), relativeValue, AlphaFunction::EASE_IN);
487  animation.Play();
488  application.SendNotification();
489  application.Render(static_cast<unsigned int>(durationSeconds*0100.0f)/* some progress */);
490  }
491  catch (Dali::DaliException& e)
492  {
493  exception = true;
494  }
495 
496  DALI_TEST_CHECK(!exception);
497  DALI_TEST_EQUALS( "yes", actor.GetProperty( nonAnimStringIndex ).Get<std::string>(), TEST_LOCATION );
498 
499  END_TEST;
500 }
501 
503 {
504  tet_infoline("Test Non Animatable Composite Properties");
505  TestApplication application;
506 
507  Actor actor = Actor::New();
508 
510  Property::Array* array = value.GetArray();
511  DALI_TEST_CHECK( array );
512 
513  array->PushBack( Property::Value( 0.1f ) );
514  array->PushBack( "a string" );
515  array->PushBack( Property::Value( Vector3(1,2,3) ) );
516 
517  DALI_TEST_EQUALS( 3u, array->Count(), TEST_LOCATION );
518 
519  Property::Index propertyIndex = actor.RegisterProperty( "composite", value, Property::READ_WRITE );
520 
521  Property::Value out = actor.GetProperty( propertyIndex );
522  Property::Array* outArray = out.GetArray();
523  DALI_TEST_CHECK( outArray != NULL );
524 
525  DALI_TEST_CHECK( Property::FLOAT == outArray->GetElementAt(0).GetType());
526  DALI_TEST_CHECK( Property::STRING == outArray->GetElementAt(1).GetType());
527  DALI_TEST_CHECK( Property::VECTOR3 == outArray->GetElementAt(2).GetType());
528 
529  DALI_TEST_EQUALS( 0.1f, outArray->GetElementAt(0).Get<float>(), TEST_LOCATION);
530  DALI_TEST_EQUALS( "a string", outArray->GetElementAt(1).Get<std::string>(), TEST_LOCATION);
531  DALI_TEST_EQUALS( Vector3(1,2,3), outArray->GetElementAt(2).Get<Vector3>(), TEST_LOCATION);
532 
533  // composite types not animatable
534  bool exception = false;
535  try
536  {
537  actor.RegisterProperty( "compositemap", value, Property::ANIMATABLE);
538  }
539  catch (Dali::DaliException& e)
540  {
541  exception = true;
543  }
544 
545  DALI_TEST_EQUALS(exception, true, TEST_LOCATION);
546 
547  // Map of maps
548  Property::Value mapOfMaps(Property::MAP);
549  Property::Map* map = mapOfMaps.GetMap();
550 
551  map->Insert( "key", Property::Value(Property::MAP) );
552  map->Insert( "2key", "a string" );
553 
554  DALI_TEST_EQUALS( "a string", (*map)["2key"].Get<std::string>(), TEST_LOCATION);
555 
556  Property::Map* innerMap = map->Find("key")->GetMap();
557  innerMap->Insert( "subkey", 5.f );
558 
559  DALI_TEST_CHECK( NULL != map->Find("key")->GetMap()->Find("subkey") );
560  DALI_TEST_EQUALS( 5.f, map->Find("key")->GetMap()->Find("subkey")->Get<float>(), TEST_LOCATION);
561  END_TEST;
562 }
563 
565 {
566  tet_infoline("Positive Test Dali::Handle::SetProperty()");
567  TestApplication application;
568 
569  Actor actor = Actor::New();
571 
573  // flush the queue and render once
574  application.SendNotification();
575  application.Render();
577  END_TEST;
578 }
579 
581 {
582  tet_infoline("Positive Test Dali::Handle::SetProperty()");
583  TestApplication application;
584 
585  Actor actor = Actor::New();
586 
588 
589  // World position is not writable so this is a no-op and should not crash
591 
592  END_TEST;
593 }
594 
596 {
597  tet_infoline("Positive Test Dali::Handle::RegisterProperty()");
598  TestApplication application;
599 
600  Stage stage = Stage::GetCurrent();
601 
602  Actor actor = Actor::New();
603  stage.Add( actor );
604 
605  const unsigned int defaultPropertyCount = actor.GetPropertyCount();
606 
607  application.SendNotification();
608  application.Render();
609 
610  Property::Index index1 = actor.RegisterProperty( "MyProperty", Vector3::ONE );
611 
612  application.SendNotification();
613  application.Render();
614 
615  DALI_TEST_EQUALS( actor.GetPropertyCount(), defaultPropertyCount + 1, TEST_LOCATION );
617 
618  // No new property should be registered when we call the below function
619  Property::Index index2 = actor.RegisterProperty( "MyProperty", Vector3::ZAXIS );
620 
621  application.SendNotification();
622  application.Render();
623 
624 
625  DALI_TEST_EQUALS( index1, index2, TEST_LOCATION ); // We should have the same index as per the first registration
626  DALI_TEST_EQUALS( actor.GetPropertyCount(), defaultPropertyCount + 1, TEST_LOCATION ); // Property count should be the same
627  DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( index2 ), Vector3::ZAXIS, TEST_LOCATION ); // Value should be what we sent on second RegisterProperty call
628 
629  END_TEST;
630 }
631 
633 {
634  tet_infoline("Positive Test Dali::Handle::GetProperty()");
635  TestApplication application;
636 
637  Actor actor = Actor::New();
638 
644  DALI_TEST_CHECK( true == actor.GetProperty( Actor::Property::VISIBLE ).Get<bool>() );
646  END_TEST;
647 }
648 
650 {
651  TestApplication application;
652  tet_infoline("Testing Dali::Handle::DownCast()");
653 
654  Actor actor = Actor::New();
655 
656  BaseHandle baseHandle = actor;
657 
658  Handle handle = Handle::DownCast(baseHandle);
659 
660  DALI_TEST_CHECK( handle );
661 
662  baseHandle = BaseHandle();
663 
664  handle = Handle::DownCast(baseHandle);
665 
666  DALI_TEST_CHECK( !handle );
667 
668  END_TEST;
669 }
670 
672 {
673  TestApplication application;
674 
675  // BaseObject is NOT an Object, so this DownCast should fail
676  BaseHandle handle( new BaseObjectType );
677  Handle customHandle1 = Handle::DownCast( handle );
678  DALI_TEST_CHECK( ! customHandle1 );
679 
680  // A DownCast on an empty handle will also fail
681  Handle empty;
682  Handle customHandle2 = Handle::DownCast( empty );
683  DALI_TEST_CHECK( ! customHandle2 );
684  END_TEST;
685 }
686 
688 {
689  TestApplication application;
690  Property::IndexContainer indices;
691 
692  // Actor
693  Actor actor = Actor::New();
694  actor.GetPropertyIndices( indices );
695  DALI_TEST_CHECK( indices.Size() );
696  DALI_TEST_EQUALS( indices.Size(), actor.GetPropertyCount(), TEST_LOCATION );
697  END_TEST;
698 }
699 
701 {
702  TestApplication application;
703 
704  struct PropertyTypeAnimatable
705  {
706  const char * name;
707  Property::Value value;
708  bool animatable;
709  };
710 
711  Property::Array array;
712  Property::Map map;
713 
714  PropertyTypeAnimatable properties[] =
715  {
716  { "Property::BOOLEAN", true, true },
717  { "Property::FLOAT", 1.0f, true },
718  { "Property::INTEGER", 1, true },
719  { "Property::VECTOR2", Vector2::ONE, true },
720  { "Property::VECTOR3", Vector3::ONE, true },
721  { "Property::VECTOR4", Vector4::ONE, true },
722  { "Property::MATRIX3", Matrix3::IDENTITY, true },
723  { "Property::MATRIX", Matrix::IDENTITY, true },
724  { "Property::RECTANGLE", Rect<int>(), false },
725  { "Property::ROTATION", AngleAxis(), true },
726  { "Property::STRING", std::string("Me"), false },
727  { "Property::ARRAY", array, false },
728  { "Property::MAP", map, false },
729  };
730 
731  unsigned int numOfProperties( sizeof( properties ) / sizeof( properties[0] ) );
732 
733  for ( unsigned int i = 0; i < numOfProperties; ++i )
734  {
735  tet_printf( "Testing: %s\n", properties[i].name );
736 
737  bool exception = false;
738  try
739  {
740  Actor actor = Actor::New();
741  actor.RegisterProperty( "manFromDelmonte", properties[i].value );
742  }
743  catch (Dali::DaliException& e)
744  {
745  exception = true;
746  }
747 
748  DALI_TEST_CHECK( properties[i].animatable != exception );
749  }
750  END_TEST;
751 }
752 
754 {
755  TestApplication application;
756 
757  Handle handle = Handle::New();
758 
759  float startValue(1.0f);
760  Property::Index index = handle.RegisterProperty( "testProperty", startValue );
761  DALI_TEST_CHECK( handle.GetProperty<float>(index) == startValue );
762 
763  application.SendNotification();
764  application.Render(0);
765  DALI_TEST_CHECK( handle.GetProperty<float>(index) == startValue );
766  application.Render(0);
767  DALI_TEST_CHECK( handle.GetProperty<float>(index) == startValue );
768 
769  handle.SetProperty( index, 5.0f );
770 
771  application.SendNotification();
772  application.Render(0);
773  DALI_TEST_CHECK( handle.GetProperty<float>(index) == 5.0f );
774  application.Render(0);
775  DALI_TEST_CHECK( handle.GetProperty<float>(index) == 5.0f );
776  END_TEST;
777 }
778 
780 {
781  TestApplication application;
782 
783  Handle handle = WeightObject::New();;
784  DALI_TEST_CHECK( handle.GetProperty<float>(WeightObject::WEIGHT) == 0.0f );
785 
786  END_TEST;
787 }
788 
Dali Docs Home
Read more about Dali