SET(TC_SOURCES
utc-Dali-Internal-ActorObserver.cpp
utc-Dali-Internal-ActorRelayout.cpp
+ utc-Dali-Internal-ConstString.cpp
utc-Dali-Internal-Core.cpp
utc-Dali-Internal-FixedSizeMemoryPool.cpp
utc-Dali-Internal-FrustumCulling.cpp
utc-Dali-Internal-Gesture.cpp
utc-Dali-Internal-Handles.cpp
+ utc-Dali-Internal-IndexedConstStringMap.cpp
+ utc-Dali-Internal-IndexedIntegerMap.cpp
utc-Dali-Internal-LongPressGesture.cpp
utc-Dali-Internal-MemoryPoolObjectAllocator.cpp
utc-Dali-Internal-OwnerPointer.cpp
utc-Dali-Internal-RotationGesture.cpp
utc-Dali-Internal-TapGesture.cpp
utc-Dali-Internal-TapGestureProcessor.cpp
- utc-Dali-Internal-ConstString.cpp
utc-Dali-Internal-TransformManagerProperty.cpp
)
--- /dev/null
+/*
+ * Copyright (c) 2022 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/public-api/dali-core.h>
+
+#include <random>
+#include <string>
+
+// Internal headers are allowed here
+#include <dali/internal/common/indexed-const-string-map.h>
+
+using namespace Dali;
+using Dali::Internal::ConstString;
+using Dali::Internal::IndexedConstStringMap;
+namespace
+{
+std::string RandomString(size_t length)
+{
+ static auto& chrs =
+ "0123456789"
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ thread_local static std::mt19937 rg{std::random_device{}()};
+ thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);
+
+ std::string s;
+
+ s.reserve(length);
+
+ while(length--)
+ s += chrs[pick(rg)];
+
+ return s;
+}
+
+// Custom << operator to print debugging log.
+std::basic_ostream<char>& operator<<(std::basic_ostream<char>& os, const ConstString& constString)
+{
+ std::string convertedString = std::string(constString.GetStringView());
+ os << convertedString;
+ return os;
+}
+
+} // namespace
+
+void utc_dali_internal_indexed_conststring_map_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_internal_indexed_conststring_map_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int UtcDaliIndexedConstStringMapEmpty(void)
+{
+ IndexedConstStringMap<int> indexedMap;
+ DALI_TEST_EQUALS(indexedMap.Empty(), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.empty(), true, TEST_LOCATION);
+
+ ConstString str("hello");
+ int value = 3;
+ DALI_TEST_EQUALS(indexedMap.Register(str, value), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(indexedMap.Empty(), false, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.empty(), false, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(indexedMap.Count(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.size(), 1, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(indexedMap.Get(str)->first, str, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.Get(str)->second, value, TEST_LOCATION);
+
+ indexedMap.Clear();
+ DALI_TEST_EQUALS(indexedMap.Empty(), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.empty(), true, TEST_LOCATION);
+
+ DALI_TEST_CHECK(indexedMap.Get(str) == indexedMap.End());
+
+ END_TEST;
+}
+
+int UtcDaliIndexedConstStringMap(void)
+{
+ IndexedConstStringMap<int> indexedMap;
+
+ auto IndexedMapGetValueTest = [](const IndexedConstStringMap<int>& indexedMap, ConstString key, bool registered, int element, const char* location) {
+ const auto& iter = indexedMap.Get(key);
+ DALI_TEST_EQUALS(!(iter == indexedMap.end()), registered, location);
+ if(registered)
+ {
+ DALI_TEST_EQUALS(iter->second, element, location);
+ }
+ };
+
+ ConstString keyFirst = ConstString("first");
+ ConstString keySecond = ConstString("second");
+ ConstString keyThird = ConstString("third");
+ ConstString keyFourth = ConstString("fourth");
+
+ // Check. empty state
+ DALI_TEST_EQUALS(0u, indexedMap.Count(), TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.Begin() == indexedMap.End());
+ DALI_TEST_CHECK(indexedMap.Empty());
+ DALI_TEST_EQUALS(0u, indexedMap.size(), TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.begin() == indexedMap.end());
+ DALI_TEST_CHECK(indexedMap.empty());
+
+ // phase 1 - Regist two element
+ DALI_TEST_CHECK(indexedMap.Register(keyFirst, 1));
+ DALI_TEST_CHECK(indexedMap.Register(keySecond, 2));
+
+ // Get data by key
+ DALI_TEST_EQUALS(2u, indexedMap.Count(), TEST_LOCATION);
+ DALI_TEST_CHECK(!indexedMap.Empty());
+ IndexedMapGetValueTest(indexedMap, ConstString("first"), true, 1, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, ConstString("second"), true, 2, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, ConstString("third"), false, 0, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, ConstString("fourth"), false, 0, TEST_LOCATION);
+
+ // Get data by index
+ DALI_TEST_EQUALS(indexedMap[keyFirst], 1, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keySecond], 2, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(0), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(1), 2, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(0), keyFirst, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(1), keySecond, TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(0) == IndexedConstStringMap<int>::KeyElementPairType(keyFirst, 1));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(1) == IndexedConstStringMap<int>::KeyElementPairType(keySecond, 2));
+
+ // Const iteration check
+ for(const auto& elem : indexedMap)
+ {
+ if(elem.first == keyFirst)
+ {
+ DALI_TEST_EQUALS(elem.second, 1, TEST_LOCATION);
+ }
+ else if(elem.first == keySecond)
+ {
+ DALI_TEST_EQUALS(elem.second, 2, TEST_LOCATION);
+ }
+ else
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ }
+
+ // Iteration and fix data check
+ for(auto&& elem : indexedMap)
+ {
+ if(elem.first == keyFirst)
+ {
+ elem.second += 110;
+ }
+ }
+ // operator[] fix data check
+ indexedMap[keySecond] += 220;
+
+ // Get data by key
+ DALI_TEST_EQUALS(2u, indexedMap.Count(), TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFirst, true, 111, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keySecond, true, 222, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyThird, false, 0, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFourth, false, 0, TEST_LOCATION);
+
+ // Get data by index
+ DALI_TEST_EQUALS(indexedMap[keyFirst], 111, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keySecond], 222, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(0), 111, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(1), 222, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(0), keyFirst, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(1), keySecond, TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(0) == IndexedConstStringMap<int>::KeyElementPairType(keyFirst, 111));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(1) == IndexedConstStringMap<int>::KeyElementPairType(keySecond, 222));
+
+ // Const iteration check
+ for(const auto& elem : indexedMap)
+ {
+ if(elem.first == keyFirst)
+ {
+ DALI_TEST_EQUALS(elem.second, 111, TEST_LOCATION);
+ }
+ else if(elem.first == keySecond)
+ {
+ DALI_TEST_EQUALS(elem.second, 222, TEST_LOCATION);
+ }
+ else
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ }
+
+ // phase 2 - Regist two more element
+ DALI_TEST_CHECK(!indexedMap.Register(keyFirst, 11)); // Register failed when we try to insert data with same key
+ DALI_TEST_CHECK(!indexedMap.Register(keySecond, 22)); // Register failed when we try to insert data with same key
+ DALI_TEST_CHECK(indexedMap.Register(keyThird, 3));
+ DALI_TEST_CHECK(indexedMap.Register(keyFourth, 4));
+
+ // Get data by key
+ DALI_TEST_EQUALS(4, indexedMap.Count(), TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFirst, true, 111, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keySecond, true, 222, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyThird, true, 3, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFourth, true, 4, TEST_LOCATION);
+
+ // Get elemnt as l-value
+ {
+ auto iter = indexedMap.Get(keyFourth);
+ DALI_TEST_CHECK(iter != indexedMap.end())
+ {
+ iter->second = 444;
+ }
+ }
+
+ // Get data by index
+ DALI_TEST_EQUALS(indexedMap[keyFirst], 111, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keySecond], 222, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keyThird], 3, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keyFourth], 444, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(0), 111, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(1), 222, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(2), 3, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(3), 444, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(0), keyFirst, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(1), keySecond, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(2), keyThird, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(3), keyFourth, TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(0) == IndexedConstStringMap<int>::KeyElementPairType(keyFirst, 111));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(1) == IndexedConstStringMap<int>::KeyElementPairType(keySecond, 222));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(2) == IndexedConstStringMap<int>::KeyElementPairType(keyThird, 3));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(3) == IndexedConstStringMap<int>::KeyElementPairType(keyFourth, 444));
+
+ // For coverage
+ DALI_TEST_EQUALS(const_cast<const IndexedConstStringMap<int>&>(indexedMap)[keyFirst], 111, TEST_LOCATION);
+
+ // Clear check
+ DALI_TEST_CHECK(!indexedMap.Empty());
+ indexedMap.Clear();
+ DALI_TEST_CHECK(indexedMap.Empty());
+ DALI_TEST_EQUALS(0u, indexedMap.Count(), TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFirst, false, 1, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keySecond, false, 2, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyThird, false, 3, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFourth, false, 4, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliIndexedConstStringMapNegative(void)
+{
+ tet_infoline("Negative test when IndexedConstStringMap access non-exist elements.");
+
+ IndexedConstStringMap<int> indexedMap;
+
+ auto IndexedMapAssertTestWithIndex = [](IndexedConstStringMap<int>& indexedMap, int testIndex) {
+ tet_printf("operator[] test");
+ // Assert when try to access as const operator[] input with not registered key.
+ try
+ {
+ const auto& elem = const_cast<const IndexedConstStringMap<int>&>(indexedMap)[ConstString("333")];
+ if(elem == 0) // Avoid build warning
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+ // Assert when try to access as operator[] input with not registered key.
+ try
+ {
+ indexedMap[ConstString("333")] = 0;
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+
+ tet_printf("GetElementByIndex test");
+ // Assert when try to access as GetElementByIndex input with not registered index.
+ try
+ {
+ const auto& elem = indexedMap.GetElementByIndex(testIndex);
+ if(elem == 0) // Avoid build warning
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+
+ tet_printf("GetKeyByIndex test");
+ // Assert when try to access as GetKeyByIndex input with not registered index.
+ try
+ {
+ const auto& elem = indexedMap.GetKeyByIndex(testIndex);
+ if(elem == 0) // Avoid build warning
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+
+ tet_printf("GetKeyElementPairByIndex test");
+ // Assert when try to access as GetKeyByIndex input with not registered index.
+ try
+ {
+ const auto& elem = indexedMap.GetKeyElementPairByIndex(testIndex);
+ if(elem == IndexedConstStringMap<int>::KeyElementPairType(ConstString("zero"), 0)) // Avoid build warning
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+ };
+ // Assert test with empty indexedMap.
+ DALI_TEST_CHECK(indexedMap.Empty());
+ IndexedMapAssertTestWithIndex(indexedMap, 0);
+
+ // Register 2 data
+ DALI_TEST_CHECK(indexedMap.Register(ConstString("first"), 1));
+ DALI_TEST_CHECK(indexedMap.Register(ConstString("second"), 2));
+ DALI_TEST_EQUALS(2u, indexedMap.Count(), TEST_LOCATION);
+ IndexedMapAssertTestWithIndex(indexedMap, 2);
+
+ // Test with always-invalid index like -1
+ IndexedMapAssertTestWithIndex(indexedMap, -1);
+
+ END_TEST;
+}
+
+int UtcDaliIndexedConstStringMapStressTest(void)
+{
+ // Copy from utc-Dali-Internal-ConstString.cpp
+ static constexpr size_t DB_SIZE = 2000;
+
+ std::vector<std::string> Database;
+ Database.reserve(DB_SIZE);
+
+ IndexedConstStringMap<ConstString> constStringDB1;
+ constStringDB1.reserve(DB_SIZE);
+
+ IndexedConstStringMap<std::string> constStringDB2;
+ constStringDB2.reserve(DB_SIZE);
+
+ for(auto i = 0u; i < DB_SIZE; i++)
+ {
+ if(i % 3 == 0)
+ {
+ Database.push_back(RandomString(10));
+ }
+ else if(i % 4 == 0)
+ {
+ Database.push_back(RandomString(7));
+ }
+ else
+ {
+ Database.push_back(RandomString(11));
+ }
+ std::string randomValue = RandomString(10);
+ DALI_TEST_EQUALS(constStringDB1.Register(ConstString(Database[i]), ConstString(randomValue)), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(constStringDB2.Register(ConstString(Database[i]), randomValue), true, TEST_LOCATION);
+ }
+
+ // Try to extra regist with same key
+ for(auto i = 0u; i < DB_SIZE; i++)
+ {
+ std::string randomValue = RandomString(2);
+ DALI_TEST_EQUALS(constStringDB1.Register(ConstString(Database[i]), ConstString(randomValue)), false, TEST_LOCATION);
+ DALI_TEST_EQUALS(constStringDB2.Register(ConstString(Database[i]), randomValue), false, TEST_LOCATION);
+ }
+
+ // check eqality betwwen original string and constString
+ for(auto i = 0u; i < DB_SIZE; i++)
+ {
+ DALI_TEST_EQUALS(constStringDB1.GetKeyByIndex(i).GetCString(), Database[i].c_str(), TEST_LOCATION);
+ DALI_TEST_EQUALS(constStringDB2.GetKeyByIndex(i).GetCString(), Database[i].c_str(), TEST_LOCATION);
+ }
+
+ // check pointer eqality betwwen 2 constString
+ for(auto i = 0u; i < DB_SIZE; i++)
+ {
+ bool pointerEqual = (constStringDB1[ConstString(Database[i])] == ConstString(constStringDB2[ConstString(Database[i])]));
+ DALI_TEST_EQUALS(pointerEqual, true, TEST_LOCATION);
+ }
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 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 <stdlib.h>
+#include <string>
+
+#include <dali/internal/common/indexed-integer-map.h>
+
+using namespace Dali;
+using Dali::Internal::IndexedIntegerMap;
+
+void utc_dali_indexed_integer_map_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_indexed_integer_map_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int UtcDaliIndexedIntegerMap(void)
+{
+ IndexedIntegerMap<int> indexedMap;
+ const std::uint32_t keyFirst = 111111u;
+ const std::uint32_t keySecond = 222222u;
+ const std::uint32_t keyThird = 333333u;
+ const std::uint32_t keyFourth = 444444u;
+
+ auto IndexedMapGetValueTest = [](const IndexedIntegerMap<int>& indexedMap, std::uint32_t key, bool registered, int element, const char* location) {
+ const auto& iter = indexedMap.Get(key);
+ DALI_TEST_EQUALS(!(iter == indexedMap.end()), registered, location);
+ if(registered)
+ {
+ DALI_TEST_EQUALS(iter->second, element, location);
+ }
+ };
+
+ // Check. empty state
+ DALI_TEST_EQUALS(0u, indexedMap.Count(), TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.Begin() == indexedMap.End());
+ DALI_TEST_CHECK(indexedMap.Empty());
+ DALI_TEST_EQUALS(0u, indexedMap.size(), TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.begin() == indexedMap.end());
+ DALI_TEST_CHECK(indexedMap.empty());
+
+ // phase 1 - Regist two element
+ DALI_TEST_CHECK(indexedMap.Register(keyFirst, 1));
+ DALI_TEST_CHECK(indexedMap.Register(keySecond, 2));
+
+ // Get data by key
+ DALI_TEST_EQUALS(2u, indexedMap.Count(), TEST_LOCATION);
+ DALI_TEST_CHECK(!indexedMap.Empty());
+ IndexedMapGetValueTest(indexedMap, keyFirst, true, 1, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keySecond, true, 2, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyThird, false, 0, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFourth, false, 0, TEST_LOCATION);
+
+ // Get data by index
+ DALI_TEST_EQUALS(indexedMap[keyFirst], 1, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keySecond], 2, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(0), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(1), 2, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(0), keyFirst, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(1), keySecond, TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(0) == IndexedIntegerMap<int>::KeyElementPairType(keyFirst, 1));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(1) == IndexedIntegerMap<int>::KeyElementPairType(keySecond, 2));
+
+ // Const iteration check
+ for(const auto& elem : indexedMap)
+ {
+ if(elem.first == keyFirst)
+ {
+ DALI_TEST_EQUALS(elem.second, 1, TEST_LOCATION);
+ }
+ else if(elem.first == keySecond)
+ {
+ DALI_TEST_EQUALS(elem.second, 2, TEST_LOCATION);
+ }
+ else
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ }
+
+ // Iteration and fix data check
+ for(auto&& elem : indexedMap)
+ {
+ if(elem.first == keyFirst)
+ {
+ elem.second += 110;
+ }
+ }
+ // operator[] fix data check
+ indexedMap[keySecond] += 220;
+
+ // Get data by key
+ DALI_TEST_EQUALS(2u, indexedMap.Count(), TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFirst, true, 111, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keySecond, true, 222, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyThird, false, 0, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFourth, false, 0, TEST_LOCATION);
+
+ // Get data by index
+ DALI_TEST_EQUALS(indexedMap[keyFirst], 111, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keySecond], 222, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(0), 111, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(1), 222, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(0), keyFirst, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(1), keySecond, TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(0) == IndexedIntegerMap<int>::KeyElementPairType(keyFirst, 111));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(1) == IndexedIntegerMap<int>::KeyElementPairType(keySecond, 222));
+
+ // Const iteration check
+ for(const auto& elem : indexedMap)
+ {
+ if(elem.first == keyFirst)
+ {
+ DALI_TEST_EQUALS(elem.second, 111, TEST_LOCATION);
+ }
+ else if(elem.first == keySecond)
+ {
+ DALI_TEST_EQUALS(elem.second, 222, TEST_LOCATION);
+ }
+ else
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ }
+
+ // phase 2 - Regist two more element
+ DALI_TEST_CHECK(!indexedMap.Register(keyFirst, 11)); // Register failed when we try to insert data with same key
+ DALI_TEST_CHECK(!indexedMap.Register(keySecond, 22)); // Register failed when we try to insert data with same key
+ DALI_TEST_CHECK(indexedMap.Register(keyThird, 3));
+ DALI_TEST_CHECK(indexedMap.Register(keyFourth, 4));
+
+ // Get data by key
+ DALI_TEST_EQUALS(4, indexedMap.Count(), TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFirst, true, 111, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keySecond, true, 222, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyThird, true, 3, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFourth, true, 4, TEST_LOCATION);
+
+ // Get elemnt as l-value
+ {
+ auto iter = indexedMap.Get(keyFourth);
+ DALI_TEST_CHECK(iter != indexedMap.end())
+ {
+ iter->second = 444;
+ }
+ }
+
+ // Get data by index
+ DALI_TEST_EQUALS(indexedMap[keyFirst], 111, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keySecond], 222, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keyThird], 3, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap[keyFourth], 444, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(0), 111, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(1), 222, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(2), 3, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetElementByIndex(3), 444, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(0), keyFirst, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(1), keySecond, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(2), keyThird, TEST_LOCATION);
+ DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(3), keyFourth, TEST_LOCATION);
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(0) == IndexedIntegerMap<int>::KeyElementPairType(keyFirst, 111));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(1) == IndexedIntegerMap<int>::KeyElementPairType(keySecond, 222));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(2) == IndexedIntegerMap<int>::KeyElementPairType(keyThird, 3));
+ DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(3) == IndexedIntegerMap<int>::KeyElementPairType(keyFourth, 444));
+
+ // For coverage
+ DALI_TEST_EQUALS(const_cast<const IndexedIntegerMap<int>&>(indexedMap)[keyFirst], 111, TEST_LOCATION);
+
+ // Clear check
+ DALI_TEST_CHECK(!indexedMap.Empty());
+ indexedMap.Clear();
+ DALI_TEST_CHECK(indexedMap.Empty());
+ DALI_TEST_EQUALS(0u, indexedMap.Count(), TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFirst, false, 1, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keySecond, false, 2, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyThird, false, 3, TEST_LOCATION);
+ IndexedMapGetValueTest(indexedMap, keyFourth, false, 4, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliIndexedIntegerMapNegative(void)
+{
+ tet_infoline("Negative test when IndexedIntegerMap access non-exist elements.");
+
+ IndexedIntegerMap<int> indexedMap;
+
+ auto IndexedMapAssertTestWithIndex = [](IndexedIntegerMap<int>& indexedMap, int testIndex) {
+ tet_printf("operator[] test");
+ // Assert when try to access as const operator[] input with not registered key.
+ try
+ {
+ const auto& elem = const_cast<const IndexedIntegerMap<int>&>(indexedMap)[333];
+ if(elem == 0) // Avoid build warning
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+ // Assert when try to access as operator[] input with not registered key.
+ try
+ {
+ indexedMap[333] = 0;
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+
+ tet_printf("GetElementByIndex test");
+ // Assert when try to access as GetElementByIndex input with not registered index.
+ try
+ {
+ const auto& elem = indexedMap.GetElementByIndex(testIndex);
+ if(elem == 0) // Avoid build warning
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+
+ tet_printf("GetKeyByIndex test");
+ // Assert when try to access as GetKeyByIndex input with not registered index.
+ try
+ {
+ const auto& elem = indexedMap.GetKeyByIndex(testIndex);
+ if(elem == 0) // Avoid build warning
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+
+ tet_printf("GetKeyElementPairByIndex test");
+ // Assert when try to access as GetKeyByIndex input with not registered index.
+ try
+ {
+ const auto& elem = indexedMap.GetKeyElementPairByIndex(testIndex);
+ if(elem == IndexedIntegerMap<int>::KeyElementPairType(0, 0)) // Avoid build warning
+ {
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Asserted
+ }
+ };
+ // Assert test with empty indexedMap.
+ DALI_TEST_CHECK(indexedMap.Empty());
+ IndexedMapAssertTestWithIndex(indexedMap, 0);
+
+ // Register 2 data
+ DALI_TEST_CHECK(indexedMap.Register(111, 1));
+ DALI_TEST_CHECK(indexedMap.Register(222, 2));
+ DALI_TEST_EQUALS(2u, indexedMap.Count(), TEST_LOCATION);
+ IndexedMapAssertTestWithIndex(indexedMap, 2);
+
+ // Test with always-invalid index like -1
+ IndexedMapAssertTestWithIndex(indexedMap, -1);
+
+ END_TEST;
+}
+
+int UtcDaliIndexedIntegerMapStressTest(void)
+{
+ IndexedIntegerMap<int> indexedMap;
+
+ std::vector<std::uint32_t> keyList(2 * (256 + 2));
+
+ // Add 256 kind keys and +- 1
+ for(std::uint32_t i = 0; i < 256 + 2; i++)
+ {
+ // Intention overflow here
+ keyList[i] = i - 1;
+ keyList[i + 256 + 2] = ((i - 1) << 24) + (((i - 1) >> 8) & 15);
+ if(i == 1)
+ {
+ //To avoid same Key
+ keyList[i + 256 + 2] = 0x0f0f0f0f;
+ }
+ if(i == 257)
+ {
+ //To avoid same Key
+ keyList[i + 256 + 2] = 0xf0f0f0f0;
+ }
+ }
+
+ auto IndexedMapGetValueTest = [](const IndexedIntegerMap<int>& indexedMap, std::uint32_t key, bool registered, int element) {
+ const auto& iter = indexedMap.Get(key);
+ DALI_TEST_CHECK(!(iter == indexedMap.end()) == registered);
+ if(registered)
+ {
+ DALI_TEST_CHECK(iter->second == element);
+ }
+ };
+
+ for(std::size_t i = 0; i < keyList.size(); i++)
+ {
+ // We don't need to check whole key. Just compare near 0 and 256+2
+ for(std::size_t j = 0; j < i && j < 4; j++)
+ {
+ DALI_TEST_CHECK(!indexedMap.Register(keyList[j], -j - 1));
+ }
+ for(std::size_t j = 256; j < i && j < 256 + 6; j++)
+ {
+ DALI_TEST_CHECK(!indexedMap.Register(keyList[j], -j - 1));
+ }
+
+ // Regist i'th keylist
+ DALI_TEST_CHECK(indexedMap.Register(keyList[i], i));
+
+ // We don't need to check whole key. Just compare near 0 and 256+2 and end and i
+ for(std::size_t j = 0; j < keyList.size() && j < 20; j++)
+ {
+ IndexedMapGetValueTest(indexedMap, keyList[j], j <= i, j);
+ }
+ for(std::size_t j = 256 - 18; j < keyList.size() && j < 256 + 22; j++)
+ {
+ IndexedMapGetValueTest(indexedMap, keyList[j], j <= i, j);
+ }
+ for(std::size_t j = keyList.size() - 20; j < keyList.size(); j++)
+ {
+ IndexedMapGetValueTest(indexedMap, keyList[j], j <= i, j);
+ }
+ // When i < 20 overflow occured, but dont care.
+ for(std::size_t j = i - 20; j < keyList.size() && j < i + 20; j++)
+ {
+ IndexedMapGetValueTest(indexedMap, keyList[j], j <= i, j);
+ }
+
+ // Keylist have over 500 kind of keys. Print debug rarely.
+ if(i % 50 == 0)
+ {
+ tet_printf("%u / %u pass\n", i, keyList.size());
+ }
+ }
+
+ END_TEST;
+}
--- /dev/null
+#ifndef DALI_INDEXED_CONST_STRING_MAP_H
+#define DALI_INDEXED_CONST_STRING_MAP_H
+
+/*
+ * Copyright (c) 2022 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/internal/common/const-string.h>
+#include <dali/internal/common/indexed-map-base.h>
+
+namespace Dali
+{
+namespace Internal
+{
+/**
+ * @brief Specific key-element container which can access by index when key is Dali::Internal::ConstString.
+ * Register element by key. and Get element by key or index.
+ *
+ * Register operation return false when already same key registered.
+ * Get operation return iterator of this container.
+ *
+ * Actually, ConstString type did comparision-and-compare with known strings internally.
+ * That mean, we can assume that ConstString already hashed as const char* type. (== std::size_t)
+ *
+ * This container just hold const char* type keys in increase order, and binary search.
+ * This system have panalty when insert / delete. and have benefit when search.
+ *
+ * @note : Current IndexedConstStringMap allow only for single element per key.
+ * And also, did not allow to Unregister operation.
+ *
+ * @note Time complexity :
+ * Register() : O(ConstString converting time + Number of data)
+ * Get() : O(ConstString converting time + log(Number of data))
+ *
+ * @tparam ElementType The type of the data that the container holds
+ */
+template<typename ElementType>
+class IndexedConstStringMap : public IndexedMapBase<ConstString, ConstString, ElementType>
+{
+public:
+ using iterator = typename IndexedMapBase<ConstString, ConstString, ElementType>::iterator;
+ using const_iterator = typename IndexedMapBase<ConstString, ConstString, ElementType>::const_iterator;
+
+public: // override
+ /**
+ * @brief Constructor.
+ */
+ IndexedConstStringMap()
+ : IndexedMapBase<ConstString, ConstString, ElementType>()
+ {
+ }
+
+ /**
+ * @copydoc IndexedMapBase::Clear()
+ */
+ void Clear() override
+ {
+ mKeyElementPool.clear();
+ mCharPtrIndexList.clear();
+ }
+
+public: // Main API
+ /**
+ * @brief Register element by the ConstString key.
+ *
+ * @param[in] key The ConstString key that this container will hold. Duplicated key doesn't allow.
+ * @param[in] element The element pairwise with key.
+ * @return True if Register success. Otherwise, return false.
+ */
+ bool Register(const ConstString& key, const ElementType& element) override
+ {
+ // Let's make key as compareable type.
+ const char* comparableKey = key.GetCString();
+
+ // Find key with binary search.
+ // We can do binary search cause mCharPtrIndexList is sorted.
+ const auto& iter = std::lower_bound(mCharPtrIndexList.cbegin(), mCharPtrIndexList.cend(), std::pair<const char*, std::uint32_t>(comparableKey, 0u));
+
+ if(iter == mCharPtrIndexList.cend() || iter->first != comparableKey)
+ {
+ // Emplace new element back.
+ std::uint32_t newElementIndex = mKeyElementPool.size();
+ mKeyElementPool.emplace_back(key, element);
+
+ // Add new index into mCharPtrIndexList.
+ mCharPtrIndexList.insert(iter, std::pair<const char*, std::uint32_t>(comparableKey, newElementIndex));
+
+ // Append element as child
+ return true;
+ }
+ else
+ {
+ // Else, duplicated key!
+ return false;
+ }
+ }
+
+ /**
+ * @brief Get element by the ConstString key.
+ *
+ * @param[in] key The ConstString key that this container will hold.
+ * @return If exist, iterator of container. Otherwise, return End().
+ */
+ iterator Get(const ConstString& key) override
+ {
+ // Let's make key as compareable type.
+ const char* comparableKey = key.GetCString();
+
+ // Find key with binary search.
+ // We can do binary search cause mCharPtrIndexList is sorted.
+ const auto& iter = std::lower_bound(mCharPtrIndexList.cbegin(), mCharPtrIndexList.cend(), std::pair<const char*, std::uint32_t>(comparableKey, 0u));
+
+ if(iter == mCharPtrIndexList.cend() || iter->first != comparableKey)
+ {
+ // Key doesn't exist!
+ return this->End();
+ }
+
+ // We found it!
+ // iter->second will be the index of elements.
+ return this->Begin() + (iter->second);
+ }
+
+ /**
+ * @brief Get element by the ConstString key.
+ *
+ * @param[in] key The ConstString key that this container will hold.
+ * @return If exist, iterator of container. Otherwise, return End().
+ */
+ const_iterator Get(const ConstString& key) const override
+ {
+ // Let's make key as compareable type.
+ const char* comparableKey = key.GetCString();
+
+ // Find key with binary search.
+ // We can do binary search cause mCharPtrIndexList is sorted.
+ const auto& iter = std::lower_bound(mCharPtrIndexList.cbegin(), mCharPtrIndexList.cend(), std::pair<const char*, std::uint32_t>(comparableKey, 0u));
+
+ if(iter == mCharPtrIndexList.cend() || iter->first != comparableKey)
+ {
+ // Key doesn't exist!
+ return this->End();
+ }
+
+ // We found it!
+ // iter->second will be the index of elements.
+ return this->Begin() + (iter->second);
+ }
+
+private:
+ /**
+ * @brief Convert from char* to index of container.
+ *
+ * @note mCharPtrIndexList's key should be increase order compare as std::size_t.
+ */
+ std::vector<std::pair<const char*, std::uint32_t>> mCharPtrIndexList{};
+
+protected:
+ /**
+ * @brief Member values from base class.
+ */
+ using IndexedMapBase<ConstString, ConstString, ElementType>::mKeyElementPool;
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INDEXED_CONST_STRING_MAP_H
--- /dev/null
+#ifndef DALI_INDEXED_INTEGER_MAP_H
+#define DALI_INDEXED_INTEGER_MAP_H
+
+/*
+ * Copyright (c) 2022 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/internal/common/indexed-map-base.h>
+
+namespace Dali
+{
+namespace Internal
+{
+/**
+ * @brief Specific key-element container which can access by index when key is std::uint32_t.
+ * Register element by key. and Get element by key or index.
+ *
+ * Register operation return false when already same key registered.
+ * Get operation return iterator of this container.
+ *
+ * This container hold integer keys in increase order, and binary search.
+ * This system have panalty when insert / delete. and have benefit when search.
+ *
+ * @note : Current IndexedIntegerMap allow only for single element per key.
+ * And also, did not allow to Unregister operation.
+ *
+ * @note Time complexity :
+ * Register() : O(Number of data)
+ * Get() : O(log(Number of data))
+ *
+ * @tparam ElementType The type of the data that the container holds
+ */
+template<typename ElementType>
+class IndexedIntegerMap : public IndexedMapBase<std::uint32_t, std::uint32_t, ElementType>
+{
+public:
+ using iterator = typename IndexedMapBase<std::uint32_t, std::uint32_t, ElementType>::iterator;
+ using const_iterator = typename IndexedMapBase<std::uint32_t, std::uint32_t, ElementType>::const_iterator;
+
+public: // override
+ /**
+ * @brief Constructor.
+ */
+ IndexedIntegerMap()
+ : IndexedMapBase<std::uint32_t, std::uint32_t, ElementType>()
+ {
+ }
+
+ /**
+ * @copydoc IndexedMapBase::Clear()
+ */
+ void Clear() override
+ {
+ mKeyElementPool.clear();
+ mKeyIndexList.clear();
+ }
+
+public: // Main API
+ /**
+ * @brief Register element by the integer key.
+ *
+ * @param[in] key The integer key that this container will hold. Duplicated key doesn't allow.
+ * @param[in] element The element pairwise with key.
+ * @return True if Register success. Otherwise, return false.
+ */
+ bool Register(const std::uint32_t& key, const ElementType& element) override
+ {
+ // Find key with binary search.
+ // We can do binary search cause mKeyIndexList is sorted.
+ const auto& iter = std::lower_bound(mKeyIndexList.cbegin(), mKeyIndexList.cend(), std::pair<std::uint32_t, std::uint32_t>(key, 0u));
+
+ if(iter == mKeyIndexList.cend() || iter->first != key)
+ {
+ // Emplace new element back.
+ std::uint32_t newElementIndex = mKeyElementPool.size();
+ mKeyElementPool.emplace_back(key, element);
+
+ // Add new index into mKeyIndexList list.
+ mKeyIndexList.insert(iter, std::pair<std::uint32_t, std::uint32_t>(key, newElementIndex));
+
+ // Append element as child
+ return true;
+ }
+ else
+ {
+ // Else, duplicated key!
+ return false;
+ }
+ }
+
+ /**
+ * @brief Get element by the integer key.
+ *
+ * @param[in] key The integer key that this container will hold.
+ * @return If exist, iterator of container. Otherwise, return End().
+ */
+ iterator Get(const std::uint32_t& key) override
+ {
+ // Find key with binary search.
+ // We can do binary search cause mKeyIndexList is sorted.
+ const auto& iter = std::lower_bound(mKeyIndexList.cbegin(), mKeyIndexList.cend(), std::pair<std::uint32_t, std::uint32_t>(key, 0u));
+
+ if(iter == mKeyIndexList.cend() || iter->first != key)
+ {
+ // Key doesn't exist!
+ return this->End();
+ }
+
+ // We found it!
+ // iter->second will be the index of elements.
+ return this->Begin() + (iter->second);
+ }
+
+ /**
+ * @brief Get element by the integer key.
+ *
+ * @param[in] key The integer key that this container will hold.
+ * @return If exist, iterator of container. Otherwise, return End().
+ */
+ const_iterator Get(const std::uint32_t& key) const override
+ {
+ // Find key with binary search.
+ // We can do binary search cause mKeyIndexList is sorted.
+ const auto& iter = std::lower_bound(mKeyIndexList.cbegin(), mKeyIndexList.cend(), std::pair<std::uint32_t, std::uint32_t>(key, 0u));
+
+ if(iter == mKeyIndexList.cend() || iter->first != key)
+ {
+ // Key doesn't exist!
+ return this->End();
+ }
+
+ // We found it!
+ // iter->second will be the index of elements.
+ return this->Begin() + (iter->second);
+ }
+
+private:
+ /**
+ * @brief Convert from Key to index of container.
+ *
+ * @note mKeyIndexList's key should be increase order.
+ */
+ std::vector<std::pair<std::uint32_t, std::uint32_t>> mKeyIndexList{};
+
+protected:
+ /**
+ * @brief Member values from base class.
+ */
+ using IndexedMapBase<std::uint32_t, std::uint32_t, ElementType>::mKeyElementPool;
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INDEXED_INTEGER_MAP_H
--- /dev/null
+#ifndef DALI_INDEXED_MAP_BASE_H
+#define DALI_INDEXED_MAP_BASE_H
+
+/*
+ * Copyright (c) 2022 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 <algorithm>
+#include <string>
+#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+
+namespace Dali
+{
+namespace Internal
+{
+/**
+ * @brief Specific key-element container which can access by index.
+ * Register element by key. and Get element by key or index.
+ *
+ * This basical member API that indexed map container needs.
+ * Indexed map container can only Register and not allow Unregister in current implement spec.
+ *
+ * This container hold std::pair<KeyType, ElementType>.
+ * Iterator will iterate this pair container.
+ *
+ * For example,
+ * @code
+ * TrieContainerBase<KeyType, SearchKeyType, KeyIndexConverterType, ElementType> container;
+ * for(auto && elements : container)
+ * {
+ * elements.first == KeyType();
+ * elements.second == ElementType();
+ * }
+ * @endcode
+ *
+ * Contain elements in registered order.
+ * You can access that data by this order as 'index'
+ *
+ * For example,
+ * @code
+ * container.Register(10001, 111);
+ * container.Register(20002, 222);
+ * container[10001] == 111;
+ * container[20002] == 222;
+ * container.GetElementByIndex(0) == 111;
+ * container.GetKeyByIndex(0) == 10001;
+ * container.GetKeyElementPairByIndex(1) == KeyElementPairType(20002, 222);
+ * @endcode
+ *
+ * Get API return iterator of container.
+ *
+ * For example,
+ * @code
+ * container.Register(10001, 111);
+ * const auto& iter = container.Get(10001);
+ * iter->first == 10001;
+ * iter->second == 111;
+ * container.Get(30003) == container.End();
+ * @endcode
+ *
+ * @tparam KeyType The type of the key that the container holds.
+ * @tparam SearchKeyType The type of the key when the container register or get.
+ * @tparam ElementType The type of the data that the container holds.
+ */
+template<typename KeyType, typename SearchKeyType, typename ElementType>
+class IndexedMapBase
+{
+public:
+ /**
+ * @brief Type definitions.
+ */
+ using KeyElementPairType = std::pair<KeyType, ElementType>;
+ using iterator = typename std::vector<KeyElementPairType>::iterator;
+ using const_iterator = typename std::vector<KeyElementPairType>::const_iterator;
+
+public: // Virtual API
+ /**
+ * @brief Register element by the key.
+ *
+ * @param[in] key The key that this container will hold. Duplicated key doesn't allow.
+ * @param[in] element The element pairwise with key.
+ * @return True if Register success. Otherwise, return false.
+ */
+ virtual bool Register(const SearchKeyType& key, const ElementType& element) = 0;
+
+ /**
+ * @brief Get element by the key.
+ *
+ * @param[in] key The key that this container will hold.
+ * @return If exist, iterator of container. Otherwise, return End().
+ */
+ virtual iterator Get(const SearchKeyType& key) = 0;
+
+ /**
+ * @brief Get element by the key.
+ *
+ * @param[in] key The key that this container will hold.
+ * @return If exist, iterator of container. Otherwise, return End().
+ */
+ virtual const_iterator Get(const SearchKeyType& key) const = 0;
+
+public:
+ /**
+ * @brief Constructor.
+ */
+ IndexedMapBase()
+ {
+ Clear();
+ }
+
+ /**
+ * @brief Destructor.
+ */
+ virtual ~IndexedMapBase()
+ {
+ mKeyElementPool.clear();
+ }
+
+ /**
+ * @brief Clear this container.
+ */
+ virtual void Clear()
+ {
+ mKeyElementPool.clear();
+ }
+
+ /**
+ * @brief Get the number of elements that this container hold.
+ *
+ * @return The number of elements that this container hold.
+ */
+ std::size_t Count() const
+ {
+ return mKeyElementPool.size();
+ }
+
+ /**
+ * @brief Check whether container is empty or not.
+ *
+ * @return Whether elemnt is empty or not.
+ */
+ bool Empty() const
+ {
+ return mKeyElementPool.empty();
+ }
+
+ /**
+ * @brief Reserve KeyElementPool container size.
+ * Reserve only if current container size is smaller than input size.
+ *
+ * @param[in] size Reserve size.
+ */
+ void Reserve(const std::size_t& size)
+ {
+ if(mKeyElementPool.size() < size)
+ {
+ mKeyElementPool.reserve(size);
+ }
+ }
+
+ /**
+ * @brief Get Element by the key.
+ * @note Assert throw when try to use unregistered key.
+ *
+ * @param[in] key The key what we want to get.
+ * @return registered element.
+ */
+ const ElementType& operator[](const SearchKeyType& key) const
+ {
+ const_iterator iter = Get(key);
+ DALI_ASSERT_ALWAYS(iter != End() && "const operator[] doesn't allow non-exist key access");
+ return iter->second;
+ }
+
+ /**
+ * @brief Get Element by the key.
+ * @note Assert throw when try to use unregistered key.
+ *
+ * @param[in] key The key what we want to get.
+ * @return registered element.
+ */
+ ElementType& operator[](const SearchKeyType& key)
+ {
+ iterator iter = Get(key);
+ DALI_ASSERT_ALWAYS(iter != End() && "operator[] doesn't allow non-exist key access");
+ return iter->second;
+ }
+
+ /**
+ * @brief Get Element by the index.
+ *
+ * @param[in] index The index what we want to get.
+ * @return index'th registered element.
+ * @note mTrieKeyElementPool emplace_back the elements ordered by Register function called.
+ */
+ const ElementType& GetElementByIndex(const std::uint32_t& index) const
+ {
+ DALI_ASSERT_ALWAYS((index < mKeyElementPool.size()) && "operator[] index >= Count()");
+ return mKeyElementPool[index].second;
+ }
+
+ /**
+ * @brief Get Key by the index.
+ *
+ * @param[in] index The index what we want to get.
+ * @return index'th registered key.
+ * @note mTrieKeyElementPool emplace_back the elements ordered by Register function called.
+ */
+ const KeyType& GetKeyByIndex(const std::uint32_t& index) const
+ {
+ DALI_ASSERT_ALWAYS((index < mKeyElementPool.size()) && "operator[] index >= Count()");
+ return mKeyElementPool[index].first;
+ }
+
+ /**
+ * @brief Get Key and Element by the index.
+ *
+ * @param[in] index The index what we want to get.
+ * @return index'th registered key element pair.
+ * @note mTrieKeyElementPool emplace_back the elements ordered by Register function called.
+ */
+ const KeyElementPairType& GetKeyElementPairByIndex(const std::uint32_t& index) const
+ {
+ DALI_ASSERT_ALWAYS((index < mKeyElementPool.size()) && "operator[] index >= Count()");
+ return mKeyElementPool[index];
+ }
+
+ /**
+ * @brief Iterator to the beginning of the data.
+ * @return Iterator to the beginning of the data
+ */
+ iterator Begin()
+ {
+ return mKeyElementPool.begin();
+ }
+ /**
+ * @brief Const Iterator to the beginning of the data.
+ * @return Const Iterator to the beginning of the data
+ */
+ const_iterator CBegin() const
+ {
+ return mKeyElementPool.cbegin();
+ }
+ /**
+ * @brief Const Iterator to the beginning of the data.
+ * @return Const Iterator to the beginning of the data
+ */
+ const_iterator Begin() const
+ {
+ return mKeyElementPool.begin();
+ }
+
+ /**
+ * @brief Iterator to the end of the data (one past last element).
+ * @return Iterator to the end of the data (one past last element)
+ */
+ iterator End()
+ {
+ return mKeyElementPool.end();
+ }
+ /**
+ * @brief Const iterator to the end of the data (one past last element).
+ * @return Const iterator to the end of the data (one past last element)
+ */
+ const_iterator CEnd() const
+ {
+ return mKeyElementPool.cend();
+ }
+ /**
+ * @brief Const iterator to the end of the data (one past last element).
+ * @return Const iterator to the end of the data (one past last element)
+ */
+ const_iterator End() const
+ {
+ return mKeyElementPool.end();
+ }
+
+public: // API for C++11 std style functions.
+ /**
+ * Support for C++11 std style function call.
+ * @see Clear()
+ */
+ void clear()
+ {
+ Clear();
+ }
+
+ /**
+ * Support for C++11 std style function call.
+ *
+ * @return The number of elements that this container hold.
+ * @see Count()
+ */
+ std::size_t size() const
+ {
+ return Count();
+ }
+
+ /**
+ * Support for C++11 std style function call.
+ *
+ * @return Whether elemnt is empty or not.
+ * @see Empty()
+ */
+ bool empty() const
+ {
+ return Empty();
+ }
+
+ /**
+ * Support for C++11 std style function call.
+ *
+ * @param[in] size Reserve size.
+ * @see Reserve()
+ */
+ void reserve(const std::size_t size)
+ {
+ Reserve(size);
+ }
+
+ /**
+ * Support for C++11 Range-based for loop: for( item : container ).
+ * @return The start iterator
+ */
+ iterator begin()
+ {
+ return Begin();
+ }
+ /**
+ * Support for C++11 Range-based for loop: for( item : container ).
+ * @return The start const iterator
+ */
+ const_iterator cbegin() const
+ {
+ return CBegin();
+ }
+
+ /**
+ * Support for C++11 Range-based for loop: for( item : container ).
+ * @return The start const iterator
+ */
+ const_iterator begin() const
+ {
+ return Begin();
+ }
+
+ /**
+ * Support for C++11 Range-based for loop: for( item : container ).
+ * @return The end iterator
+ */
+ iterator end()
+ {
+ return End();
+ }
+
+ /**
+ * Support for C++11 Range-based for loop: for( item : container ).
+ * @return The end const iterator
+ */
+ const_iterator cend() const
+ {
+ return CEnd();
+ }
+
+ /**
+ * Support for C++11 Range-based for loop: for( item : container ).
+ * @return The end const iterator
+ */
+ const_iterator end() const
+ {
+ return End();
+ }
+
+protected:
+ std::vector<KeyElementPairType> mKeyElementPool;
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INDEXED_MAP_BASE_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
{
bool done = false;
- ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
-
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ auto iter = mActions.Get(ConstString(actionName));
+#else
+ ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
+#endif
if(iter != mActions.end())
{
done = (iter->second)(object, actionName, properties);
{
bool connected(false);
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ auto iter = mSignalConnectors.Get(ConstString(signalName));
+#else
ConnectorContainer::iterator iter = find_if(mSignalConnectors.begin(), mSignalConnectors.end(), PairFinder<std::string, ConnectionPair>(signalName));
-
+#endif
if(iter != mSignalConnectors.end())
{
connected = (iter->second)(object, connectionTracker, signalName, functor);
if(index < count)
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ name = std::string(mActions.GetKeyByIndex(index).GetStringView());
+#else
name = mActions[index].first;
+#endif
}
else
{
if(index < count)
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ name = std::string(mSignalConnectors.GetKeyByIndex(index).GetStringView());
+#else
name = mSignalConnectors[index].first;
+#endif
}
else
{
std::string_view TypeInfo::GetRegisteredPropertyName(Property::Index index) const
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredProperties.Get(static_cast<std::uint32_t>(index));
+#else
RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
+#endif
if(iter != mRegisteredProperties.end())
{
return iter->second.name.GetStringView();
}
else
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredProperties.Get(static_cast<std::uint32_t>(index));
+#else
RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
+#endif
if(iter != mRegisteredProperties.end())
{
return iter->second.name.GetStringView();
}
else
{
- ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ if(!mActions.Register(ConstString(actionName), function))
+ {
+ DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
+ }
+#else
+ ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
if(iter == mActions.end())
{
{
DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
}
+#endif
}
}
}
else
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ if(!mSignalConnectors.Register(ConstString(signalName), function))
+ {
+ DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str());
+ }
+#else
ConnectorContainer::iterator iter = find_if(mSignalConnectors.begin(), mSignalConnectors.end(), PairFinder<std::string, ConnectionPair>(signalName));
if(iter == mSignalConnectors.end())
{
DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str());
}
+#endif
}
}
}
else
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ if(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+ {
+ DALI_ASSERT_ALWAYS(!"Property index already added to Type");
+ }
+#else
RegisteredPropertyContainer::iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
if(iter == mRegisteredProperties.end())
{
mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
{
DALI_ASSERT_ALWAYS(!"Property index already added to Type");
}
+#endif
}
}
}
else
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ if(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+ {
+ DALI_ASSERT_ALWAYS(!"Property index already added to Type");
+ }
+#else
RegisteredPropertyContainer::iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
if(iter == mRegisteredProperties.end())
{
mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
{
DALI_ASSERT_ALWAYS(!"Property index already added to Type");
}
+#endif
}
}
void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Type type)
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ if(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+ {
+ DALI_ASSERT_ALWAYS(!"Property index already added to Type");
+ }
+#else
RegisteredPropertyContainer::iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
if(iter == mRegisteredProperties.end())
{
mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
{
DALI_ASSERT_ALWAYS(!"Property index already added to Type");
}
+#endif
}
void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Value defaultValue)
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ if(!mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(defaultValue.GetType(), ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+ {
+ DALI_ASSERT_ALWAYS(!"Property index already added to Type");
+ }
+ else
+ {
+ mPropertyDefaultValues.Register(static_cast<std::uint32_t>(index), std::move(defaultValue));
+ }
+#else
RegisteredPropertyContainer::iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
if(iter == mRegisteredProperties.end())
{
mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(defaultValue.GetType(), ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
{
DALI_ASSERT_ALWAYS(!"Property index already added to Type");
}
+#endif
}
void TypeInfo::AddAnimatablePropertyComponent(std::string name, Property::Index index, Property::Index baseIndex, uint32_t componentIndex)
bool success = false;
- RegisteredPropertyContainer::iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ if(mRegisteredProperties.Get(static_cast<std::uint32_t>(index)) == mRegisteredProperties.end())
+ {
+ const auto& iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PropertyComponentFinder<RegisteredPropertyPair>(baseIndex, componentIndex));
+ if(iter == mRegisteredProperties.end())
+ {
+ mRegisteredProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, ConstString(name), baseIndex, componentIndex));
+ success = true;
+ }
+ }
+#else
+ RegisteredPropertyContainer::iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
if(iter == mRegisteredProperties.end())
{
iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PropertyComponentFinder<RegisteredPropertyPair>(baseIndex, componentIndex));
success = true;
}
}
+#endif
DALI_ASSERT_ALWAYS(success && "Property component already registered");
}
void TypeInfo::AddChildProperty(std::string name, Property::Index index, Property::Type type)
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ if(!mRegisteredChildProperties.Register(static_cast<std::uint32_t>(index), RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)))
+#else
RegisteredPropertyContainer::iterator iter = find_if(mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
if(iter == mRegisteredChildProperties.end())
{
mRegisteredChildProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
}
else
+#endif
{
DALI_ASSERT_ALWAYS(!"Property index already added to Type");
}
{
Property::Index basePropertyIndex = Property::INVALID_INDEX;
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredProperties.Get(static_cast<std::uint32_t>(index));
+#else
RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
+#endif
if(iter != mRegisteredProperties.end())
{
basePropertyIndex = iter->second.basePropertyIndex;
{
int componentIndex = Property::INVALID_COMPONENT_INDEX;
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredProperties.Get(static_cast<std::uint32_t>(index));
+#else
RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
+#endif
if(iter != mRegisteredProperties.end())
{
componentIndex = iter->second.componentIndex;
std::string_view TypeInfo::GetChildPropertyName(Property::Index index) const
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredChildProperties.Get(static_cast<std::uint32_t>(index));
+#else
RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
+#endif
if(iter != mRegisteredChildProperties.end())
{
return iter->second.name.GetStringView();
{
Property::Type type(Property::NONE);
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredChildProperties.Get(static_cast<std::uint32_t>(index));
+#else
RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
+#endif
if(iter != mRegisteredChildProperties.end())
{
type = iter->second.type;
}
else
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredProperties.Get(static_cast<std::uint32_t>(index));
+#else
RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
+#endif
if(iter != mRegisteredProperties.end())
{
writable = iter->second.setFunc ? true : false;
}
else
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredProperties.Get(static_cast<std::uint32_t>(index));
+#else
RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
-
+#endif
if(iter != mRegisteredProperties.end())
{
if(iter->second.componentIndex == Property::INVALID_COMPONENT_INDEX)
Property::Value TypeInfo::GetPropertyDefaultValue(Property::Index index) const
{
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mPropertyDefaultValues.Get(static_cast<std::uint32_t>(index));
+#else
PropertyDefaultValueContainer::const_iterator iter = find_if(mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(), PairFinder<Property::Index, PropertyDefaultValuePair>(index));
+#endif
if(iter != mPropertyDefaultValues.end())
{
return iter->second;
void TypeInfo::SetProperty(BaseObject* object, Property::Index index, Property::Value value) const
{
- RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredProperties.Get(static_cast<std::uint32_t>(index));
+#else
+ RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
+#endif
if(iter != mRegisteredProperties.end())
{
if(iter->second.setFunc)
void TypeInfo::SetProperty(BaseObject* object, const std::string& name, Property::Value value) const
{
+ // Slow but should not be done that often
RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PropertyNameFinder<RegisteredPropertyPair>(ConstString(name)));
if(iter != mRegisteredProperties.end())
{
Property::Value TypeInfo::GetProperty(const BaseObject* object, Property::Index index) const
{
- RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ const auto& iter = mRegisteredProperties.Get(static_cast<std::uint32_t>(index));
+#else
+ RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder<Property::Index, RegisteredPropertyPair>(index));
+#endif
if(iter != mRegisteredProperties.end())
{
if(mCSharpType) // using csharp property get which returns a pointer to a Property::Value
#ifndef DALI_INTERNAL_TYPE_INFO_H
#define DALI_INTERNAL_TYPE_INFO_H
+#define USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO /// For safety. If some problem occured, just remove this define.
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <string>
// INTERNAL INCLUDES
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+#include <dali/internal/common/indexed-const-string-map.h>
+#include <dali/internal/common/indexed-integer-map.h>
+#endif
+
#include <dali/devel-api/object/csharp-type-info.h>
#include <dali/internal/common/const-string.h>
#include <dali/internal/event/object/default-property-metadata.h>
int32_t componentIndex = Property::INVALID_COMPONENT_INDEX;
};
- using ConnectionPair = std::pair<std::string, Dali::TypeInfo::SignalConnectorFunction>;
- using ActionPair = std::pair<std::string, Dali::TypeInfo::ActionFunction>;
- using RegisteredPropertyPair = std::pair<Property::Index, RegisteredProperty>;
- using PropertyDefaultValuePair = std::pair<Property::Index, Property::Value>;
-
+ using ActionPair = std::pair<std::string, Dali::TypeInfo::ActionFunction>;
+ using ConnectionPair = std::pair<std::string, Dali::TypeInfo::SignalConnectorFunction>;
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ using RegisteredPropertyPair = std::pair<std::uint32_t, RegisteredProperty>;
+ using PropertyDefaultValuePair = std::pair<std::uint32_t, Property::Value>;
+#else
+ using RegisteredPropertyPair = std::pair<Property::Index, RegisteredProperty>;
+ using PropertyDefaultValuePair = std::pair<Property::Index, Property::Value>;
+#endif
+
+#ifdef USE_INDEXED_MAP_CONTAINER_AT_TYPE_INFO
+ using ActionContainer = Dali::Internal::IndexedConstStringMap<Dali::TypeInfo::ActionFunction>;
+ using ConnectorContainer = Dali::Internal::IndexedConstStringMap<Dali::TypeInfo::SignalConnectorFunction>;
+ using RegisteredPropertyContainer = Dali::Internal::IndexedIntegerMap<RegisteredProperty>;
+ using PropertyDefaultValueContainer = Dali::Internal::IndexedIntegerMap<Property::Value>;
+#else
using ActionContainer = std::vector<ActionPair>;
using ConnectorContainer = std::vector<ConnectionPair>;
using RegisteredPropertyContainer = std::vector<RegisteredPropertyPair>;
using PropertyDefaultValueContainer = std::vector<PropertyDefaultValuePair>;
+#endif
/**
* Append properties from registeredProperties onto indices.
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
TypeRegistry::TypeInfoPointer TypeRegistry::GetTypeInfo(const std::string& uniqueTypeName)
{
- for(auto&& iter : mRegistryLut)
+ auto iter = mRegistryLut.Get(ConstString(uniqueTypeName));
+ if(iter != mRegistryLut.end())
{
- // Note! mRegistryLut contains Dali::TypeInfo handles, so cannot call GetTypeName()
- // as it calls us back resulting in infinite loop (GetTypeName is in BaseHandle part)
- if(iter->GetName() == uniqueTypeName)
- {
- return iter;
- }
+ return iter->second;
}
+
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", uniqueTypeName.c_str());
return TypeRegistry::TypeInfoPointer();
if(index < mRegistryLut.size())
{
- return mRegistryLut[index]->GetName();
+ return mRegistryLut.GetElementByIndex(index)->GetName();
}
return EMPTY_STRING;
{
std::string baseTypeName = DemangleClassName(baseTypeInfo.name());
- // check for duplicates using uniqueTypeName
- for(auto&& iter : mRegistryLut)
+ if(!mRegistryLut.Register(ConstString(uniqueTypeName), new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance, defaultProperties, defaultPropertyCount)))
{
- if(iter->GetName() == uniqueTypeName)
- {
- DALI_LOG_WARNING("Duplicate name in TypeRegistry for '%s'\n", +uniqueTypeName.c_str());
- DALI_ASSERT_ALWAYS(!"Duplicate type name in Type Registration");
- return uniqueTypeName; // never actually happening due to the assert
- }
+ DALI_LOG_WARNING("Duplicate name in TypeRegistry for '%s'\n", +uniqueTypeName.c_str());
+ DALI_ASSERT_ALWAYS(!"Duplicate type name in Type Registration");
+ return uniqueTypeName; // never actually happening due to the assert
}
-
- mRegistryLut.push_back(TypeRegistry::TypeInfoPointer(
- new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance, defaultProperties, defaultPropertyCount)));
DALI_LOG_INFO(gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str());
if(callCreateOnInit)
{
std::string baseTypeName = DemangleClassName(baseTypeInfo.name());
- // check for duplicates using uniqueTypeName
- for(auto&& iter : mRegistryLut)
+ if(!mRegistryLut.Register(ConstString(uniqueTypeName), TypeRegistry::TypeInfoPointer(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance))))
{
- if(iter->GetName() == uniqueTypeName)
- {
- DALI_LOG_WARNING("Duplicate name in TypeRegistry for '%s'\n", +uniqueTypeName.c_str());
- DALI_ASSERT_ALWAYS(!"Duplicate type name in Type Registration");
- return; // never actually happening due to the assert
- }
+ DALI_LOG_WARNING("Duplicate name in TypeRegistry for '%s'\n", +uniqueTypeName.c_str());
+ DALI_ASSERT_ALWAYS(!"Duplicate type name in Type Registration");
+ return; // never actually happening due to the assert
}
-
- mRegistryLut.push_back(TypeRegistry::TypeInfoPointer(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance)));
DALI_LOG_INFO(gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str());
}
void TypeRegistry::RegisterSignal(TypeRegistration& typeRegistration, std::string name, Dali::TypeInfo::SignalConnectorFunction func)
{
- for(auto&& iter : mRegistryLut)
+ auto iter = mRegistryLut.Get(ConstString(typeRegistration.RegisteredName()));
+ if(iter != mRegistryLut.end())
{
- if(iter->GetName() == typeRegistration.RegisteredName())
- {
- iter->AddConnectorFunction(std::move(name), func);
- break;
- }
+ iter->second->AddConnectorFunction(std::move(name), func);
}
}
bool TypeRegistry::RegisterAction(TypeRegistration& typeRegistration, std::string name, Dali::TypeInfo::ActionFunction f)
{
- for(auto&& iter : mRegistryLut)
+ auto iter = mRegistryLut.Get(ConstString(typeRegistration.RegisteredName()));
+ if(iter != mRegistryLut.end())
{
- if(iter->GetName() == typeRegistration.RegisteredName())
- {
- iter->AddActionFunction(std::move(name), f);
- return true;
- }
+ iter->second->AddActionFunction(std::move(name), f);
+ return true;
}
return false;
}
bool TypeRegistry::RegisterProperty(TypeRegistration& typeRegistration, std::string name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc)
{
- for(auto&& iter : mRegistryLut)
+ auto iter = mRegistryLut.Get(ConstString(typeRegistration.RegisteredName()));
+ if(iter != mRegistryLut.end())
{
- if(iter->GetName() == typeRegistration.RegisteredName())
- {
- iter->AddProperty(std::move(name), index, type, setFunc, getFunc);
- return true;
- }
+ iter->second->AddProperty(std::move(name), index, type, setFunc, getFunc);
+ return true;
}
-
return false;
}
bool TypeRegistry::RegisterProperty(const std::string& objectName, std::string name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc)
{
- for(auto&& iter : mRegistryLut)
+ auto iter = mRegistryLut.Get(ConstString(objectName));
+ if(iter != mRegistryLut.end())
{
- if(iter->GetName() == objectName)
- {
- iter->AddProperty(std::move(name), index, type, setFunc, getFunc);
- return true;
- }
+ iter->second->AddProperty(std::move(name), index, type, setFunc, getFunc);
+ return true;
}
return false;
bool TypeRegistry::RegisterAnimatableProperty(TypeRegistration& typeRegistration, std::string name, Property::Index index, Property::Type type)
{
- for(auto&& iter : mRegistryLut)
+ auto iter = mRegistryLut.Get(ConstString(typeRegistration.RegisteredName()));
+ if(iter != mRegistryLut.end())
{
- if(iter->GetName() == typeRegistration.RegisteredName())
- {
- iter->AddAnimatableProperty(std::move(name), index, type);
- return true;
- }
+ iter->second->AddAnimatableProperty(std::move(name), index, type);
+ return true;
}
return false;
bool TypeRegistry::RegisterAnimatableProperty(TypeRegistration& typeRegistration, std::string name, Property::Index index, Property::Value value)
{
- for(auto&& iter : mRegistryLut)
+ auto iter = mRegistryLut.Get(ConstString(typeRegistration.RegisteredName()));
+ if(iter != mRegistryLut.end())
{
- if(iter->GetName() == typeRegistration.RegisteredName())
- {
- iter->AddAnimatableProperty(std::move(name), index, std::move(value));
- return true;
- }
+ iter->second->AddAnimatableProperty(std::move(name), index, std::move(value));
+ return true;
}
return false;
bool TypeRegistry::RegisterAnimatablePropertyComponent(TypeRegistration& typeRegistration, std::string name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex)
{
- for(auto&& iter : mRegistryLut)
+ auto iter = mRegistryLut.Get(ConstString(typeRegistration.RegisteredName()));
+ if(iter != mRegistryLut.end())
{
- if(iter->GetName() == typeRegistration.RegisteredName())
- {
- iter->AddAnimatablePropertyComponent(std::move(name), index, baseIndex, componentIndex);
- return true;
- }
+ iter->second->AddAnimatablePropertyComponent(std::move(name), index, baseIndex, componentIndex);
+ return true;
}
return false;
bool TypeRegistry::RegisterChildProperty(const std::string& registeredType, std::string name, Property::Index index, Property::Type type)
{
- for(auto&& iter : mRegistryLut)
+ auto iter = mRegistryLut.Get(ConstString(registeredType));
+ if(iter != mRegistryLut.end())
{
- if(iter->GetName() == registeredType)
- {
- iter->AddChildProperty(std::move(name), index, type);
- return true;
- }
+ iter->second->AddChildProperty(std::move(name), index, type);
+ return true;
}
return false;
#define DALI_INTERNAL_TYPE_REGISTRY_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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/object/csharp-type-info.h>
+#include <dali/internal/common/indexed-const-string-map.h>
#include <dali/internal/event/common/type-info-impl.h>
#include <dali/internal/event/object/default-property-metadata.h>
#include <dali/public-api/object/base-handle.h>
/*
* Mapping from type name to TypeInfo
*/
- std::vector<TypeInfoPointer> mRegistryLut;
+ Dali::Internal::IndexedConstStringMap<TypeInfoPointer> mRegistryLut;
std::vector<Dali::TypeInfo::CreateFunction> mInitFunctions;