utc-Dali-Internal-LongPressGesture.cpp
utc-Dali-Internal-MatrixUtils.cpp
utc-Dali-Internal-MemoryPoolObjectAllocator.cpp
+ utc-Dali-Internal-OrderedSet.cpp
utc-Dali-Internal-OwnerPointer.cpp
utc-Dali-Internal-PinchGesture.cpp
utc-Dali-Internal-PinchGestureProcessor.cpp
--- /dev/null
+/*
+ * Copyright (c) 2023 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <utility>
+
+// INTERNAL INCLUDES
+#include <dali-test-suite-utils.h>
+#include <dali/internal/common/ordered-set.h>
+
+using namespace Dali::Internal;
+
+void utc_dali_internal_owner_set_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_internal_owner_set_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace
+{
+/// Takes in a reference to a bool which is set to true when the destructor is called
+class OwnedClass
+{
+public:
+ OwnedClass(bool& destructorCalled)
+ : mDestructorCalled(destructorCalled)
+ {
+ mDestructorCalled = false;
+ }
+
+ ~OwnedClass()
+ {
+ mDestructorCalled = true;
+ }
+
+private:
+ bool& mDestructorCalled;
+};
+
+/// Just a simple class with a member value and global refcount.
+class ClassWithId
+{
+public:
+ ClassWithId(int id)
+ : mId(id)
+ {
+ ++gRefCount;
+ }
+ ~ClassWithId()
+ {
+ --gRefCount;
+ }
+
+ static int gRefCount;
+ int mId{};
+};
+int ClassWithId::gRefCount = 0;
+
+} // namespace
+
+///////////////////////////////////////////////////////////////////////////////
+
+int UtcDaliOrderedSetEnsureDeletion(void)
+{
+ // Ensure that the object owned by the OrderedSet is deleted.
+
+ bool deleted = false;
+
+ {
+ OrderedSet<OwnedClass> set;
+ set.PushBack(new OwnedClass(deleted));
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+ }
+
+ // OrderedSet out-of-scope, object should be deleted.
+
+ DALI_TEST_EQUALS(deleted, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetFalseEnsureNotDeletionWhen(void)
+{
+ // Ensure that the object owned by the OrderedSET is deleted.
+
+ bool deleted = false;
+
+ OwnedClass* ptr;
+
+ {
+ // Create OrderedSet without ownership. It will not delete automatically.
+ OrderedSet<OwnedClass, false> set;
+ ptr = new OwnedClass(deleted);
+ set.PushBack(ptr);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+ }
+
+ // OrderedSet out-of-scope, but, object should not be deleted.
+
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ delete ptr;
+ DALI_TEST_EQUALS(deleted, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetDefaultConstructor(void)
+{
+ // Ensure the default constructor is created as expected.
+
+ OrderedSet<OwnedClass> set;
+ DALI_TEST_CHECK(set.Count() == 0u);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetFalseDefaultConstructor(void)
+{
+ // Ensure the default constructor is created as expected.
+
+ OrderedSet<OwnedClass, false> set;
+ DALI_TEST_CHECK(set.Count() == 0u);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetReserve(void)
+{
+ OrderedSet<OwnedClass> set;
+ set.Reserve(100u);
+
+ // Reserve function didn't change the count.
+ DALI_TEST_CHECK(set.Count() == 0u);
+
+ OrderedSet<OwnedClass> set2;
+ set2.Reserve(100u);
+
+ // Reserve function didn't change the count.
+ DALI_TEST_CHECK(set2.Count() == 0u);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetMove(void)
+{
+ // Call move constructor and move assignment operator
+
+ bool deleted = false;
+ OwnedClass* owned = new OwnedClass(deleted);
+
+ OrderedSet<OwnedClass> first;
+ DALI_TEST_CHECK(first.Find(owned) == first.End());
+ first.PushBack(owned);
+ DALI_TEST_CHECK(first.Find(owned) != first.End());
+
+ {
+ // Move constructor, first should have a nullptr now, no object deletion
+ OrderedSet<OwnedClass> second(std::move(first));
+ DALI_TEST_CHECK(first.Find(owned) == first.End());
+ DALI_TEST_CHECK(second.Find(owned) != second.End());
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ // Assign second to first, no deletion, second should have a nullptr now
+ first = std::move(second);
+ DALI_TEST_CHECK(first.Find(owned) != first.End());
+ DALI_TEST_CHECK(second.Find(owned) == second.End());
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+ }
+
+ // second is out-of-scope now, no object deletion
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ // Assign to an empty pointer, owned object should be deleted
+ OrderedSet<OwnedClass> empty;
+ first = std::move(empty);
+ DALI_TEST_EQUALS(deleted, true, TEST_LOCATION);
+ DALI_TEST_CHECK(first.Find(owned) == first.End());
+ DALI_TEST_CHECK(empty.Find(owned) == empty.End());
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetFalseMove(void)
+{
+ // Call move constructor and move assignment operator
+
+ bool deleted = false;
+ OwnedClass* owned = new OwnedClass(deleted);
+
+ OrderedSet<OwnedClass, false> first;
+ DALI_TEST_CHECK(first.Find(owned) == first.End());
+ first.PushBack(owned);
+ DALI_TEST_CHECK(first.Find(owned) != first.End());
+
+ {
+ // Move constructor, first should have a nullptr now, no object deletion
+ OrderedSet<OwnedClass, false> second(std::move(first));
+ DALI_TEST_CHECK(first.Find(owned) == first.End());
+ DALI_TEST_CHECK(second.Find(owned) != second.End());
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ // Assign second to first, no deletion, second should have a nullptr now
+ first = std::move(second);
+ DALI_TEST_CHECK(first.Find(owned) != first.End());
+ DALI_TEST_CHECK(second.Find(owned) == second.End());
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+ }
+
+ // second is out-of-scope now, no object deletion
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ // Assign to an empty pointer, but owned object should not be deleted
+ OrderedSet<OwnedClass, false> empty;
+ first = std::move(empty);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+ DALI_TEST_CHECK(first.Find(owned) == first.End());
+ DALI_TEST_CHECK(empty.Find(owned) == empty.End());
+
+ delete owned;
+ DALI_TEST_EQUALS(deleted, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetErase(void)
+{
+ // Ensure that calling Reset deletes the object and sets the owner-pointer to NULL
+
+ bool deleted = false;
+ OwnedClass* owned = new OwnedClass(deleted);
+
+ OrderedSet<OwnedClass> set;
+ set.PushBack(owned);
+ DALI_TEST_EQUALS(set.Count(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+ set.EraseObject(owned);
+ DALI_TEST_EQUALS(deleted, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetFalseErase(void)
+{
+ // Ensure that calling Reset not deletes the object and sets the owner-pointer to NULL
+
+ bool deleted = false;
+ OwnedClass* owned = new OwnedClass(deleted);
+
+ OrderedSet<OwnedClass, false> set;
+ set.PushBack(owned);
+ DALI_TEST_EQUALS(set.Count(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+ set.EraseObject(owned);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ delete owned;
+ DALI_TEST_EQUALS(deleted, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetClear(void)
+{
+ // Ensure that calling Reset deletes the object and sets the owner-pointer to NULL
+
+ bool deleted = false;
+ OwnedClass* owned = new OwnedClass(deleted);
+
+ OrderedSet<OwnedClass> set;
+ set.PushBack(owned);
+ DALI_TEST_EQUALS(set.Count(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ set.Clear();
+ DALI_TEST_EQUALS(set.Count(), 0u, TEST_LOCATION);
+ DALI_TEST_EQUALS(deleted, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetFalseClear(void)
+{
+ // Ensure that calling Reset deletes the object and sets the owner-pointer to NULL
+
+ bool deleted = false;
+ OwnedClass* owned = new OwnedClass(deleted);
+
+ OrderedSet<OwnedClass, false> set;
+ set.PushBack(owned);
+ DALI_TEST_EQUALS(set.Count(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ set.Clear();
+ DALI_TEST_EQUALS(set.Count(), 0u, TEST_LOCATION);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ delete owned;
+ DALI_TEST_EQUALS(deleted, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetRelease(void)
+{
+ // Ensure that calling Release does NOT delete the object but still sets the owner-pointer to NULL
+
+ bool deleted = false;
+ OwnedClass* owned = new OwnedClass(deleted);
+
+ OrderedSet<OwnedClass> set;
+ set.PushBack(owned);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+
+ auto iter = set.Find(owned);
+ DALI_TEST_CHECK(iter != set.End());
+ DALI_TEST_EQUALS(set.Count(), 1u, TEST_LOCATION);
+
+ OwnedClass* released = set.Release(iter);
+ DALI_TEST_EQUALS(deleted, false, TEST_LOCATION);
+ DALI_TEST_CHECK(set.Find(owned) == set.End());
+ DALI_TEST_CHECK(set.Find(released) == set.End());
+ DALI_TEST_EQUALS(set.Count(), 0u, TEST_LOCATION);
+
+ delete released;
+ DALI_TEST_EQUALS(deleted, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetIteratorOrderCheck(void)
+{
+ // Ensure that order of iterator is equal with Order of Insertion.
+
+ // Reset refcount of class
+ ClassWithId::gRefCount = 0;
+
+ // To avoid lucky pass, run this test multiple time.
+ int tryCnt = 3;
+ while(tryCnt--)
+ {
+ int baseId = tryCnt; // random id
+ int id = baseId;
+ int n = 10 + 5 * (tryCnt + 1); // random count
+
+ OrderedSet<ClassWithId> set;
+
+ for(int i = 0; i < n; ++i)
+ {
+ ClassWithId* object = new ClassWithId(id++);
+ set.PushBack(object);
+ }
+
+ int expectId;
+ // Check by for iteration
+ expectId = baseId;
+ for(auto iter = set.Begin(), iterEnd = set.End(); iter != iterEnd; ++iter)
+ {
+ DALI_TEST_EQUALS(expectId++, (*iter)->mId, TEST_LOCATION);
+ }
+ DALI_TEST_EQUALS(expectId, id, TEST_LOCATION);
+
+ // Check by range referenced iteration
+ expectId = baseId;
+ for(auto&& iter : set)
+ {
+ DALI_TEST_EQUALS(expectId++, iter->mId, TEST_LOCATION);
+ // Change iter's value.
+ ++(iter->mId);
+ }
+ DALI_TEST_EQUALS(expectId, id, TEST_LOCATION);
+
+ // Check by range iteration. Note that class value changed.
+ expectId = baseId + 1;
+ for(const auto& iter : set)
+ {
+ DALI_TEST_EQUALS(expectId++, iter->mId, TEST_LOCATION);
+ }
+ DALI_TEST_EQUALS(expectId, id + 1, TEST_LOCATION);
+ }
+
+ // Check whether leak exist.
+ DALI_TEST_EQUALS(ClassWithId::gRefCount, 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliOrderedSetFalseIteratorOrderCheck(void)
+{
+ // Ensure that order of iterator is equal with Order of Insertion.
+
+ // Reset refcount of class
+ ClassWithId::gRefCount = 0;
+
+ // Container of ownered class, to release memories after test finished.
+ std::vector<ClassWithId*> objectList;
+
+ // To avoid lucky pass, run this test multiple time.
+ int tryCnt = 3;
+ while(tryCnt--)
+ {
+ int baseId = tryCnt; // random id
+ int id = baseId;
+ int n = 10 + 5 * (tryCnt + 1); // random count
+
+ OrderedSet<ClassWithId, false> set;
+
+ for(int i = 0; i < n; ++i)
+ {
+ ClassWithId* object = new ClassWithId(id++);
+ objectList.push_back(object);
+ set.PushBack(object);
+ }
+
+ int expectId;
+ // Check by for iteration
+ expectId = baseId;
+ for(auto iter = set.Begin(), iterEnd = set.End(); iter != iterEnd; ++iter)
+ {
+ DALI_TEST_EQUALS(expectId++, (*iter)->mId, TEST_LOCATION);
+ }
+ DALI_TEST_EQUALS(expectId, id, TEST_LOCATION);
+
+ // Check by range referenced iteration
+ expectId = baseId;
+ for(auto&& iter : set)
+ {
+ DALI_TEST_EQUALS(expectId++, iter->mId, TEST_LOCATION);
+ // Change iter's value.
+ ++(iter->mId);
+ }
+ DALI_TEST_EQUALS(expectId, id, TEST_LOCATION);
+
+ // Check by range iteration. Note that class value changed.
+ expectId = baseId + 1;
+ for(const auto& iter : set)
+ {
+ DALI_TEST_EQUALS(expectId++, iter->mId, TEST_LOCATION);
+ }
+ DALI_TEST_EQUALS(expectId, id + 1, TEST_LOCATION);
+ }
+
+ // Check whether leak exist.
+ DALI_TEST_EQUALS(ClassWithId::gRefCount, objectList.size(), TEST_LOCATION);
+
+ // Release memory now.
+ for(auto&& iter : objectList)
+ {
+ delete iter;
+ }
+ objectList.clear();
+ DALI_TEST_EQUALS(ClassWithId::gRefCount, 0, TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
--- /dev/null
+#ifndef DALI_INTERNAL_ORDERED_SET_H
+#define DALI_INTERNAL_ORDERED_SET_H
+
+/*
+ * Copyright (c) 2023 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <unordered_map>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/list-wrapper.h>
+
+namespace Dali
+{
+namespace Internal
+{
+/**
+ * @brief Container of data which has strong point to Find & Erase.
+ * It will be useful when we need to iterate the order of data insertion.
+ * and need to check whether some object is exist or not very fast.
+ * @note Since the data's memory is not continuos, iteration is slower than normal vector contianer.
+ *
+ * @tparam T The type of class
+ * @tparam owned True if data is owned, So we will automatcally release the memory
+ * False if data is not owned by this set. Default as true.
+ * @tparam Hash Custom hash function of const T* type for MapContainer.
+ * Note that if two const T* return true at KeyEqual, Hash should return same value.
+ * Default as std::hash<const T*>
+ * @tparam KeyEqual Custom equal function of const T* type for MapContainer.
+ * Return true if two const T* type is equal. Default as std::equal_to<const T*>
+ */
+template<class T, bool owned = true, class Hash = std::hash<const T*>, class KeyEqual = std::equal_to<const T*>>
+class OrderedSet
+{
+public:
+ // Real data owned container.
+ using ListContainer = typename std::list<T*>;
+ using Iterator = typename ListContainer::iterator;
+ using ConstIterator = typename ListContainer::const_iterator;
+
+ // Find helper map container.
+ using MapContainer = typename std::unordered_map<const T*, Iterator, Hash, KeyEqual>;
+
+ using SizeType = std::size_t;
+
+ /**
+ * @brief Construct a new OrderedSet object
+ */
+ OrderedSet() = default;
+
+ /**
+ * @brief Move construct
+ */
+ OrderedSet(OrderedSet&& rhs)
+ : mMap(std::move(rhs.mMap)),
+ mList(std::move(rhs.mList))
+ {
+ rhs.mMap.clear();
+ rhs.mMap.rehash(0);
+ rhs.mList.clear();
+ }
+
+ /**
+ * @brief Move assign
+ */
+ OrderedSet& operator=(OrderedSet&& rhs)
+ {
+ Clear();
+ mMap = std::move(rhs.mMap);
+ mList = std::move(rhs.mList);
+ rhs.mMap.clear();
+ rhs.mMap.rehash(0);
+ rhs.mList.clear();
+ return *this;
+ }
+
+ ~OrderedSet()
+ {
+ Clear();
+ }
+
+ /**
+ * @brief Iterator of begin & end
+ */
+ Iterator Begin()
+ {
+ return mList.begin();
+ }
+ Iterator End()
+ {
+ return mList.end();
+ }
+ ConstIterator Begin() const
+ {
+ return mList.begin();
+ }
+ ConstIterator End() const
+ {
+ return mList.end();
+ }
+
+ // Support for C++11 Range-based for loop: for( item : container ).
+ Iterator begin()
+ {
+ return Begin();
+ }
+ Iterator end()
+ {
+ return End();
+ }
+ ConstIterator begin() const
+ {
+ return Begin();
+ }
+ ConstIterator end() const
+ {
+ return End();
+ }
+
+ /**
+ * @brief Get the number of elements.
+ *
+ * @return The number of elements that this container owned.
+ */
+ SizeType Count() const
+ {
+ return mMap.size();
+ }
+
+ /**
+ * @brief Reserves space in the ordered set.
+ *
+ * @param[in] count Count of elements to reserve
+ */
+ void Reserve(SizeType count)
+ {
+ if(mMap.size() < count)
+ {
+ mMap.rehash(count);
+ }
+ }
+
+ /**
+ * @brief Find and get iterator of object. If not exist, return End().
+ *
+ * @param[in] object The object pointer what we want to find.
+ * @return Iterator of object, or End().
+ */
+ Iterator Find(T* object)
+ {
+ auto mapIter = mMap.find(object);
+ if(mapIter == mMap.end())
+ {
+ return End();
+ }
+ return mapIter->second;
+ }
+ ConstIterator Find(const T* object) const
+ {
+ auto mapIter = mMap.find(object);
+ if(mapIter == mMap.end())
+ {
+ return End();
+ }
+ return mapIter->second;
+ }
+
+ /**
+ * @brief PushBack and keep ownership of object.
+ * @note Iterator will keep order of PushBack API call.
+ *
+ * @param[in] object The object pointer what we want to insert.
+ */
+ void PushBack(T* object)
+ {
+ DALI_ASSERT_DEBUG(Find(object) == End());
+ auto newIter = mList.insert(mList.end(), object);
+ mMap.insert({object, newIter});
+ }
+
+ /**
+ * @brief Erase and remove memory of object.
+ *
+ * @param[in] object The object pointer what we want to erase.
+ */
+ void EraseObject(T* object)
+ {
+ // TODO : Should we allow duplicated erase?
+ //DALI_ASSERT_DEBUG(Find(object) != End());
+ Erase(Find(object));
+ }
+ void EraseObject(const T* object)
+ {
+ // TODO : Should we allow duplicated erase?
+ //DALI_ASSERT_DEBUG(Find(object) != End());
+ Erase(Find(object));
+ }
+
+ /**
+ * @brief Erase and remove memory of object by iterator.
+ *
+ * @param[in] iter The iterator what we want to erase.
+ */
+ Iterator Erase(Iterator iter)
+ {
+ Iterator ret = mList.end();
+ if(iter != mList.end())
+ {
+ // Erase mMap first.
+ auto mapIter = mMap.find(*iter);
+ DALI_ASSERT_DEBUG(mapIter != mMap.end());
+ mMap.erase(mapIter);
+
+ // Erase owned object.
+ if constexpr(owned)
+ {
+ delete *iter;
+ }
+ ret = mList.erase(iter);
+ }
+ return ret;
+ }
+ ConstIterator Erase(ConstIterator iter)
+ {
+ ConstIterator ret = mList.end();
+ if(iter != mList.end())
+ {
+ // Erase mMap first.
+ auto mapIter = mMap.find(*iter);
+ DALI_ASSERT_DEBUG(mapIter != mMap.end());
+ mMap.erase(mapIter);
+
+ // Erase owned object.
+ if constexpr(owned)
+ {
+ delete *iter;
+ }
+ ret = mList.erase(iter);
+ }
+ return ret;
+ }
+
+ /**
+ * @brief Release and move ownership of object.
+ * This API do not remove memory.
+ *
+ * @param[in] iter The iterator what we want to release.
+ */
+ T* Release(Iterator iter)
+ {
+ T* result = (*iter);
+
+ // Erase mMap first.
+ auto mapIter = mMap.find(result);
+ DALI_ASSERT_DEBUG(mapIter != mMap.end());
+ mMap.erase(mapIter);
+
+ // Erase without delete reference
+ mList.erase(iter);
+ return result;
+ }
+ T* Release(ConstIterator iter)
+ {
+ const T* result = (*iter);
+
+ // Erase mMap first.
+ auto mapIter = mMap.find(result);
+ DALI_ASSERT_DEBUG(mapIter != mMap.end());
+ mMap.erase(mapIter);
+
+ // Erase without delete reference
+ mList.erase(iter);
+ return result;
+ }
+
+ /**
+ * @brief Remove all data and release memory if we owned data.
+ */
+ void Clear()
+ {
+ // Delete memory
+ if constexpr(owned)
+ {
+ for(auto&& iter : mList)
+ {
+ delete iter;
+ }
+ }
+ mMap.clear();
+ mMap.rehash(0);
+ mList.clear();
+ }
+
+private:
+ // Delete copy operation.
+ OrderedSet(const OrderedSet&) = delete;
+ OrderedSet& operator=(const OrderedSet&) = delete;
+
+private:
+ MapContainer mMap{}; ///< Helper cache map to find item fast.
+ ListContainer mList{}; ///< Ordered by PushBack API called. Actual ownership will be stored here.
+};
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_ORDERED_SET_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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 AnimationPlaylist::AnimationDestroyed(Animation& animation)
{
- Dali::Vector<Animation*>::Iterator iter = std::find(mAnimations.Begin(), mAnimations.End(), &animation);
+ auto iter = mAnimations.Find(&animation);
DALI_ASSERT_ALWAYS(iter != mAnimations.End() && "Animation not found");
- mAnimations.Remove(iter);
+ mAnimations.Erase(iter);
}
void AnimationPlaylist::OnPlay(Animation& animation)
{
- mPlaylist.push_back(Dali::Animation(&animation));
+ Dali::Animation handle = Dali::Animation(&animation);
+ auto iter = mPlaylist.lower_bound(handle);
+ if(iter != mPlaylist.end() && (*iter).first == handle)
+ {
+ // Just increase reference count.
+ ++(iter->second);
+ }
+ else
+ {
+ mPlaylist.insert(iter, {handle, 1u});
+ }
}
void AnimationPlaylist::OnClear(Animation& animation)
{
- std::vector<Dali::Animation>::iterator iter = std::find(mPlaylist.begin(), mPlaylist.end(), Dali::Animation(&animation));
- std::vector<Dali::Animation>::iterator last = mPlaylist.end();
- if(iter != last)
+ Dali::Animation handle = Dali::Animation(&animation);
+ auto iter = mPlaylist.find(handle);
+
+ // Animation might be removed when NotifyCompleted called.
+ if(DALI_LIKELY(iter != mPlaylist.end()))
{
- --last; // move to real last
- std::swap(*iter, *last); // swap
- mPlaylist.resize(mPlaylist.size() - 1u);
+ // Just decrease reference count. But if reference count is zero, remove it.
+ if(--(iter->second) == 0u)
+ {
+ mPlaylist.erase(iter);
+ }
}
}
// Since animations can be unreferenced during the signal emissions, iterators into animationPointers may be invalidated.
// First copy and reference the finished animations, then emit signals
- for(Dali::Vector<Animation*>::Iterator iter = mAnimations.Begin(); iter != mAnimations.End(); ++iter)
+ for(auto* animation : mAnimations)
{
- Animation* animation = *iter;
-
if(animation->HasFinished())
{
- finishedAnimations.push_back(Dali::Animation(animation));
+ Dali::Animation handle = Dali::Animation(animation);
+ finishedAnimations.push_back(handle);
// The animation may be present in mPlaylist - remove if necessary
// Note that the animation "Finish" signal is emitted after Stop() has been called
- std::vector<Dali::Animation>::iterator iter = std::find(mPlaylist.begin(), mPlaylist.end(), Dali::Animation(animation));
- DALI_ASSERT_DEBUG(iter != mPlaylist.end());
- mPlaylist.erase(iter);
+ OnClear(*animation);
}
}
// Now it's safe to emit the signals
- for(std::vector<Dali::Animation>::iterator iter = finishedAnimations.begin(); iter != finishedAnimations.end(); ++iter)
+ for(auto iter = finishedAnimations.begin(); iter != finishedAnimations.end(); ++iter)
{
Dali::Animation& handle = *iter;
{
std::vector<Dali::Animation> notifyProgressAnimations; // Will own animations until all emits have been done
- for(Dali::Vector<Animation*>::Iterator iter = mAnimations.Begin(); iter != mAnimations.End(); ++iter)
+ for(auto* animation : mAnimations)
{
- Animation* animation = *iter;
-
if((animation->GetSceneObject()) == sceneGraphAnimation)
{
// Store handles to animations that need signals emitted in the case of an animation being cleared in-between emits
uint32_t AnimationPlaylist::GetAnimationCount()
{
- return mAnimations.Size();
+ return mAnimations.Count();
}
Dali::Animation AnimationPlaylist::GetAnimationAt(uint32_t index)
{
- if(index >= mAnimations.Size())
+ if(index >= mAnimations.Count())
{
DALI_LOG_ERROR("Animation index is out of bounds.\n");
return Dali::Animation();
}
- return Dali::Animation(mAnimations[index]);
+
+ // This will spend a lot of time. But GetAnimationAt API will be called very rarely.
+ Animation* ret = nullptr;
+ for(auto iter : mAnimations)
+ {
+ if(index == 0u)
+ {
+ ret = iter;
+ break;
+ }
+ --index;
+ }
+ DALI_ASSERT_DEBUG(ret != nullptr);
+ return Dali::Animation(ret);
}
} // namespace Internal
#define DALI_INTERNAL_ANIMATION_PLAYLIST_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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/devel-api/common/map-wrapper.h>
#include <dali/internal/common/message.h>
+#include <dali/internal/common/ordered-set.h>
#include <dali/internal/event/common/complete-notification-interface.h>
#include <dali/public-api/animation/animation.h>
#include <dali/public-api/common/dali-vector.h>
void NotifyCompleted() override;
private:
- Dali::Vector<Animation*> mAnimations; ///< All existing animations (not owned)
- std::vector<Dali::Animation> mPlaylist; ///< The currently playing animations (owned through handle)
+ OrderedSet<Animation, false> mAnimations; ///< All existing animations (not owned)
+ std::map<Dali::Animation, uint32_t> mPlaylist; ///< The currently playing animations (owned through handle). Note we can hold same handles multiple.
};
/**
mCompare);
OwnerPointer<SceneGraph::PropertyNotification> transferOwnership(const_cast<SceneGraph::PropertyNotification*>(mPropertyNotification));
AddPropertyNotificationMessage(mUpdateManager, transferOwnership);
+
+ // Setup mapping infomations between scenegraph property notification
+ mPropertyNotificationManager.PropertyNotificationSceneObjectMapping(mPropertyNotification, *this);
}
}
{
DALI_ASSERT_ALWAYS(EventThreadServices::IsCoreRunning());
+ // Remove mapping infomations
+ mPropertyNotificationManager.PropertyNotificationSceneObjectUnmapping(mPropertyNotification);
+
// Remove PropertyNotification using a message to the update manager
RemovePropertyNotificationMessage(mUpdateManager, *mPropertyNotification);
mPropertyNotification = nullptr;
void PropertyNotificationManager::PropertyNotificationDestroyed(PropertyNotification& propertyNotification)
{
- Dali::Vector<PropertyNotification*>::Iterator iter = std::find(mPropertyNotifications.Begin(), mPropertyNotifications.End(), &propertyNotification);
+ auto iter = mPropertyNotifications.Find(&propertyNotification);
DALI_ASSERT_ALWAYS(iter != mPropertyNotifications.End() && "PropertyNotification not found");
- mPropertyNotifications.Remove(iter);
+ mPropertyNotifications.Erase(iter);
}
-void PropertyNotificationManager::NotifyProperty(SceneGraph::PropertyNotification* propertyNotification, bool validity)
+void PropertyNotificationManager::PropertyNotificationSceneObjectMapping(const SceneGraph::PropertyNotification* sceneGraphPropertyNotification, PropertyNotification& propertyNotification)
{
- Dali::Vector<PropertyNotification*>::Iterator iter = mPropertyNotifications.Begin();
- const Dali::Vector<PropertyNotification*>::Iterator endIter = mPropertyNotifications.End();
+ mSceneGraphObjectMap.insert({sceneGraphPropertyNotification, &propertyNotification});
+}
+
+void PropertyNotificationManager::PropertyNotificationSceneObjectUnmapping(const SceneGraph::PropertyNotification* sceneGraphPropertyNotification)
+{
+ auto iter = mSceneGraphObjectMap.find(sceneGraphPropertyNotification);
+ DALI_ASSERT_DEBUG(iter != mSceneGraphObjectMap.end());
- // walk the collection of PropertyNotifications
- for(; iter != endIter; ++iter)
+ mSceneGraphObjectMap.erase(iter);
+}
+
+void PropertyNotificationManager::NotifyProperty(SceneGraph::PropertyNotification* sceneGraphPropertyNotification, bool validity)
+{
+ const auto iter = mSceneGraphObjectMap.find(sceneGraphPropertyNotification);
+ if(iter != mSceneGraphObjectMap.end())
{
- // found one with the matching SceneGraph::PropertyNotification?
- if((*iter)->CompareSceneObject(propertyNotification))
+ // Check if this notification hold inputed scenegraph property notification.
+ auto* propertyNotification = iter->second;
+ if(propertyNotification->CompareSceneObject(sceneGraphPropertyNotification))
{
// allow application to access the value that triggered this emit incase of NOTIFY_ON_CHANGED mode
- (*iter)->SetNotifyResult(validity);
+ propertyNotification->SetNotifyResult(validity);
// yes..emit signal
- (*iter)->EmitSignalNotify();
- break;
+ propertyNotification->EmitSignalNotify();
}
}
}
#define DALI_INTERNAL_PROPERTY_NOTIFICATION_MANAGER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
*
*/
+// EXTERNAL INCLUDES
+#include <unordered_map>
+
// INTERNAL INCLUDES
+#include <dali/internal/common/ordered-set.h>
#include <dali/internal/event/common/property-notifier.h>
#include <dali/public-api/common/dali-vector.h>
*/
void PropertyNotificationDestroyed(PropertyNotification& propertyNotification);
+ /**
+ * Called when a SceneGraph::PropertyNotification is mapping by PropertyNotification.
+ */
+ void PropertyNotificationSceneObjectMapping(const SceneGraph::PropertyNotification* sceneGraphPropertyNotification, PropertyNotification& propertyNotification);
+
+ /**
+ * Called when a SceneGraph::PropertyNotification is unmaped from PropertyNotification.
+ */
+ void PropertyNotificationSceneObjectUnmapping(const SceneGraph::PropertyNotification* sceneGraphPropertyNotification);
+
private: // private virtual overrides
/**
* @copydoc PropertyNotifier::NotifyProperty
*/
- void NotifyProperty(SceneGraph::PropertyNotification* propertyNotification, bool validity) override;
+ void NotifyProperty(SceneGraph::PropertyNotification* sceneGraphPropertyNotification, bool validity) override;
private:
/**
PropertyNotificationManager& operator=(const PropertyNotificationManager& rhs);
private:
- Dali::Vector<PropertyNotification*> mPropertyNotifications; ///< All existing PropertyNotifications (not owned)
+ OrderedSet<PropertyNotification, false> mPropertyNotifications; ///< All existing PropertyNotifications (not owned)
+
+ std::unordered_map<const SceneGraph::PropertyNotification*, PropertyNotification*> mSceneGraphObjectMap; ///< Converter from SceneGraph object pointer to Event object.
};
} // namespace Internal
MemoryPoolRelayoutContainer::MemoryPoolRelayoutContainer(MemoryPoolObjectAllocator<RelayoutInfo>& objectAllocator)
: mAllocator(objectAllocator)
{
+ mDummyRelayoutInfo.reset(new RelayoutInfo());
}
MemoryPoolRelayoutContainer::~MemoryPoolRelayoutContainer() = default;
bool MemoryPoolRelayoutContainer::Contains(const Dali::Actor& actor)
{
- for(RelayoutInfoContainer::Iterator it = mRelayoutInfos.Begin(), itEnd = mRelayoutInfos.End(); it != itEnd; ++it)
- {
- RelayoutInfo* info = *it;
+ // Store actor into dummy info.
+ // It will be used for check comparision.
+ mDummyRelayoutInfo->actor = actor;
- if(info->actor == actor)
- {
- return true;
- }
- }
+ bool ret = (mRelayoutInfos.Find(mDummyRelayoutInfo.get()) != mRelayoutInfos.End());
- return false;
+ // Reset empty handle for deference.
+ mDummyRelayoutInfo->actor = Dali::Actor();
+ return ret;
}
void MemoryPoolRelayoutContainer::Add(const Dali::Actor& actor, const Vector2& size)
void MemoryPoolRelayoutContainer::PopBack()
{
- if(mRelayoutInfos.Size() > 0)
+ if(mRelayoutInfos.Count() > 0)
{
RelayoutInfoContainer::Iterator back = mRelayoutInfos.End();
back--;
RelayoutInfo* info = *back;
- mAllocator.Destroy(info);
mRelayoutInfos.Erase(back);
+
+ // Need to be destroyed after mRelayoutInfos erased.
+ mAllocator.Destroy(info);
}
}
-void MemoryPoolRelayoutContainer::Get(size_t index, Dali::Actor& actorOut, Vector2& sizeOut) const
+void MemoryPoolRelayoutContainer::GetBack(Dali::Actor& actorOut, Vector2& sizeOut) const
{
- DALI_ASSERT_DEBUG(index < Size());
-
- RelayoutInfo* info = mRelayoutInfos[index];
- actorOut = info->actor;
- sizeOut = info->size;
+ if(mRelayoutInfos.Count() > 0)
+ {
+ RelayoutInfoContainer::ConstIterator back = mRelayoutInfos.End();
+ back--;
+ RelayoutInfo* info = *back;
+ actorOut = info->actor;
+ sizeOut = info->size;
+ }
}
size_t MemoryPoolRelayoutContainer::Size() const
{
- return mRelayoutInfos.Size();
+ return mRelayoutInfos.Count();
}
void MemoryPoolRelayoutContainer::Reserve(size_t capacity)
void MemoryPoolRelayoutContainer::Clear()
{
- for(size_t i = 0; i < Size(); ++i)
+ for(auto& info : mRelayoutInfos)
{
- RelayoutInfo* info = mRelayoutInfos[i];
mAllocator.Destroy(info);
}
#define DALI_INTERNAL_MEMORY_POOL_RELAYOUT_CONTAINER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
*
*/
+// EXTERNAL INCLUDES
+#include <memory> // for std::unique_ptr
+
// INTERNAL INCLUDES
#include <dali/public-api/actors/actor.h>
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/size-negotiation/relayout-container.h>
#include <dali/internal/common/memory-pool-object-allocator.h>
+#include <dali/internal/common/ordered-set.h>
namespace Dali
{
{
Dali::Actor actor; ///< The actor to relayout
Vector2 size; ///< The desired size of the actor
+ struct RelayoutInfoHash
+ {
+ std::size_t operator()(const RelayoutInfo* x) const noexcept
+ {
+ return reinterpret_cast<std::size_t>(x->actor.GetObjectPtr());
+ }
+ };
+ struct RelayoutInfoCompare
+ {
+ bool operator()(const RelayoutInfo* lhs, const RelayoutInfo* rhs) const noexcept
+ {
+ return lhs->actor == rhs->actor;
+ }
+ };
};
/**
void PopBack();
/**
- * @brief Retrieve relayout information for the given index
+ * @brief Retrieve relayout information for the latest added
*
- * @param index The index of the information to retrieve
+ * @param[out] actorOut Latest added actor
+ * @param[out] sizeOt Latest added size
*/
- void Get(size_t index, Dali::Actor& actorOut, Vector2& sizeOut) const;
+ void GetBack(Dali::Actor& actorOut, Vector2& sizeOut) const;
/**
* @brief The count of information in the container
*/
void Clear();
+private:
/**
* @brief Returns if the container contains the actor or not
*
bool Contains(const Dali::Actor& actor);
private:
- using RelayoutInfoContainer = Vector<RelayoutInfo*>;
+ using RelayoutInfoContainer = Dali::Internal::OrderedSet<RelayoutInfo, false, RelayoutInfo::RelayoutInfoHash, RelayoutInfo::RelayoutInfoCompare>;
RelayoutInfoContainer mRelayoutInfos; ///< The list of relayout infos
MemoryPoolObjectAllocator<RelayoutInfo>& mAllocator; ///< The memory pool from which the infos are allocated
+
+ std::unique_ptr<RelayoutInfo> mDummyRelayoutInfo; ///< Dummy pointer that will be used to compare relayout infors what we already holded.
};
} // namespace Internal
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
mRelayoutStack->Reserve(32);
}
-RelayoutController::~RelayoutController()
-{
- delete mRelayoutStack;
-}
+RelayoutController::~RelayoutController() = default;
RelayoutController* RelayoutController::Get()
{
Internal::Actor* actorPtr = &GetImplementation(actor);
// Only add the rootActor if it is not already recorded
- auto itr = std::find(mDirtyLayoutSubTrees.begin(), mDirtyLayoutSubTrees.end(), actorPtr);
+ auto iter = mDirtyLayoutSubTrees.Find(actorPtr);
- if(itr == mDirtyLayoutSubTrees.end())
+ if(iter == mDirtyLayoutSubTrees.End())
{
mDirtyLayoutSubTrees.PushBack(actorPtr);
}
void RelayoutController::RemoveRequest(Dali::Actor& actor)
{
Internal::Actor* actorPtr = &GetImplementation(actor);
-
- mDirtyLayoutSubTrees.Erase(std::remove(mDirtyLayoutSubTrees.begin(),
- mDirtyLayoutSubTrees.end(),
- actorPtr),
- mDirtyLayoutSubTrees.end());
+ mDirtyLayoutSubTrees.EraseObject(actorPtr);
}
void RelayoutController::Request()
void RelayoutController::OnObjectDestroyed(const Dali::RefObject* object)
{
- // Search for and null the object if found in the following lists
- FindAndZero(mDirtyLayoutSubTrees, object);
+ mDirtyLayoutSubTrees.EraseObject(static_cast<const Dali::Internal::Actor*>(object));
}
void RelayoutController::Relayout()
{
Dali::Actor actor;
Vector2 size;
- mRelayoutStack->Get(mRelayoutStack->Size() - 1, actor, size);
+
+ mRelayoutStack->GetBack(actor, size);
Actor& actorImpl = GetImplementation(actor);
mRelayoutStack->PopBack();
mProcessingCoreEvents = processingEvents;
}
-void RelayoutController::FindAndZero(const RawActorList& list, const Dali::RefObject* object)
-{
- // Object has been destroyed so clear it from this list
- for(auto& actor : list)
- {
- if(actor && (actor == object))
- {
- actor = nullptr; // Reset the pointer in the list. We don't want to remove it in case something is iterating over the list.
- }
- }
-}
-
uint32_t RelayoutController::GetMemoryPoolCapacity()
{
return mRelayoutInfoAllocator.GetCapacity();
#define DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
// EXTERNAL INCLUDES
#include <cstdint>
+#include <memory> // for unique_ptr
// INTERNAL INCLUDES
#include <dali/internal/common/memory-pool-object-allocator.h>
+#include <dali/internal/common/ordered-set.h>
#include <dali/internal/event/size-negotiation/memory-pool-relayout-container.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/base-object.h>
void OnObjectDestroyed(const Dali::RefObject* object);
private:
- using RawActorList = Dali::Vector<Dali::Internal::Actor*>;
+ using RawActorList = Dali::Internal::OrderedSet<Dali::Internal::Actor, false>;
/**
* @brief Request for relayout. Relays out whole scene.
*/
void QueueActor(Internal::Actor* actor, RelayoutContainer& actors, Vector2 size);
- /**
- * @brief Find the given object in the list and null it out
- *
- * @param[in] list The list to search
- * @param[in] object The object to search for
- */
- void FindAndZero(const RawActorList& list, const Dali::RefObject* object);
-
// Undefined
RelayoutController(const RelayoutController&) = delete;
RelayoutController& operator=(const RelayoutController&) = delete;
SlotDelegate<RelayoutController> mSlotDelegate;
- RawActorList mDirtyLayoutSubTrees; ///< List of roots of sub trees that are dirty
- MemoryPoolRelayoutContainer* mRelayoutStack; ///< Stack for relayouting
+ RawActorList mDirtyLayoutSubTrees; ///< List of roots of sub trees that are dirty
+
+ std::unique_ptr<MemoryPoolRelayoutContainer> mRelayoutStack; ///< Stack for relayouting
bool mRelayoutConnection : 1; ///< Whether EventProcessingFinishedSignal signal is connected.
bool mRelayoutFlag : 1; ///< Relayout flag to avoid unnecessary calls
// INTERNAL INCLUDES
#include <dali/devel-api/threading/thread-pool.h>
#include <dali/integration-api/core.h>
+#include <dali/internal/common/ordered-set.h>
#include <dali/internal/event/common/scene-impl.h>
std::vector<SceneGraph::Scene*> sceneContainer; ///< List of pointers to the scene graph objects of the scenes
Render::RenderAlgorithms renderAlgorithms; ///< The RenderAlgorithms object is used to action the renders required by a RenderInstruction
- OwnerContainer<Render::Sampler*> samplerContainer; ///< List of owned samplers
- OwnerContainer<Render::FrameBuffer*> frameBufferContainer; ///< List of owned framebuffers
- OwnerContainer<Render::VertexBuffer*> vertexBufferContainer; ///< List of owned vertex buffers
- OwnerContainer<Render::Geometry*> geometryContainer; ///< List of owned Geometries
- OwnerContainer<Render::RenderTracker*> mRenderTrackers; ///< List of render trackers
- OwnerKeyContainer<Render::Renderer> rendererContainer; ///< List of owned renderers
- OwnerKeyContainer<Render::Texture> textureContainer; ///< List of owned textures
+ OrderedSet<Render::Sampler> samplerContainer; ///< List of owned samplers
+ OrderedSet<Render::FrameBuffer> frameBufferContainer; ///< List of owned framebuffers
+ OrderedSet<Render::VertexBuffer> vertexBufferContainer; ///< List of owned vertex buffers
+ OrderedSet<Render::Geometry> geometryContainer; ///< List of owned Geometries
+ OwnerKeyContainer<Render::Renderer> rendererContainer; ///< List of owned renderers
+ OwnerKeyContainer<Render::Texture> textureContainer; ///< List of owned textures
+
+ OrderedSet<Render::RenderTracker> mRenderTrackers; ///< List of owned render trackers
ProgramController programController; ///< Owner of the programs
Render::ShaderCache shaderCache; ///< The cache for the graphics shaders
{
DALI_ASSERT_DEBUG(textureKey && "Trying to remove empty texture key");
- // Find the texture, use std::find so we can do the erase safely
- auto iter = std::find(mImpl->textureContainer.begin(), mImpl->textureContainer.end(), textureKey);
+ // Find the texture, use std::find so we can do the erase by iterator safely
+ auto iter = std::find(mImpl->textureContainer.Begin(), mImpl->textureContainer.End(), textureKey);
- if(iter != mImpl->textureContainer.end())
+ if(iter != mImpl->textureContainer.End())
{
textureKey->Destroy();
mImpl->textureContainer.Erase(iter); // Texture found; now destroy it
{
DALI_ASSERT_DEBUG(nullptr != frameBuffer);
- // Find the framebuffer, use std:find so we can safely do the erase
- auto iter = std::find(mImpl->frameBufferContainer.begin(), mImpl->frameBufferContainer.end(), frameBuffer);
+ // Find the framebuffer, use OrderedSet.Find so we can safely do the erase
+ auto iter = mImpl->frameBufferContainer.Find(frameBuffer);
- if(iter != mImpl->frameBufferContainer.end())
+ if(iter != mImpl->frameBufferContainer.End())
{
frameBuffer->Destroy();
mImpl->frameBufferContainer.Erase(iter); // frameBuffer found; now destroy it
void RenderManager::RemoveGeometry(Render::Geometry* geometry)
{
- auto iter = std::find(mImpl->geometryContainer.begin(), mImpl->geometryContainer.end(), geometry);
-
- if(iter != mImpl->geometryContainer.end())
- {
- mImpl->geometryContainer.Erase(iter);
- }
+ mImpl->geometryContainer.EraseObject(geometry);
}
void RenderManager::AttachVertexBuffer(Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer)
{
- DALI_ASSERT_DEBUG(nullptr != geometry);
-
- // Find the geometry
- for(auto&& iter : mImpl->geometryContainer)
- {
- if(iter == geometry)
- {
- iter->AddVertexBuffer(vertexBuffer);
- break;
- }
- }
+ geometry->AddVertexBuffer(vertexBuffer);
}
void RenderManager::RemoveVertexBuffer(Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer)
{
- DALI_ASSERT_DEBUG(nullptr != geometry);
-
- // Find the geometry
- for(auto&& iter : mImpl->geometryContainer)
- {
- if(iter == geometry)
- {
- iter->RemoveVertexBuffer(vertexBuffer);
- break;
- }
- }
+ geometry->RemoveVertexBuffer(vertexBuffer);
}
void RenderManager::SetGeometryType(Render::Geometry* geometry, uint32_t geometryType)
#define DALI_INTERNAL_SCENE_GRAPH_PROPERTY_NOTIFICATION_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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/devel-api/common/owner-container.h>
#include <dali/internal/event/common/property-notification-impl.h>
#include <dali/internal/update/common/property-base.h>
#include <dali/public-api/object/property-notification.h>
{
class PropertyNotification;
-using PropertyNotificationContainer = OwnerContainer<PropertyNotification*>;
-using PropertyNotificationIter = PropertyNotificationContainer::Iterator;
-using PropertyNotificationConstIter = PropertyNotificationContainer::ConstIterator;
-using ConditionFunction = bool (*)(const Dali::PropertyInput&, Dali::Internal::PropertyNotification::RawArgumentContainer&);
+using ConditionFunction = bool (*)(const Dali::PropertyInput&, Dali::Internal::PropertyNotification::RawArgumentContainer&);
/**
* PropertyNotifications are used to inspect properties of scene graph objects, as part of a scene
ResetterContainer<PropertyResetterBase> propertyResetters; ///< A container of property resetters
ResetterContainer<NodeResetter> nodeResetters; ///< A container of node resetters
- OwnerContainer<Animation*> animations; ///< A container of owned animations
- PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
- OwnerKeyContainer<Renderer> renderers; ///< A container of owned renderers
- OwnerContainer<TextureSet*> textureSets; ///< A container of owned texture sets
- OwnerContainer<Shader*> shaders; ///< A container of owned shaders
+ OwnerContainer<Animation*> animations; ///< A container of owned animations
+ OwnerContainer<PropertyNotification*> propertyNotifications; ///< A container of owner property notifications.
+ OwnerKeyContainer<Renderer> renderers; ///< A container of owned renderers
+ OwnerContainer<TextureSet*> textureSets; ///< A container of owned texture sets
+ OwnerContainer<Shader*> shaders; ///< A container of owned shaders
DiscardQueue<Node*, OwnerContainer<Node*>> nodeDiscardQueue; ///< Nodes are added here when disconnected from the scene-graph.
DiscardQueue<Shader*, OwnerContainer<Shader*>> shaderDiscardQueue;