Give range of tags for constraints 10/321910/7
authorEunki, Hong <eunkiki.hong@samsung.com>
Tue, 1 Apr 2025 02:27:58 +0000 (11:27 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Tue, 8 Apr 2025 01:49:41 +0000 (10:49 +0900)
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>
22 files changed:
automated-tests/src/dali-internal/CMakeLists.txt
automated-tests/src/dali-internal/utc-Dali-Internal-Constraint.cpp [new file with mode: 0644]
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-Constraint.cpp
automated-tests/src/dali/utc-Dali-Handle.cpp
dali/integration-api/constraint-integ.cpp [new file with mode: 0644]
dali/integration-api/constraint-integ.h [new file with mode: 0644]
dali/integration-api/file.list
dali/internal/event/animation/constrainer.cpp
dali/internal/event/animation/constrainer.h
dali/internal/event/animation/constraint-base.cpp
dali/internal/event/animation/linear-constrainer-impl.cpp
dali/internal/event/animation/path-constrainer-impl.cpp
dali/internal/event/common/object-impl.cpp
dali/internal/event/common/object-impl.h
dali/public-api/animation/constraint-tag-ranges.h [new file with mode: 0644]
dali/public-api/animation/constraint.cpp
dali/public-api/animation/constraint.h
dali/public-api/dali-core.h
dali/public-api/file.list
dali/public-api/object/handle.cpp
dali/public-api/object/handle.h

index e382d22ccb6edefcad05fed79f6d48d311cfce34..713005591778922c8ac223224f1adfb2431b3cd0 100644 (file)
@@ -9,6 +9,7 @@ SET(TC_SOURCES
   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
diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-Constraint.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-Constraint.cpp
new file mode 100644 (file)
index 0000000..3693a21
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+* 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;
+}
index 38fd77a3483c1aecb539d6c51fb30a74d411af78..fb4c85cf66beab5ac3224ab0bc4c00340c28da4f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -3189,7 +3189,7 @@ int UtcDaliActorRemoveConstraintTag(void)
   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);
@@ -3202,7 +3202,7 @@ int UtcDaliActorRemoveConstraintTag(void)
   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);
@@ -3212,6 +3212,33 @@ int UtcDaliActorRemoveConstraintTag(void)
   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;
index e0255b231f86c9d9a5f558dc32a55daeed1b30ca..0ba4c76cedcb38f1a51de23206cc9ed2f0dfe811 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -703,10 +703,14 @@ int UtcDaliConstraintTagP(void)
   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
 
@@ -726,6 +730,30 @@ int UtcDaliConstraintSetTagN(void)
   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
@@ -1631,7 +1659,6 @@ int UtcDaliConstraintComponentNonTransformPropertyConstraintP(void)
   END_TEST;
 }
 
-
 namespace PostConstraintTest
 {
 void CheckComponentProperty(TestApplication& application, Actor& actor, Handle target)
@@ -1648,14 +1675,14 @@ void CheckComponentProperty(TestApplication& application, Actor& actor, Handle t
   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});
@@ -1670,7 +1697,7 @@ void CheckComponentProperty(TestApplication& application, Actor& actor, Handle t
   preConstraint.Remove();
   postConstraint.Remove();
 }
-}
+} // namespace PostConstraintTest
 
 int UtcDaliConstraintApplyPost(void)
 {
index 3c991ec8c7114bea2098090584ae59de3f9f0be9..24d0ed679218e7e26aa7eb9d23f5a9a69fbf0394 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -2158,6 +2158,42 @@ int UtcDaliHandleRemoveConstraintsNegative02(void)
   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;
diff --git a/dali/integration-api/constraint-integ.cpp b/dali/integration-api/constraint-integ.cpp
new file mode 100644 (file)
index 0000000..938b40f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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
diff --git a/dali/integration-api/constraint-integ.h b/dali/integration-api/constraint-integ.h
new file mode 100644 (file)
index 0000000..a0b33e7
--- /dev/null
@@ -0,0 +1,71 @@
+#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
index d7feadfef7502374513d2e92339a9ab47eb7bb6f..88123951b3f9a4aa4e1dd15675c4fc50283f3b31 100644 (file)
@@ -5,6 +5,7 @@ SET( platform_abstraction_src_dir ${ROOT_SRC_DIR}/dali/integration-api )
 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
@@ -34,6 +35,7 @@ SET( platform_abstraction_events_src_files
 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
index 56c546a977e16627461f05d2ea67abf102c91831..3974fde6079c852691732edce50d1f89f66f2660 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -19,6 +19,8 @@
 #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>
 
@@ -26,15 +28,48 @@ namespace Dali
 {
 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)
   {
@@ -42,7 +77,15 @@ Constrainer::~Constrainer()
     (*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);
   }
 }
 
@@ -62,7 +105,7 @@ void Constrainer::ObjectDestroyed(Object& object)
 
 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)
@@ -73,7 +116,10 @@ void Constrainer::Remove(Dali::Handle& target)
       (*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);
@@ -106,6 +152,15 @@ void Constrainer::Observe(Dali::Handle& handle)
   }
 }
 
+uint32_t Constrainer::GetTag()
+{
+  if(mTag == NOT_APPLIED_TAG_NUMBER)
+  {
+    mTag = AcquireConstrainerTag();
+  }
+  return mTag;
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 21726bb7a25860ca96f7050aa17999072d46b9d2..85b5343fb00888bc23554ed6e07e7156f5fa9e62 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -93,8 +93,15 @@ protected:
    */
   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
index 8d1730afeb49adb302e95cc4008c05b5ce072c77..80c5fd79a0eb664a70e4df2ad0fe37d0ffdfaa94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -196,6 +196,17 @@ ConstraintBase::RemoveAction ConstraintBase::GetRemoveAction() const
 
 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;
 }
 
index 98df63cbccd4a109c0236bc8a5d40c09ee69727b..f76298c068bf6a58172ae97c97ee40b2c4279d04 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -22,6 +22,7 @@
 #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>
@@ -136,7 +137,8 @@ void LinearConstrainer::Apply(Property target, Property source, const Vector2& r
   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();
 
index 4ea5c08eb957d23be423b1ec6e8c6d05cf3b7f90..8f0fad0931d88842fcc6a62824cab386df52e115 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -22,6 +22,7 @@
 #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>
@@ -160,7 +161,8 @@ void PathConstrainer::Apply(Property target, Property source, const Vector2& ran
     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();
   }
@@ -170,7 +172,8 @@ void PathConstrainer::Apply(Property target, Property source, const Vector2& ran
     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();
   }
index 1e63f2095f36e1279366f0bb7b55e61bc390e30e..0fed9334242803f1fb81ef28ab0b84b82965911e 100644 (file)
@@ -948,6 +948,35 @@ void Object::RemoveConstraints(uint32_t tag)
   }
 }
 
+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;
index 30703b92772b994a2d1c4bb9b55b7636e8ed75d1..5fdef72a16cca73b234309de2943e6a627a3acb6 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -343,6 +343,11 @@ public:
    */
   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.
diff --git a/dali/public-api/animation/constraint-tag-ranges.h b/dali/public-api/animation/constraint-tag-ranges.h
new file mode 100644 (file)
index 0000000..7848f0b
--- /dev/null
@@ -0,0 +1,62 @@
+#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
index e8b5ea51d5dbd948a218b1c3a1965acb63859b10..1590ac531b23854d1c97f6fc727cfd2ddff8ee9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -102,6 +102,7 @@ Constraint::RemoveAction Constraint::GetRemoveAction() const
 
 void Constraint::SetTag(const uint32_t tag)
 {
+  DALI_ASSERT_ALWAYS(tag <= ConstraintTagRanges::CUSTOM_CONSTRAINT_TAG_MAX && "Out of tag range!");
   GetImplementation(*this).SetTag(tag);
 }
 
index 51a4f7251e5ab290f9624d67f82c7bdec4c9a16f..b4661591921bba8e14b3cbc914112f1bc0edf3f5 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -23,6 +23,7 @@
 
 // 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>
@@ -519,6 +520,8 @@ public:
 
   /**
    * @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
index a3a18a85ba5dfc0d03b112f1566040e36db4bea1..060c4b0d61dcf0447f149a83b5fd44a2f517b102 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -31,6 +31,7 @@
 #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>
index 08b1cf5f4a72716cbe6de3835eae7efa5103dc5b..5071f4c615ff740648dc0022583979fa4d665fb9 100644 (file)
@@ -114,6 +114,7 @@ SET( public_api_core_animation_header_files
   ${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
index 45f8fcd9adff1e9bb77fae7dfdbe720be871af89..099b0ea5ab35e88549fbf6a8a420428283cbb517 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -185,14 +185,21 @@ void Handle::RemovePropertyNotifications()
 
 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
index 1e4130a534bb55fc4788a3ffdb895e09973623bc..99148a27e089df55ad286099d870ee1e55307eac 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -582,7 +582,7 @@ public:
   // 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.
@@ -591,6 +591,8 @@ public:
 
   /**
    * @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
@@ -598,6 +600,18 @@ public:
    */
   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.
    *