Print log if TypeInfo asserted + Do not assert if we call SetProperty for readonly... 53/314153/2
authorEunki, Hong <eunkiki.hong@samsung.com>
Mon, 8 Jul 2024 01:52:43 +0000 (10:52 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Tue, 9 Jul 2024 03:28:25 +0000 (12:28 +0900)
Change-Id: Ia910ced0e022f95a262cd508b02b31917b1e3a83
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali/utc-Dali-CSharp-TypeRegistry.cpp
automated-tests/src/dali/utc-Dali-TypeRegistry.cpp
dali/internal/event/common/type-info-impl.cpp

index bf4a348..b536c2a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -181,13 +181,43 @@ int UtcDaliRegisterCSharpPropertyN(void)
   END_TEST;
 }
 
+int UtcDaliCSharpPropertyRegistrationFunctions(void)
+{
+  TestApplication application;
+  int             propertyIndex = PROPERTY_REGISTRATION_START_INDEX + 10;
+
+  CSharpTypeRegistry::RegisterType("DateControl", typeid(Dali::Actor), &CreateCustomNamedInit);
+
+  // Attempt to register a property without a setter
+  try
+  {
+    CSharpTypeRegistry::RegisterProperty("DateControl", "propName1", propertyIndex++, Property::BOOLEAN, NULL, GetProperty);
+    tet_result(TET_PASS);
+  }
+  catch(DaliException& e)
+  {
+    tet_result(TET_FAIL);
+  }
+
+  // Attempt to register a property without a getter
+  try
+  {
+    CSharpTypeRegistry::RegisterProperty("DateControl", "propName2", propertyIndex++, Property::BOOLEAN, NULL, NULL);
+    tet_result(TET_FAIL);
+  }
+  catch(DaliException& e)
+  {
+    DALI_TEST_ASSERT(e, "!\"GetProperty", TEST_LOCATION);
+  }
+  END_TEST;
+}
+
 int UtcDaliRegisterCSharpPropertySetP(void)
 {
   TestApplication application;
 
   // register the same property twice
   CSharpTypeRegistry::RegisterType("DateControl", typeid(Dali::Actor), &CreateCustomNamedInit);
-  ;
 
   Property::Index index(100001);
 
@@ -222,6 +252,40 @@ int UtcDaliRegisterCSharpPropertySetP(void)
   END_TEST;
 }
 
+int UtcDaliRegisterCSharpPropertySetN(void)
+{
+  TestApplication application;
+
+  // register the same property twice
+  CSharpTypeRegistry::RegisterType("DateControl", typeid(Dali::Actor), &CreateCustomNamedInit);
+
+  Property::Index index(100001);
+
+  CSharpTypeRegistry::RegisterProperty("DateControl",
+                                       "readonly",
+                                       index,
+                                       Property::INTEGER,
+                                       nullptr,
+                                       GetProperty);
+
+  TypeRegistry typeRegistry = TypeRegistry::Get();
+
+  TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo("DateControl");
+
+  // Check the property is writable in the type registry
+  Internal::TypeInfo& typeInfoImpl = GetImplementation(typeInfo);
+
+  Property::Value value(50);
+
+  typeInfoImpl.SetProperty(NULL, index, value);
+  DALI_TEST_EQUALS(setPropertyCalled, false, TEST_LOCATION);
+
+  typeInfoImpl.SetProperty(NULL, "readonly", value);
+  DALI_TEST_EQUALS(setPropertyCalled, false, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliRegisterCSharpPropertyGetP(void)
 {
   TestApplication application;
index 7c7f875..9a2ab58 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1162,7 +1162,7 @@ int UtcDaliTypeRegistryAnimatablePropertyRegistrationP(void)
   END_TEST;
 }
 
-int UtcDaliTypeRegistryAnimatablePropertyRegistrationN(void)
+int UtcDaliTypeRegistryAnimatablePropertyRegistrationN01(void)
 {
   TestApplication application;
   TypeRegistry    typeRegistry = TypeRegistry::Get();
@@ -1192,6 +1192,27 @@ int UtcDaliTypeRegistryAnimatablePropertyRegistrationN(void)
   END_TEST;
 }
 
+int UtcDaliTypeRegistryAnimatablePropertyRegistrationN02(void)
+{
+  TestApplication application;
+  TypeRegistry    typeRegistry = TypeRegistry::Get();
+
+  AnimatablePropertyRegistration property1(customType1, "animPropName", ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1, Property::BOOLEAN);
+
+  // Attempt to register an animatable property with the same index
+  try
+  {
+    AnimatablePropertyRegistration property1(customType1, "animPropName2", ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1, Property::BOOLEAN);
+    tet_result(TET_FAIL);
+  }
+  catch(DaliException& e)
+  {
+    DALI_TEST_ASSERT(e, "!\"Property index already added to Type\"", TEST_LOCATION);
+  }
+
+  END_TEST;
+}
+
 int UtcDaliTypeRegistryAnimatablePropertyRegistrationWithDefaultP(void)
 {
   TestApplication application;
@@ -1268,7 +1289,7 @@ int UtcDaliTypeRegistryAnimatablePropertyRegistrationWithDefaultP(void)
   END_TEST;
 }
 
-int UtcDaliTypeRegistryAnimatablePropertyRegistrationWithDefaultN(void)
+int UtcDaliTypeRegistryAnimatablePropertyRegistrationWithDefaultN01(void)
 {
   TestApplication application;
   TypeRegistry    typeRegistry = TypeRegistry::Get();
@@ -1298,6 +1319,27 @@ int UtcDaliTypeRegistryAnimatablePropertyRegistrationWithDefaultN(void)
   END_TEST;
 }
 
+int UtcDaliTypeRegistryAnimatablePropertyRegistrationWithDefaultN02(void)
+{
+  TestApplication application;
+  TypeRegistry    typeRegistry = TypeRegistry::Get();
+
+  AnimatablePropertyRegistration property1(customType1, "animPropName", ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1, false);
+
+  // Attempt to register an animatable property with the same index
+  try
+  {
+    AnimatablePropertyRegistration property1(customType1, "animPropName2", ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1, false);
+    tet_result(TET_FAIL);
+  }
+  catch(DaliException& e)
+  {
+    DALI_TEST_ASSERT(e, "!\"Property index already added to Type\"", TEST_LOCATION);
+  }
+
+  END_TEST;
+}
+
 int UtcDaliTypeRegistryAnimatablePropertyComponentRegistrationP(void)
 {
   TestApplication application;
@@ -1936,7 +1978,7 @@ int UtcDaliPropertyRegistrationFunctions(void)
   // Attempt to register a property without a setter
   try
   {
-    PropertyRegistration property1(customType1, "propName", propertyIndex++, Property::BOOLEAN, NULL, &GetProperty);
+    PropertyRegistration property1(customType1, "propName1", propertyIndex++, Property::BOOLEAN, NULL, &GetProperty);
     tet_result(TET_PASS);
   }
   catch(DaliException& e)
@@ -1947,7 +1989,7 @@ int UtcDaliPropertyRegistrationFunctions(void)
   // Attempt to register a property without a getter
   try
   {
-    PropertyRegistration property1(customType1, "propName", propertyIndex++, Property::BOOLEAN, NULL, NULL);
+    PropertyRegistration property1(customType1, "propName2", propertyIndex++, Property::BOOLEAN, NULL, NULL);
     tet_result(TET_FAIL);
   }
   catch(DaliException& e)
@@ -2018,11 +2060,42 @@ int UtcDaliPropertyRegistrationPropertyWritableP(void)
   Internal::TypeInfo& typeInfoImpl = GetImplementation(typeInfo);
 
   DALI_TEST_EQUALS(typeInfoImpl.IsPropertyWritable(propertyIndex1), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(typeInfoImpl.IsPropertyWritable(propertyIndex2), false, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPropertyRegistrationPropertyWritableN01(void)
+{
+  TestApplication application;
+  int             propertyIndex1 = PROPERTY_REGISTRATION_START_INDEX + 200;
+  int             propertyIndex2 = PROPERTY_REGISTRATION_START_INDEX + 201;
+
+  // Add two properties, one with SetProperty, one without
+  PropertyRegistration property1(customType1, "propNameReadwrite", propertyIndex1, Property::BOOLEAN, &SetProperty, &GetProperty);
+  PropertyRegistration property2(customType1, "propNameReadonly", propertyIndex2, Property::BOOLEAN, NULL, &GetProperty);
+
+  // Create custom-actor
+  TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo(typeid(MyTestCustomActor));
+  DALI_TEST_CHECK(typeInfo);
+  BaseHandle handle = typeInfo.CreateInstance();
+  DALI_TEST_CHECK(handle);
+  Actor customActor = Actor::DownCast(handle);
+  DALI_TEST_CHECK(customActor);
+
+  // Check SetProperty and GetProperty works well for Readwrite
+  setPropertyCalled = false;
+  customActor.SetProperty(propertyIndex1, true);
+  DALI_TEST_EQUALS(setPropertyCalled, true, TEST_LOCATION);
+
+  setPropertyCalled = false;
+  customActor.SetProperty(propertyIndex2, true);
+  DALI_TEST_EQUALS(setPropertyCalled, false, TEST_LOCATION);
 
   END_TEST;
 }
 
-int UtcDaliPropertyRegistrationPropertyWritableN(void)
+int UtcDaliPropertyRegistrationPropertyWritableN02(void)
 {
   TypeInfo            typeInfo     = TypeRegistry::Get().GetTypeInfo(typeid(MyTestCustomActor));
   Internal::TypeInfo& typeInfoImpl = GetImplementation(typeInfo);
index e5e90e7..77dd25d 100644 (file)
@@ -133,7 +133,7 @@ inline bool GetBaseType(Internal::TypeInfo*& baseType, TypeRegistry& typeRegistr
   // if greater than unresolved means we have a base type, null means no base
   bool baseExists = (baseType > UNRESOLVED);
   // base only needs to be resolved once
-  if(UNRESOLVED == baseType)
+  if(DALI_UNLIKELY(UNRESOLVED == baseType))
   {
     TypeRegistry::TypeInfoPointer base = typeRegistry.GetTypeInfo(baseTypeName);
     if(base)
@@ -438,13 +438,13 @@ std::string_view TypeInfo::GetPropertyName(Property::Index index) const
 
 void TypeInfo::AddActionFunction(std::string actionName, Dali::TypeInfo::ActionFunction function)
 {
-  if(nullptr == function)
+  if(DALI_UNLIKELY(nullptr == function))
   {
     DALI_LOG_WARNING("Action function is empty\n");
   }
   else
   {
-    if(!mActions.Register(ConstString(actionName), function))
+    if(DALI_UNLIKELY(!mActions.Register(ConstString(actionName), function)))
     {
       DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
     }
@@ -453,13 +453,13 @@ void TypeInfo::AddActionFunction(std::string actionName, Dali::TypeInfo::ActionF
 
 void TypeInfo::AddConnectorFunction(std::string signalName, Dali::TypeInfo::SignalConnectorFunction function)
 {
-  if(nullptr == function)
+  if(DALI_UNLIKELY(nullptr == function))
   {
     DALI_LOG_WARNING("Connector function is empty\n");
   }
   else
   {
-    if(!mSignalConnectors.Register(ConstString(signalName), function))
+    if(DALI_UNLIKELY(!mSignalConnectors.Register(ConstString(signalName), function)))
     {
       DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str());
     }
@@ -470,14 +470,16 @@ void TypeInfo::AddProperty(std::string name, Property::Index index, Property::Ty
 {
   // The setter can be empty as a property can be read-only.
 
-  if(nullptr == getFunc)
+  if(DALI_UNLIKELY(nullptr == getFunc))
   {
+    DALI_LOG_ERROR("GetProperty Function is empty! name:%s, index:%d, type:%d\n", name.c_str(), index, static_cast<int32_t>(type));
     DALI_ASSERT_ALWAYS(!"GetProperty Function is empty");
   }
   else
   {
-    if(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+    if(DALI_UNLIKELY(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))))
     {
+      DALI_LOG_ERROR("Property index already added to Type! name:%s, index:%d, type:%d\n", name.c_str(), index, static_cast<int32_t>(type));
       DALI_ASSERT_ALWAYS(!"Property index already added to Type");
     }
   }
@@ -487,14 +489,16 @@ void TypeInfo::AddProperty(std::string name, Property::Index index, Property::Ty
 {
   // The setter can be empty as a property can be read-only.
 
-  if(nullptr == getFunc)
+  if(DALI_UNLIKELY(nullptr == getFunc))
   {
+    DALI_LOG_ERROR("GetProperty Function is empty! name:%s, index:%d, type:%d\n", name.c_str(), index, static_cast<int32_t>(type));
     DALI_ASSERT_ALWAYS(!"GetProperty Function is empty");
   }
   else
   {
-    if(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+    if(DALI_UNLIKELY(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))))
     {
+      DALI_LOG_ERROR("Property index already added to Type! name:%s, index:%d, type:%d\n", name.c_str(), index, static_cast<int32_t>(type));
       DALI_ASSERT_ALWAYS(!"Property index already added to Type");
     }
   }
@@ -502,16 +506,18 @@ void TypeInfo::AddProperty(std::string name, Property::Index index, Property::Ty
 
 void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Type type)
 {
-  if(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+  if(DALI_UNLIKELY(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))))
   {
+    DALI_LOG_ERROR("Property index already added to Type! name:%s, index:%d, type:%d\n", name.c_str(), index, static_cast<int32_t>(type));
     DALI_ASSERT_ALWAYS(!"Property index already added to Type");
   }
 }
 
 void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Value defaultValue)
 {
-  if(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(defaultValue.GetType(), ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+  if(DALI_UNLIKELY(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(defaultValue.GetType(), ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))))
   {
+    DALI_LOG_ERROR("Property index already added to Type! name:%s, index:%d\n", name.c_str(), index);
     DALI_ASSERT_ALWAYS(!"Property index already added to Type");
   }
   else
@@ -523,28 +529,37 @@ void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Pr
 void TypeInfo::AddAnimatablePropertyComponent(std::string name, Property::Index index, Property::Index baseIndex, uint32_t componentIndex)
 {
   Property::Type type = GetPropertyType(baseIndex);
-  DALI_ASSERT_ALWAYS((type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4) && "Base property does not support component");
+  if(DALI_UNLIKELY(!(type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4)))
+  {
+    DALI_LOG_ERROR("Base property does not support component! name:%s, index:%d, baseIndex:%d, component:%d, type:%d\n", name.c_str(), index, baseIndex, static_cast<int32_t>(componentIndex), static_cast<int32_t>(type));
+    DALI_ASSERT_ALWAYS(!"Base property does not support component");
+  }
 
   bool success = false;
 
-  if(mRegisteredProperties.Get(static_cast<std::uint32_t>(index)) == mRegisteredProperties.end())
+  if(DALI_LIKELY(mRegisteredProperties.Get(static_cast<std::uint32_t>(index)) == mRegisteredProperties.end()))
   {
     const auto& iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PropertyComponentFinder<RegisteredPropertyPair>(baseIndex, componentIndex));
 
-    if(iter == mRegisteredProperties.end())
+    if(DALI_LIKELY(iter == mRegisteredProperties.end()))
     {
       mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, ConstString(name), baseIndex, componentIndex));
       success = true;
     }
   }
 
-  DALI_ASSERT_ALWAYS(success && "Property component already registered");
+  if(DALI_UNLIKELY(!success))
+  {
+    DALI_LOG_ERROR("Property component already registered! name:%s, index:%d, baseIndex:%d, component:%d\n", name.c_str(), index, baseIndex, static_cast<int32_t>(componentIndex));
+    DALI_ASSERT_ALWAYS(!"Property component already registered");
+  }
 }
 
 void TypeInfo::AddChildProperty(std::string name, Property::Index index, Property::Type type)
 {
-  if(!mRegisteredChildProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+  if(DALI_UNLIKELY(!mRegisteredChildProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))))
   {
+    DALI_LOG_ERROR("Property index already added to Type! name:%s, index:%d, type:%d\n", name.c_str(), index, static_cast<int32_t>(type));
     DALI_ASSERT_ALWAYS(!"Property index already added to Type");
   }
 }
@@ -882,19 +897,26 @@ void TypeInfo::SetProperty(BaseObject* object, Property::Index index, Property::
   const auto& iter = mRegisteredProperties.Get(static_cast<std::uint32_t>(index));
   if(iter != mRegisteredProperties.end())
   {
-    if(iter->second.setFunc)
+    if(mCSharpType)
     {
-      if(mCSharpType)
+      if(DALI_UNLIKELY(nullptr == iter->second.cSharpSetFunc))
       {
-        // CSharp wants a property name not an index
-        auto name = (iter->second).name;
-
-        iter->second.cSharpSetFunc(object, name.GetCString(), const_cast<Property::Value*>(&value));
+        DALI_LOG_ERROR("Trying to write to a read-only property! name:%s, index:%d, object:%p\n", (iter->second).name.GetCString(), static_cast<int32_t>(index), object);
+        return;
       }
-      else
+      // CSharp wants a property name not an index
+      auto name = (iter->second).name;
+
+      iter->second.cSharpSetFunc(object, name.GetCString(), const_cast<Property::Value*>(&value));
+    }
+    else
+    {
+      if(DALI_UNLIKELY(nullptr == iter->second.setFunc))
       {
-        iter->second.setFunc(object, index, value);
+        DALI_LOG_ERROR("Trying to write to a read-only property! name:%s, index:%d, object:%p\n", (iter->second).name.GetCString(), static_cast<int32_t>(index), object);
+        return;
       }
+      iter->second.setFunc(object, index, value);
     }
   }
   else if(GetBaseType(mBaseType, mTypeRegistry, mBaseTypeName))
@@ -914,15 +936,23 @@ void TypeInfo::SetProperty(BaseObject* object, const std::string& name, Property
   RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PropertyNameFinder<RegisteredPropertyPair>(ConstString(name)));
   if(iter != mRegisteredProperties.end())
   {
-    DALI_ASSERT_ALWAYS(iter->second.setFunc && "Trying to write to a read-only property");
-
     if(mCSharpType)
     {
+      if(DALI_UNLIKELY(nullptr == iter->second.cSharpSetFunc))
+      {
+        DALI_LOG_ERROR("Trying to write to a read-only property! name:%s, index:%d, object:%p\n", name.c_str(), static_cast<int32_t>(iter->first), object);
+        return;
+      }
       // CSharp wants a property name not an index
       iter->second.cSharpSetFunc(object, name.c_str(), const_cast<Property::Value*>(&value));
     }
     else
     {
+      if(DALI_UNLIKELY(nullptr == iter->second.setFunc))
+      {
+        DALI_LOG_ERROR("Trying to write to a read-only property! name:%s, index:%d, object:%p\n", name.c_str(), static_cast<int32_t>(iter->first), object);
+        return;
+      }
       iter->second.setFunc(object, iter->first, value);
     }
   }