From b123507d545f2c406dd2b54fad076d0af710eed5 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Mon, 8 Jul 2024 10:52:43 +0900 Subject: [PATCH] Print log if TypeInfo asserted + Do not assert if we call SetProperty for readonly + Add keyword LIKELY / UNLIKELY Change-Id: Ia910ced0e022f95a262cd508b02b31917b1e3a83 Signed-off-by: Eunki, Hong --- .../src/dali/utc-Dali-CSharp-TypeRegistry.cpp | 68 ++++++++++++++++- automated-tests/src/dali/utc-Dali-TypeRegistry.cpp | 85 ++++++++++++++++++++-- dali/internal/event/common/type-info-impl.cpp | 82 ++++++++++++++------- 3 files changed, 201 insertions(+), 34 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-CSharp-TypeRegistry.cpp b/automated-tests/src/dali/utc-Dali-CSharp-TypeRegistry.cpp index bf4a348..b536c2a 100644 --- a/automated-tests/src/dali/utc-Dali-CSharp-TypeRegistry.cpp +++ b/automated-tests/src/dali/utc-Dali-CSharp-TypeRegistry.cpp @@ -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; diff --git a/automated-tests/src/dali/utc-Dali-TypeRegistry.cpp b/automated-tests/src/dali/utc-Dali-TypeRegistry.cpp index 7c7f875..9a2ab58 100644 --- a/automated-tests/src/dali/utc-Dali-TypeRegistry.cpp +++ b/automated-tests/src/dali/utc-Dali-TypeRegistry.cpp @@ -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); diff --git a/dali/internal/event/common/type-info-impl.cpp b/dali/internal/event/common/type-info-impl.cpp index e5e90e7..77dd25d 100644 --- a/dali/internal/event/common/type-info-impl.cpp +++ b/dali/internal/event/common/type-info-impl.cpp @@ -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(type)); DALI_ASSERT_ALWAYS(!"GetProperty Function is empty"); } else { - if(!mRegisteredProperties.Register(static_cast(index), RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))) + if(DALI_UNLIKELY(!mRegisteredProperties.Register(static_cast(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(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(type)); DALI_ASSERT_ALWAYS(!"GetProperty Function is empty"); } else { - if(!mRegisteredProperties.Register(static_cast(index), RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))) + if(DALI_UNLIKELY(!mRegisteredProperties.Register(static_cast(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(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(index), RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))) + if(DALI_UNLIKELY(!mRegisteredProperties.Register(static_cast(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(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(index), RegisteredProperty(defaultValue.GetType(), ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))) + if(DALI_UNLIKELY(!mRegisteredProperties.Register(static_cast(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(componentIndex), static_cast(type)); + DALI_ASSERT_ALWAYS(!"Base property does not support component"); + } bool success = false; - if(mRegisteredProperties.Get(static_cast(index)) == mRegisteredProperties.end()) + if(DALI_LIKELY(mRegisteredProperties.Get(static_cast(index)) == mRegisteredProperties.end())) { const auto& iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PropertyComponentFinder(baseIndex, componentIndex)); - if(iter == mRegisteredProperties.end()) + if(DALI_LIKELY(iter == mRegisteredProperties.end())) { mRegisteredProperties.Register(static_cast(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(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(index), RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX))) + if(DALI_UNLIKELY(!mRegisteredChildProperties.Register(static_cast(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(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(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(&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(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(&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(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(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(iter->first), object); + return; + } // CSharp wants a property name not an index iter->second.cSharpSetFunc(object, name.c_str(), const_cast(&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(iter->first), object); + return; + } iter->second.setFunc(object, iter->first, value); } } -- 2.7.4