Let we give constraint tag's range for custom and internal.
The tags what we can control as public is only for custom ranges,
and make internal constraint didn't removed.
Change-Id: I0ab45d4ed258cdcd30f4c98a61b0a0251cf4c692
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
utc-Dali-Internal-AnimatableProperty.cpp
utc-Dali-Internal-ActorObserver.cpp
utc-Dali-Internal-ActorRelayout.cpp
+ utc-Dali-Internal-Constraint.cpp
utc-Dali-Internal-ConstString.cpp
utc-Dali-Internal-Core.cpp
utc-Dali-Internal-Debug.cpp
--- /dev/null
+/*
+* Copyright (c) 2025 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.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#include <dali-test-suite-utils.h>
+#include <dali/integration-api/constraint-integ.h>
+#include <dali/public-api/dali-core.h>
+
+using namespace Dali;
+
+void utc_dali_internal_constraint_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_internal_constraint_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+/**
+ * A function to use for a constraint, no data collected.
+ */
+template<typename T>
+void BasicFunction(T& /* current */, const PropertyInputContainer& /* inputs */)
+{
+}
+
+/**
+ * TestConstraint reference.
+ * When constraint is called, the resultRef is updated
+ * with the value supplied.
+ */
+template<typename T>
+struct TestConstraintRef
+{
+ TestConstraintRef(unsigned int& resultRef, unsigned int value)
+ : mResultRef(resultRef),
+ mValue(value)
+ {
+ }
+
+ void operator()(T& current, const PropertyInputContainer& /* inputs */)
+ {
+ mResultRef = mValue;
+ }
+
+ unsigned int& mResultRef;
+ unsigned int mValue;
+};
+} // namespace
+
+int UtcDaliInternalConstraintSetInternalTag(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
+ DALI_TEST_EQUALS(constraint.GetTag(), 0u, TEST_LOCATION);
+
+ const uint32_t tag = Dali::ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START;
+ Dali::Integration::ConstraintSetInternalTag(constraint, tag);
+ DALI_TEST_EQUALS(constraint.GetTag(), tag, TEST_LOCATION);
+
+ const uint32_t tag2 = Dali::ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_MAX;
+ Dali::Integration::ConstraintSetInternalTag(constraint, tag2);
+ DALI_TEST_EQUALS(constraint.GetTag(), tag2, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliInternalConstraintSetInternalTagN01(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
+ DALI_TEST_EQUALS(constraint.GetTag(), 0u, TEST_LOCATION);
+
+ try
+ {
+ const uint32_t tag = Dali::ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START - 1u;
+ Dali::Integration::ConstraintSetInternalTag(constraint, tag);
+ DALI_TEST_CHECK(false); // Should not reach here!
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+ END_TEST;
+}
+
+int UtcDaliInternalConstraintSetInternalTagN02(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
+ DALI_TEST_EQUALS(constraint.GetTag(), 0u, TEST_LOCATION);
+
+ try
+ {
+ const uint32_t tag = Dali::ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_MAX + 1u;
+ Dali::Integration::ConstraintSetInternalTag(constraint, tag);
+ DALI_TEST_CHECK(false); // Should not reach here!
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+ END_TEST;
+}
+
+int UtcDaliInternalConstraintSetInternalTagN03(void)
+{
+ tet_infoline("Do not allow to set cross-tag between custom and internal.");
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ Constraint constraint1 = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
+ DALI_TEST_EQUALS(constraint1.GetTag(), Dali::ConstraintTagRanges::DEFAULT_TAG, TEST_LOCATION);
+
+ Constraint constraint2 = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
+ DALI_TEST_EQUALS(constraint2.GetTag(), Dali::ConstraintTagRanges::DEFAULT_TAG, TEST_LOCATION);
+
+ const uint32_t internalTag = Dali::ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START;
+ Dali::Integration::ConstraintSetInternalTag(constraint1, internalTag);
+ DALI_TEST_EQUALS(constraint1.GetTag(), internalTag, TEST_LOCATION);
+
+ const uint32_t customTag = Dali::ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_START;
+ constraint2.SetTag(customTag);
+ DALI_TEST_EQUALS(constraint2.GetTag(), customTag, TEST_LOCATION);
+ try
+ {
+ constraint1.SetTag(customTag);
+ DALI_TEST_CHECK(false); // Should not reach here!
+ }
+ catch(DaliException& e)
+ {
+ DALI_TEST_ASSERT(e, "\"Cross tag setting is not allowed!\"", TEST_LOCATION);
+ }
+
+ try
+ {
+ Dali::Integration::ConstraintSetInternalTag(constraint2, internalTag);
+ DALI_TEST_CHECK(false); // Should not reach here!
+ }
+ catch(DaliException& e)
+ {
+ DALI_TEST_ASSERT(e, "\"Cross tag setting is not allowed!\"", TEST_LOCATION);
+ }
+
+ // But allow to set Default tag, which is 0
+ constraint1.SetTag(Dali::ConstraintTagRanges::DEFAULT_TAG);
+ DALI_TEST_EQUALS(constraint1.GetTag(), Dali::ConstraintTagRanges::DEFAULT_TAG, TEST_LOCATION);
+ constraint2.SetTag(Dali::ConstraintTagRanges::DEFAULT_TAG);
+ DALI_TEST_EQUALS(constraint2.GetTag(), Dali::ConstraintTagRanges::DEFAULT_TAG, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliInternalConstraintHandleRemoveConstraints(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+
+ uint32_t result1 = 0u;
+ uint32_t result2 = 0u;
+ uint32_t result3 = 0u;
+ uint32_t result4 = 0u;
+
+ uint32_t constraint1Tag = 1u;
+ Constraint constraint1 = Constraint::New<Vector4>(actor, Actor::Property::COLOR, TestConstraintRef<Vector4>(result1, 1));
+ constraint1.SetTag(constraint1Tag);
+ constraint1.Apply();
+
+ uint32_t constraint2Tag = 2u;
+ Constraint constraint2 = Constraint::New<Vector4>(actor, Actor::Property::COLOR, TestConstraintRef<Vector4>(result2, 2));
+ constraint2.SetTag(constraint2Tag);
+ constraint2.Apply();
+
+ uint32_t internalConstraint3Tag = Dali::ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START + 1u;
+ Constraint internalConstraint3 = Constraint::New<Vector4>(actor, Actor::Property::COLOR, TestConstraintRef<Vector4>(result3, 3));
+ Dali::Integration::ConstraintSetInternalTag(internalConstraint3, internalConstraint3Tag);
+ internalConstraint3.Apply();
+
+ uint32_t internalConstraint4Tag = Dali::ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START + 2u;
+ Constraint internalConstraint4 = Constraint::New<Vector4>(actor, Actor::Property::COLOR, TestConstraintRef<Vector4>(result4, 4));
+ Dali::Integration::ConstraintSetInternalTag(internalConstraint4, internalConstraint4Tag);
+ internalConstraint4.Apply();
+
+ application.GetScene().Add(actor);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result2, 2u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result3, 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result4, 4u, TEST_LOCATION);
+
+ tet_printf("Test 1 : Handle::RemoveConstraints() didnt remove internal constraints\n");
+
+ result1 = result2 = result3 = result4 = 0u;
+
+ actor.RemoveConstraints();
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 0u, TEST_LOCATION); // constraint1 didnt applied
+ DALI_TEST_EQUALS(result2, 0u, TEST_LOCATION); // constraint2 didnt applied
+ DALI_TEST_EQUALS(result3, 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result4, 4u, TEST_LOCATION);
+
+ // Re-apply removed constraints for next tests.
+ result1 = result2 = result3 = result4 = 0u;
+
+ constraint1.Apply();
+ constraint2.Apply();
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result2, 2u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result3, 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result4, 4u, TEST_LOCATION);
+
+ tet_printf("Test 2 : Integration::HandleRemoveConstraints(tag) to remove internal constraints\n");
+
+ result1 = result2 = result3 = result4 = 0u;
+
+ Dali::Integration::HandleRemoveConstraints(actor, internalConstraint4Tag);
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result2, 2u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result3, 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result4, 0u, TEST_LOCATION); // internalConstraint4 didnt applied
+
+ result1 = result2 = result3 = result4 = 0u;
+
+ Dali::Integration::HandleRemoveConstraints(actor, internalConstraint3Tag);
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result2, 2u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result3, 0u, TEST_LOCATION); // internalConstraint3 didnt applied
+ DALI_TEST_EQUALS(result4, 0u, TEST_LOCATION); // internalConstraint4 didnt applied
+
+ // Re-apply removed constraints for next tests.
+ result1 = result2 = result3 = result4 = 0u;
+
+ internalConstraint3.Apply();
+ internalConstraint4.Apply();
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result2, 2u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result3, 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result4, 4u, TEST_LOCATION);
+
+ tet_printf("Test 3 : Integration::HandleRemoveConstraints(tagBegin, tagEnd) to remove multiple internal constraints\n");
+
+ result1 = result2 = result3 = result4 = 0u;
+
+ Dali::Integration::HandleRemoveConstraints(actor, internalConstraint3Tag, internalConstraint4Tag + 100u);
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result2, 2u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result3, 0u, TEST_LOCATION); // internalConstraint3 didnt applied
+ DALI_TEST_EQUALS(result4, 0u, TEST_LOCATION); // internalConstraint4 didnt applied
+
+ // Re-apply removed constraints for next tests.
+ result1 = result2 = result3 = result4 = 0u;
+
+ internalConstraint3.Apply();
+ internalConstraint4.Apply();
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result2, 2u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result3, 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result4, 4u, TEST_LOCATION);
+
+ tet_printf("Test 4 : Integration::HandleRemoveAllConstraints() to remove every constraints both custom and internal\n");
+
+ result1 = result2 = result3 = result4 = 0u;
+
+ Dali::Integration::HandleRemoveAllConstraints(actor);
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 0u, TEST_LOCATION); // constraint1 didnt applied
+ DALI_TEST_EQUALS(result2, 0u, TEST_LOCATION); // constraint2 didnt applied
+ DALI_TEST_EQUALS(result3, 0u, TEST_LOCATION); // internalConstraint3 didnt applied
+ DALI_TEST_EQUALS(result4, 0u, TEST_LOCATION); // internalConstraint4 didnt applied
+
+ END_TEST;
+}
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
DALI_TEST_EQUALS(result2, 2u, TEST_LOCATION);
- // 2. Remove Constraint2 and test...
+ // 4. Remove Constraint2 and test...
result1 = 0;
result2 = 0;
actor.RemoveConstraints(constraint2Tag);
DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
DALI_TEST_EQUALS(result2, 0u, TEST_LOCATION); ///< constraint 2 should not apply now.
- // 2. Remove Constraint1 as well and test...
+ // 5. Remove Constraint1 as well and test...
result1 = 0;
result2 = 0;
actor.RemoveConstraints(constraint1Tag);
application.SendNotification();
application.Render();
+ DALI_TEST_EQUALS(result1, 0u, TEST_LOCATION); ///< constraint 1 should not apply now.
+ DALI_TEST_EQUALS(result2, 0u, TEST_LOCATION); ///< constraint 2 should not apply now.
+
+ // 5. Re-Apply Constraint1 and test...
+ result1 = 0;
+ result2 = 0;
+ constraint1.Apply();
+ constraint2.Apply();
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(result1, 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(result2, 2u, TEST_LOCATION);
+
+ // 6. Remove Constraint1 and 2, and test...
+ result1 = 0;
+ result2 = 0;
+ actor.RemoveConstraints(constraint1Tag, constraint2Tag + 1u);
+ // make color property dirty, which will trigger constraints to be reapplied.
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
DALI_TEST_EQUALS(result1, 0u, TEST_LOCATION); ///< constraint 1 should not apply now.
DALI_TEST_EQUALS(result2, 0u, TEST_LOCATION); ///< constraint 2 should not apply now.
END_TEST;
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
constraint.SetTag(tag);
DALI_TEST_EQUALS(constraint.GetTag(), tag, TEST_LOCATION);
+ const unsigned int tag2 = Dali::ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX;
+ constraint.SetTag(tag2);
+ DALI_TEST_EQUALS(constraint.GetTag(), tag2, TEST_LOCATION);
+
END_TEST;
}
-int UtcDaliConstraintSetTagN(void)
+int UtcDaliConstraintSetTagN1(void)
{
// Attempt to set from uninitialised constraint
END_TEST;
}
+int UtcDaliConstraintSetTagN2(void)
+{
+ // Attempt to set out of custom tag ranges
+
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
+ DALI_TEST_EQUALS(constraint.GetTag(), 0u, TEST_LOCATION);
+
+ try
+ {
+ const uint32_t tag = Dali::ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX + 1u;
+ constraint.SetTag(tag);
+ DALI_TEST_CHECK(false); // Should not reach here!
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
+
int UtcDaliConstraintGetTagN(void)
{
// Attempt to retrieve from uninitialised constraint
END_TEST;
}
-
namespace PostConstraintTest
{
void CheckComponentProperty(TestApplication& application, Actor& actor, Handle target)
DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3::ONE, TEST_LOCATION);
Property::Index prePropertyIndex = target.RegisterProperty("testPreProperty", Vector3::ZERO);
- Constraint preConstraint = Constraint::New<Vector3>(target, prePropertyIndex, [](Vector3& output, const PropertyInputContainer& inputs) {
+ Constraint preConstraint = Constraint::New<Vector3>(target, prePropertyIndex, [](Vector3& output, const PropertyInputContainer& inputs) {
output = inputs[0]->GetVector3();
});
preConstraint.AddSource(Source{actor, Actor::Property::WORLD_POSITION});
preConstraint.Apply();
Property::Index postPropertyIndex = target.RegisterProperty("testPostProperty", Vector3::ZERO);
- Constraint postConstraint = Constraint::New<Vector3>(target, postPropertyIndex, [](Vector3& output, const PropertyInputContainer& inputs) {
+ Constraint postConstraint = Constraint::New<Vector3>(target, postPropertyIndex, [](Vector3& output, const PropertyInputContainer& inputs) {
output = inputs[0]->GetVector3();
});
postConstraint.AddSource(Source{actor, Actor::Property::WORLD_POSITION});
preConstraint.Remove();
postConstraint.Remove();
}
-}
+} // namespace PostConstraintTest
int UtcDaliConstraintApplyPost(void)
{
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
END_TEST;
}
+int UtcDaliHandleRemoveConstraintsNegative03(void)
+{
+ TestApplication application;
+ Dali::Handle instance;
+ try
+ {
+ unsigned int arg1(0u);
+ unsigned int arg2(3u);
+ instance.RemoveConstraints(arg1, arg2);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliHandleRemoveConstraintsNegative04(void)
+{
+ TestApplication application;
+ Dali::Handle instance = Dali::Handle::New();
+ try
+ {
+ unsigned int arg1(0u);
+ unsigned int arg2(Dali::ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX + 2u);
+ instance.RemoveConstraints(arg1, arg2);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
int UtcDaliHandleAddPropertyNotificationNegative01(void)
{
TestApplication application;
--- /dev/null
+/*
+ * Copyright (c) 2025 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali/integration-api/constraint-integ.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/animation/constraint-impl.h>
+#include <dali/internal/event/common/object-impl.h>
+
+namespace Dali::Integration
+{
+void ConstraintSetInternalTag(Dali::Constraint& constraint, const uint32_t tag)
+{
+ DALI_ASSERT_ALWAYS(ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START <= tag && tag <= ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_MAX && "Out of tag range!");
+ GetImplementation(constraint).SetTag(tag);
+}
+
+void HandleRemoveAllConstraints(Dali::Handle& handle)
+{
+ GetImplementation(handle).RemoveConstraints();
+}
+
+void HandleRemoveConstraints(Dali::Handle& handle, uint32_t tag)
+{
+ DALI_ASSERT_ALWAYS(ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START <= tag && tag <= ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_MAX && "Out of tag range!");
+ GetImplementation(handle).RemoveConstraints(tag);
+}
+
+void HandleRemoveConstraints(Dali::Handle& handle, uint32_t tagBegin, uint32_t tagEnd)
+{
+ DALI_ASSERT_ALWAYS(ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START <= tagBegin && tagEnd <= ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_MAX + 1u && "Out of tag range!");
+ GetImplementation(handle).RemoveConstraints(tagBegin, tagEnd);
+}
+} // namespace Dali::Integration
--- /dev/null
+#ifndef DALI_CONSTRAINT_INTEG_H
+#define DALI_CONSTRAINT_INTEG_H
+
+/*
+ * Copyright (c) 2025 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/animation/constraint.h>
+#include <dali/public-api/object/handle.h>
+
+namespace Dali::Integration
+{
+/**
+ * @brief Set tag number for given constraint.
+ * It should be called only for internal repositories.
+ * Have exclusive relation with SetTag().
+ * @warning Assert if we set internal tags which alread set some custom tag by application.
+ *
+ * @SINCE_2_4.14
+ * @param[in] constraint The constraint that want to set tag.
+ * @param[in] tag The tag number.
+ */
+DALI_CORE_API void ConstraintSetInternalTag(Dali::Constraint& constraint, const uint32_t tag);
+
+/**
+ * @brief Removes all the constraint from the Object include custom and internal.
+ * It should be called only for internal repositories.
+ *
+ * @SINCE_2_4.14
+ * @param[in] handle The handle that want to remove all constraints.
+ */
+DALI_CORE_API void HandleRemoveAllConstraints(Dali::Handle& handle);
+
+/**
+ * @brief Removes all the constraint from the Object with a matching tag.
+ * It should be called only for internal repositories.
+ *
+ * @SINCE_2_4.14
+ * @param[in] handle The handle that want to remove constraint by tag.
+ * @param[in] tag The tag of the constraints which will be removed. Only internal tag be allowed.
+ */
+DALI_CORE_API void HandleRemoveConstraints(Dali::Handle& handle, uint32_t tag);
+
+/**
+ * @brief Removes all the constraint from the Object with a range of tags [tagBegin tagEnd).
+ * It should be called only for internal repositories.
+ *
+ * @SINCE_2_4.14
+ * @param[in] handle The handle that want to remove constraint by tag.
+ * @param[in] tagBegin The begin tag of the constraints which will be removed. Only internal tag be allowed. (include)
+ * @param[in] tagEnd The end tag of the constraints which will be removed. Only internal tag be allowed. (exclusived)
+ */
+DALI_CORE_API void HandleRemoveConstraints(Dali::Handle& handle, uint32_t tagBegin, uint32_t tagEnd);
+
+} // namespace Dali::Integration
+
+#endif // DALI_CONSTRAINT_INTEG_H
SET( platform_abstraction_src_files
${platform_abstraction_src_dir}/addon-manager.cpp
${platform_abstraction_src_dir}/bitmap.cpp
+ ${platform_abstraction_src_dir}/constraint-integ.cpp
${platform_abstraction_src_dir}/core.cpp
${platform_abstraction_src_dir}/debug.cpp
${platform_abstraction_src_dir}/input-options.cpp
SET( platform_abstraction_header_files
${platform_abstraction_src_dir}/addon-manager.h
${platform_abstraction_src_dir}/bitmap.h
+ ${platform_abstraction_src_dir}/constraint-integ.h
${platform_abstraction_src_dir}/context-notifier.h
${platform_abstraction_src_dir}/core.h
${platform_abstraction_src_dir}/core-enumerations.h
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
#include <dali/internal/event/animation/constrainer.h>
// INTERNAL INCLUDES
+#include <dali/devel-api/common/free-list.h>
+#include <dali/integration-api/constraint-integ.h>
#include <dali/internal/event/animation/constraint-source-impl.h>
#include <dali/public-api/animation/constraint.h>
{
namespace Internal
{
+namespace
+{
+Dali::FreeList& GetFreeList()
+{
+ static Dali::FreeList gConstrainerFreeList;
+ return gConstrainerFreeList;
+}
+
+uint32_t AcquireConstrainerTag()
+{
+ uint32_t tag = GetFreeList().Add(0);
+ DALI_ASSERT_ALWAYS(tag < Dali::ConstraintTagRanges::INTERNAL_TAG_MAX_COUNT_PER_DERIVATION && "To many constrainer applied!");
+ return tag + Dali::ConstraintTagRanges::CORE_CONSTRAINT_TAG_START;
+}
+
+void ReleaseConstrainerTag(uint32_t tag)
+{
+ if(DALI_LIKELY(tag >= Dali::ConstraintTagRanges::CORE_CONSTRAINT_TAG_START))
+ {
+ GetFreeList().Remove(tag - Dali::ConstraintTagRanges::CORE_CONSTRAINT_TAG_START);
+ }
+}
+
+/**
+ * @brief Special tag number if we never apply the constraints before.
+ */
+constexpr uint32_t NOT_APPLIED_TAG_NUMBER = 0u;
+static_assert(NOT_APPLIED_TAG_NUMBER < Dali::ConstraintTagRanges::CORE_CONSTRAINT_TAG_START);
+static_assert(NOT_APPLIED_TAG_NUMBER < Dali::ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START);
+} // namespace
+
Constrainer::Constrainer()
-: Object(nullptr) // we don't have our own scene object
+: Object(nullptr), // we don't have our own scene object
+ mObservedObjects(),
+ mTag(NOT_APPLIED_TAG_NUMBER)
{
}
Constrainer::~Constrainer()
{
//Remove all the constraints created by the object
- uint32_t tag = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this)); // taking 32bits of this as tag
+ uint32_t tag = mTag;
const ObjectIter end = mObservedObjects.End();
for(ObjectIter iter = mObservedObjects.Begin(); iter != end; ++iter)
{
(*iter)->RemoveObserver(*this);
//Remove constraints
- (*iter)->RemoveConstraints(tag);
+ if(tag != NOT_APPLIED_TAG_NUMBER)
+ {
+ (*iter)->RemoveConstraints(tag);
+ }
+ }
+
+ if(mTag != NOT_APPLIED_TAG_NUMBER)
+ {
+ ReleaseConstrainerTag(mTag);
}
}
void Constrainer::Remove(Dali::Handle& target)
{
- uint32_t tag = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this)); // taking 32bits of this as tag
+ uint32_t tag = mTag;
Object& object = GetImplementation(target);
const ObjectIter end = mObservedObjects.End();
for(ObjectIter iter = mObservedObjects.Begin(); iter != end; ++iter)
(*iter)->RemoveObserver(*this);
//Remove constraints created in the object
- target.RemoveConstraints(tag);
+ if(tag != NOT_APPLIED_TAG_NUMBER)
+ {
+ Dali::Integration::HandleRemoveConstraints(target, tag);
+ }
//Remove object from the vector of observed objects
mObservedObjects.Erase(iter);
}
}
+uint32_t Constrainer::GetTag()
+{
+ if(mTag == NOT_APPLIED_TAG_NUMBER)
+ {
+ mTag = AcquireConstrainerTag();
+ }
+ return mTag;
+}
+
} // namespace Internal
} // namespace Dali
#define DALI_INTERNAL_CONSTRAINER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
*/
void Observe(Dali::Handle& handle);
+ /**
+ * @brief Get the tag number for this constrainer.
+ * Each running constrainer will not have same tag number.
+ */
+ uint32_t GetTag();
+
private:
ObjectContainer mObservedObjects; ///< The list of object which have been constrained by the Constrainer
+ uint32_t mTag;
};
} // namespace Internal
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
void ConstraintBase::SetTag(uint32_t tag)
{
+ if(mTag != ConstraintTagRanges::DEFAULT_TAG && tag != ConstraintTagRanges::DEFAULT_TAG)
+ {
+ // Assert if application try to set tag to internal constraints,
+ // or internal engine try to set tag what application using.
+ DALI_ASSERT_ALWAYS(
+ (((ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_START <= mTag && mTag <= ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX) &&
+ (ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_START <= tag && tag <= ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX)) ||
+ ((ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START <= mTag && mTag <= ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_MAX) &&
+ (ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_START <= tag && tag <= ConstraintTagRanges::INTERNAL_CONSTRAINT_TAG_MAX))) &&
+ "Cross tag setting is not allowed!");
+ }
mTag = tag;
}
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
#include <cstring> // for strcmp
// INTERNAL INCLUDES
+#include <dali/integration-api/constraint-integ.h>
#include <dali/internal/event/common/property-helper.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-array.h>
Dali::Constraint constraint = Dali::Constraint::New<float>(target.object, target.propertyIndex, LinearConstraintFunctor(mValue, mProgress, range, wrap));
constraint.AddSource(Dali::Source(source.object, source.propertyIndex));
- constraint.SetTag(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this))); // taking 32bits of this as tag
+ uint32_t tag = GetTag();
+ Dali::Integration::ConstraintSetInternalTag(constraint, tag);
constraint.SetRemoveAction(Dali::Constraint::DISCARD);
constraint.Apply();
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
#include <cstring> // for strcmp
// INTERNAL INCLUDES
+#include <dali/integration-api/constraint-integ.h>
#include <dali/internal/event/common/property-helper.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/property-array.h>
Dali::Constraint constraint = Dali::Constraint::New<Vector3>(target.object, target.propertyIndex, PathConstraintFunctor(mPath, range, wrap));
constraint.AddSource(Dali::Source(source.object, source.propertyIndex));
- constraint.SetTag(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this))); // taking 32bits of this as tag
+ uint32_t tag = GetTag();
+ Dali::Integration::ConstraintSetInternalTag(constraint, tag);
constraint.SetRemoveAction(Dali::Constraint::DISCARD);
constraint.Apply();
}
Dali::Constraint constraint = Dali::Constraint::New<Quaternion>(target.object, target.propertyIndex, PathConstraintFunctor(mPath, range, mForward, wrap));
constraint.AddSource(Dali::Source(source.object, source.propertyIndex));
- constraint.SetTag(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this))); // taking 32bits of this as tag
+ uint32_t tag = GetTag();
+ Dali::Integration::ConstraintSetInternalTag(constraint, tag);
constraint.SetRemoveAction(Dali::Constraint::DISCARD);
constraint.Apply();
}
}
}
+void Object::RemoveConstraints(uint32_t tagBegin, uint32_t tagEnd)
+{
+ // guard against constraint sending messages during core destruction
+ if(mConstraints && Stage::IsInstalled())
+ {
+ auto iter(mConstraints->begin());
+ while(iter != mConstraints->end())
+ {
+ ConstraintBase& constraint = GetImplementation(*iter);
+ const uint32_t tag = constraint.GetTag();
+ if(tagBegin <= tag && tag < tagEnd)
+ {
+ GetImplementation(*iter).RemoveInternal();
+ iter = mConstraints->erase(iter);
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+
+ if(mConstraints->empty())
+ {
+ delete mConstraints;
+ mConstraints = nullptr;
+ }
+ }
+}
+
void Object::SetTypeInfo(const TypeInfo* typeInfo)
{
mTypeInfo = typeInfo;
#define DALI_INTERNAL_OBJECT_H
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
*/
void RemoveConstraints(uint32_t tag);
+ /**
+ * @copydoc Dali::Handle::RemoveConstraints( uint32_t, uint32_t )
+ */
+ void RemoveConstraints(uint32_t tagBegin, uint32_t tagEnd);
+
/**
* Called by TypeInfo to set the type-info that this object-impl is created by.
* @param[in] typeInfo The TypeInfo that creates this object-impl.
--- /dev/null
+#ifndef DALI_CONSTRAINT_TAG_RANGES_H
+#define DALI_CONSTRAINT_TAG_RANGES_H
+
+/*
+ * Copyright (c) 2025 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+
+namespace Dali
+{
+/**
+ * @addtogroup dali_core_animation
+ * @{
+ */
+
+/**
+ * @brief Enumeration for the constraint tag.
+ *
+ * Enumerations are being used here rather than static constants so that switch statements can be
+ * used to compare property indices.
+ * @SINCE_2_4.14
+ */
+// clang-format off
+enum ConstraintTagRanges
+{
+ DEFAULT_TAG = 0, ///< Special tag that we don't set any tags @SINCE_2_4.14
+
+ CUSTOM_CONSTRAINT_TAG_START = 1, ///< Minimum tag for application @SINCE_2_4.14
+ CUSTOM_CONSTRAINT_TAG_MAX = 999999999, ///< Maximum tag for application @SINCE_2_4.14
+
+ INTERNAL_CONSTRAINT_TAG_START = CUSTOM_CONSTRAINT_TAG_MAX + 1, ///< Minimum tag for internal @SINCE_2_4.14
+
+ INTERNAL_TAG_MAX_COUNT_PER_DERIVATION = 1000000, ///< The range of tag number for each sub-repository could be used @SINCE_2_4.14
+
+ CORE_CONSTRAINT_TAG_START = INTERNAL_CONSTRAINT_TAG_START, ///< Minimum tag that Core can uses up to @SINCE_2_4.14
+ CORE_CONSTRAINT_TAG_MAX = CORE_CONSTRAINT_TAG_START + INTERNAL_TAG_MAX_COUNT_PER_DERIVATION - 1u, ///< Maximum tag that Core can uses up to @SINCE_2_4.14
+
+ INTERNAL_CONSTRAINT_TAG_MAX = INTERNAL_CONSTRAINT_TAG_START + 999999999, ///< Maximum tag for internal @SINCE_2_4.14
+};
+// clang-format on
+
+/**
+ * @}
+ */
+} // namespace Dali
+
+#endif // DALI_CONSTRAINT_TAG_RANGES_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
void Constraint::SetTag(const uint32_t tag)
{
+ DALI_ASSERT_ALWAYS(tag <= ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX && "Out of tag range!");
GetImplementation(*this).SetTag(tag);
}
#define DALI_CONSTRAINT_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
// INTERNAL INCLUDES
#include <dali/public-api/animation/constraint-source.h>
+#include <dali/public-api/animation/constraint-tag-ranges.h>
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/object/base-handle.h>
#include <dali/public-api/object/property-input.h>
/**
* @brief Sets a tag for the constraint so it can be identified later.
+ * @note We can only set tag between [ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_START ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_END]
+ * or ConstraintTagRanges::DEFAULT_TAG
*
* @SINCE_1_0.0
* @param[in] tag An integer to identify the constraint
#define DALI_CORE_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
#include <dali/public-api/animation/alpha-function.h>
#include <dali/public-api/animation/animation.h>
#include <dali/public-api/animation/constraint-source.h>
+#include <dali/public-api/animation/constraint-tag-ranges.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/animation/key-frames.h>
${public_api_src_dir}/animation/constraint.h
${public_api_src_dir}/animation/constraints.h
${public_api_src_dir}/animation/constraint-source.h
+ ${public_api_src_dir}/animation/constraint-tag-ranges.h
${public_api_src_dir}/animation/key-frames.h
${public_api_src_dir}/animation/linear-constrainer.h
${public_api_src_dir}/animation/path.h
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
void Handle::RemoveConstraints()
{
- GetImplementation(*this).RemoveConstraints();
+ RemoveConstraints(Dali::ConstraintTagRanges::DEFAULT_TAG, Dali::ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX + 1u);
}
void Handle::RemoveConstraints(uint32_t tag)
{
+ DALI_ASSERT_ALWAYS(tag <= ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX && "Out of tag range!");
GetImplementation(*this).RemoveConstraints(tag);
}
+void Handle::RemoveConstraints(uint32_t tagBegin, uint32_t tagEnd)
+{
+ DALI_ASSERT_ALWAYS(tagEnd <= ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX + 1u && "Out of tag range!");
+ GetImplementation(*this).RemoveConstraints(tagBegin, tagEnd);
+}
+
IndirectValue Handle::operator[](Property::Index index)
{
// Will assert on access if handle is empty
#define DALI_HANDLE_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
// Constraints
/**
- * @brief Removes all constraints from an Object.
+ * @brief Removes all default tag constraints and custom constraints from an Object.
*
* @SINCE_1_0.0
* @pre The object has been initialized.
/**
* @brief Removes all the constraint from the Object with a matching tag.
+ * @note We can only use tag between [ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_START ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_END]
+ * or ConstraintTagRanges::DEFAULT_TAG
*
* @SINCE_1_0.0
* @param[in] tag The tag of the constraints which will be removed
*/
void RemoveConstraints(uint32_t tag);
+ /**
+ * @brief Removes all the constraint from the Object with a range of tags [tagBegin tagEnd).
+ * @note We can only use tag between [ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_START ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_END]
+ * or ConstraintTagRanges::DEFAULT_TAG
+ *
+ * @SINCE_2_4.14
+ * @param[in] tagBegin The begin tag of the constraints which will be removed (include)
+ * @param[in] tagEnd The end tag of the constraints which will be removed (exclusived)
+ * @pre The Object has been initialized.
+ */
+ void RemoveConstraints(uint32_t tagBegin, uint32_t tagEnd);
+
/**
* @brief Index operator, using integer lookup.
*