18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#include "object_registry.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <chrono> 198bf80f4bSopenharmony_ci 208bf80f4bSopenharmony_ci#include <base/containers/fixed_string.h> 218bf80f4bSopenharmony_ci#include <base/util/compile_time_hashes.h> 228bf80f4bSopenharmony_ci#include <base/util/uid_util.h> 238bf80f4bSopenharmony_ci 248bf80f4bSopenharmony_ci#include <meta/interface/animation/builtin_animations.h> 258bf80f4bSopenharmony_ci#include <meta/interface/intf_derived.h> 268bf80f4bSopenharmony_ci 278bf80f4bSopenharmony_ci#include "any.h" 288bf80f4bSopenharmony_ci#include "call_context.h" 298bf80f4bSopenharmony_ci#include "metadata.h" 308bf80f4bSopenharmony_ci#include "property/bind.h" 318bf80f4bSopenharmony_ci#include "property/stack_property.h" 328bf80f4bSopenharmony_ci#include "random.h" 338bf80f4bSopenharmony_ci 348bf80f4bSopenharmony_ci#define OBJ_REG_LOG(...) 358bf80f4bSopenharmony_ci 368bf80f4bSopenharmony_ci/* 378bf80f4bSopenharmony_ci Notes: 388bf80f4bSopenharmony_ci * Currently Unregistering object and creating it at the same time can cause the pointer ObjectTypeInfo still 398bf80f4bSopenharmony_ci be used after the Unregister function returns. 408bf80f4bSopenharmony_ci * Same issue applies to creating and unregistering property. 418bf80f4bSopenharmony_ci*/ 428bf80f4bSopenharmony_ci 438bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE() 448bf80f4bSopenharmony_ci 458bf80f4bSopenharmony_ciconst size_t DISPOSAL_THRESHOLD = 100; 468bf80f4bSopenharmony_ci 478bf80f4bSopenharmony_cistatic BASE_NS::Uid GenerateInstanceId(uint64_t random) 488bf80f4bSopenharmony_ci{ 498bf80f4bSopenharmony_ci // NOTE: instance uid:s are generated from 64 bit random number and 64 bit timestamp 508bf80f4bSopenharmony_ci auto elapsed = std::chrono::high_resolution_clock::now(); 518bf80f4bSopenharmony_ci auto high = std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed.time_since_epoch()).count(); 528bf80f4bSopenharmony_ci 538bf80f4bSopenharmony_ci BASE_NS::Uid uid; 548bf80f4bSopenharmony_ci uid.data[0] = high; 558bf80f4bSopenharmony_ci uid.data[1] = random; 568bf80f4bSopenharmony_ci return uid; 578bf80f4bSopenharmony_ci} 588bf80f4bSopenharmony_ci 598bf80f4bSopenharmony_ciObjectRegistry::ObjectRegistry() : random_(CreateXoroshiro128(BASE_NS::FNV1aHash("ToolKitObjectRegistry"))) {} 608bf80f4bSopenharmony_ci 618bf80f4bSopenharmony_ciObjectRegistry::~ObjectRegistry() 628bf80f4bSopenharmony_ci{ 638bf80f4bSopenharmony_ci queues_.clear(); 648bf80f4bSopenharmony_ci defaultContext_.reset(); 658bf80f4bSopenharmony_ci classRegistry_.Clear(); 668bf80f4bSopenharmony_ci // Just for sanity. 678bf80f4bSopenharmony_ci GC(); 688bf80f4bSopenharmony_ci // And to make sure all "objects" are unregistered. (we have some that never un-register) 698bf80f4bSopenharmony_ci // doing it one at a time, because unregister will modify the list.. 708bf80f4bSopenharmony_ci bool first = true; 718bf80f4bSopenharmony_ci auto& pluginRegistry = CORE_NS::GetPluginRegister(); 728bf80f4bSopenharmony_ci for (;;) { 738bf80f4bSopenharmony_ci const auto& types = pluginRegistry.GetTypeInfos(ObjectTypeInfo::UID); 748bf80f4bSopenharmony_ci if (types.empty()) { 758bf80f4bSopenharmony_ci break; 768bf80f4bSopenharmony_ci } 778bf80f4bSopenharmony_ci auto object = static_cast<const ObjectTypeInfo* const>(types[0]); 788bf80f4bSopenharmony_ci if (first) { 798bf80f4bSopenharmony_ci CORE_LOG_F("Object classes not unregistered before object registry death. (force unregister)"); 808bf80f4bSopenharmony_ci first = false; 818bf80f4bSopenharmony_ci } 828bf80f4bSopenharmony_ci auto& classInfo = object->GetFactory()->GetClassInfo(); 838bf80f4bSopenharmony_ci CORE_LOG_F( 848bf80f4bSopenharmony_ci "Name: [%s] ClassId [%s]", BASE_NS::string(classInfo.Name()).c_str(), classInfo.Id().ToString().c_str()); 858bf80f4bSopenharmony_ci pluginRegistry.UnregisterTypeInfo(*types[0]); 868bf80f4bSopenharmony_ci } 878bf80f4bSopenharmony_ci} 888bf80f4bSopenharmony_ci 898bf80f4bSopenharmony_ciIClassRegistry& ObjectRegistry::GetClassRegistry() 908bf80f4bSopenharmony_ci{ 918bf80f4bSopenharmony_ci return classRegistry_; 928bf80f4bSopenharmony_ci} 938bf80f4bSopenharmony_ci 948bf80f4bSopenharmony_cistatic void RegisterToPluginRegistry(const ObjectTypeInfo& info) 958bf80f4bSopenharmony_ci{ 968bf80f4bSopenharmony_ci auto& pluginRegistry = CORE_NS::GetPluginRegister(); 978bf80f4bSopenharmony_ci const auto& types = pluginRegistry.GetTypeInfos(ObjectTypeInfo::UID); 988bf80f4bSopenharmony_ci for (auto it = types.begin(); it != types.end(); it++) { 998bf80f4bSopenharmony_ci auto object = static_cast<const ObjectTypeInfo* const>(*it); 1008bf80f4bSopenharmony_ci if (*object == info) { 1018bf80f4bSopenharmony_ci return; 1028bf80f4bSopenharmony_ci } 1038bf80f4bSopenharmony_ci } 1048bf80f4bSopenharmony_ci pluginRegistry.RegisterTypeInfo(info); 1058bf80f4bSopenharmony_ci} 1068bf80f4bSopenharmony_ci 1078bf80f4bSopenharmony_cistatic void UnregisterFromPluginRegistry(const BASE_NS::Uid& uid) 1088bf80f4bSopenharmony_ci{ 1098bf80f4bSopenharmony_ci auto& pluginRegistry = CORE_NS::GetPluginRegister(); 1108bf80f4bSopenharmony_ci const auto& types = pluginRegistry.GetTypeInfos(ObjectTypeInfo::UID); 1118bf80f4bSopenharmony_ci for (auto it = types.begin(); it != types.end(); it++) { 1128bf80f4bSopenharmony_ci auto object = static_cast<const ObjectTypeInfo* const>(*it); 1138bf80f4bSopenharmony_ci if (object->GetFactory()->GetClassInfo().Id() == ObjectId(uid)) { 1148bf80f4bSopenharmony_ci pluginRegistry.UnregisterTypeInfo(**it); 1158bf80f4bSopenharmony_ci break; 1168bf80f4bSopenharmony_ci } 1178bf80f4bSopenharmony_ci } 1188bf80f4bSopenharmony_ci} 1198bf80f4bSopenharmony_ci 1208bf80f4bSopenharmony_cibool ObjectRegistry::RegisterObjectType(const IClassInfo::Ptr& classInfo) 1218bf80f4bSopenharmony_ci{ 1228bf80f4bSopenharmony_ci if (!classInfo) { 1238bf80f4bSopenharmony_ci return false; 1248bf80f4bSopenharmony_ci } 1258bf80f4bSopenharmony_ci const auto factory = interface_pointer_cast<IObjectFactory>(classInfo); 1268bf80f4bSopenharmony_ci if (!factory) { 1278bf80f4bSopenharmony_ci CORE_LOG_E("ObjectRegistry: The class (%s) being registered does not provide object factory", 1288bf80f4bSopenharmony_ci classInfo->GetClassInfo().Name().data()); 1298bf80f4bSopenharmony_ci } 1308bf80f4bSopenharmony_ci if (!classRegistry_.Register(factory)) { 1318bf80f4bSopenharmony_ci return false; 1328bf80f4bSopenharmony_ci } 1338bf80f4bSopenharmony_ci 1348bf80f4bSopenharmony_ci // Construct dummy object of that type to get the static metadata initialised 1358bf80f4bSopenharmony_ci BASE_NS::vector<IObject::Ptr> classes; 1368bf80f4bSopenharmony_ci auto res = CreateInternal(factory->GetClassInfo().Id().ToUid(), classes); 1378bf80f4bSopenharmony_ci if (res.successful && !classes.empty()) { 1388bf80f4bSopenharmony_ci // for now we need to set the super classes to safely destroy some objects, using dummy instance id 1398bf80f4bSopenharmony_ci SetObjectInstanceIds(classes, BASE_NS::Uid {}); 1408bf80f4bSopenharmony_ci } else { 1418bf80f4bSopenharmony_ci CORE_LOG_W("Failed to create object when generating static metadata [uid=%s]", 1428bf80f4bSopenharmony_ci BASE_NS::to_string(factory->GetClassInfo().Id().ToUid()).c_str()); 1438bf80f4bSopenharmony_ci } 1448bf80f4bSopenharmony_ci return true; 1458bf80f4bSopenharmony_ci} 1468bf80f4bSopenharmony_ci 1478bf80f4bSopenharmony_cibool ObjectRegistry::UnregisterObjectType(const IClassInfo::Ptr& classInfo) 1488bf80f4bSopenharmony_ci{ 1498bf80f4bSopenharmony_ci if (const auto factory = interface_pointer_cast<IObjectFactory>(classInfo)) { 1508bf80f4bSopenharmony_ci return classRegistry_.Unregister(factory); 1518bf80f4bSopenharmony_ci } 1528bf80f4bSopenharmony_ci return false; 1538bf80f4bSopenharmony_ci} 1548bf80f4bSopenharmony_ci 1558bf80f4bSopenharmony_ciBASE_NS::string ObjectRegistry::GetClassName(BASE_NS::Uid uid) const 1568bf80f4bSopenharmony_ci{ 1578bf80f4bSopenharmony_ci return classRegistry_.GetClassName(uid); 1588bf80f4bSopenharmony_ci} 1598bf80f4bSopenharmony_ci 1608bf80f4bSopenharmony_ciObjectRegistry::CreateResult ObjectRegistry::CreateInternal( 1618bf80f4bSopenharmony_ci BASE_NS::Uid uid, BASE_NS::vector<IObject::Ptr>& classes) const 1628bf80f4bSopenharmony_ci{ 1638bf80f4bSopenharmony_ci IObject::Ptr obj; 1648bf80f4bSopenharmony_ci ClassInfo info; 1658bf80f4bSopenharmony_ci if (auto fac = classRegistry_.GetObjectFactory(uid)) { 1668bf80f4bSopenharmony_ci obj = fac->CreateInstance(); 1678bf80f4bSopenharmony_ci if (obj) { 1688bf80f4bSopenharmony_ci info = fac->GetClassInfo(); 1698bf80f4bSopenharmony_ci return CreateResult { ConstructObjectInternal(obj, classes), info.category, info.IsSingleton() }; 1708bf80f4bSopenharmony_ci } 1718bf80f4bSopenharmony_ci } 1728bf80f4bSopenharmony_ci return { false, 0, false }; 1738bf80f4bSopenharmony_ci} 1748bf80f4bSopenharmony_ci 1758bf80f4bSopenharmony_cibool ObjectRegistry::ConstructObjectInternal(const IObject::Ptr& obj, BASE_NS::vector<IObject::Ptr>& classes) const 1768bf80f4bSopenharmony_ci{ 1778bf80f4bSopenharmony_ci classes.push_back(obj); 1788bf80f4bSopenharmony_ci if (auto agr = obj->GetInterface<IDerived>()) { 1798bf80f4bSopenharmony_ci auto superUid = agr->GetSuperClassUid(); 1808bf80f4bSopenharmony_ci if (superUid != BASE_NS::Uid {}) { 1818bf80f4bSopenharmony_ci OBJ_REG_LOG("\tCreate super of %s", GetClassName(superUid).c_str()); 1828bf80f4bSopenharmony_ci auto super = CreateInternal(superUid, classes); 1838bf80f4bSopenharmony_ci if (!super.successful) { 1848bf80f4bSopenharmony_ci // failed to create super class. 1858bf80f4bSopenharmony_ci CORE_LOG_F("Could not create the super class [uid=%s]", BASE_NS::to_string(superUid).c_str()); 1868bf80f4bSopenharmony_ci return false; 1878bf80f4bSopenharmony_ci } 1888bf80f4bSopenharmony_ci } 1898bf80f4bSopenharmony_ci } 1908bf80f4bSopenharmony_ci return true; 1918bf80f4bSopenharmony_ci} 1928bf80f4bSopenharmony_ci 1938bf80f4bSopenharmony_civoid ObjectRegistry::SetObjectInstanceIds(const BASE_NS::vector<IObject::Ptr>& classes, InstanceId instid) const 1948bf80f4bSopenharmony_ci{ 1958bf80f4bSopenharmony_ci IObject::Ptr obj = classes.front(); 1968bf80f4bSopenharmony_ci IObject::Ptr base; 1978bf80f4bSopenharmony_ci 1988bf80f4bSopenharmony_ci // Prepare object hierarchy for building by setting instance ids and super objects 1998bf80f4bSopenharmony_ci for (auto it = classes.rbegin(); it != classes.rend(); ++it) { 2008bf80f4bSopenharmony_ci if (auto o = (*it)->GetInterface<ILifecycle>()) { 2018bf80f4bSopenharmony_ci o->SetInstanceId(instid); 2028bf80f4bSopenharmony_ci } 2038bf80f4bSopenharmony_ci if (auto der = (*it)->GetInterface<IDerived>()) { 2048bf80f4bSopenharmony_ci if (base) { 2058bf80f4bSopenharmony_ci OBJ_REG_LOG("\tAssigning instance of %s as super to %s", BASE_NS::string(base->GetClassName()).c_str(), 2068bf80f4bSopenharmony_ci BASE_NS::string((*it)->GetClassName()).c_str()); 2078bf80f4bSopenharmony_ci } 2088bf80f4bSopenharmony_ci der->SetSuperInstance(obj, base); 2098bf80f4bSopenharmony_ci } 2108bf80f4bSopenharmony_ci base = *it; 2118bf80f4bSopenharmony_ci } 2128bf80f4bSopenharmony_ci} 2138bf80f4bSopenharmony_ci 2148bf80f4bSopenharmony_cibool ObjectRegistry::BuildObject(const BASE_NS::vector<IObject::Ptr>& classes, const IMetadata::Ptr& data) const 2158bf80f4bSopenharmony_ci{ 2168bf80f4bSopenharmony_ci if (classes.empty()) { 2178bf80f4bSopenharmony_ci return false; 2188bf80f4bSopenharmony_ci } 2198bf80f4bSopenharmony_ci IObject::Ptr obj = classes.front(); 2208bf80f4bSopenharmony_ci IMetadata::Ptr meta = ConstructMetadata(); 2218bf80f4bSopenharmony_ci 2228bf80f4bSopenharmony_ci // Set metadata first so that one can use IMetadata via GetSelf in the non-top classes' Build 2238bf80f4bSopenharmony_ci for (auto it = classes.rbegin(); it != classes.rend(); ++it) { 2248bf80f4bSopenharmony_ci if (auto i = (*it)->GetInterface<IMetadataInternal>()) { 2258bf80f4bSopenharmony_ci i->SetMetadata(meta); 2268bf80f4bSopenharmony_ci } 2278bf80f4bSopenharmony_ci } 2288bf80f4bSopenharmony_ci // call build for the object hierarchy 2298bf80f4bSopenharmony_ci for (auto it = classes.rbegin(); it != classes.rend(); ++it) { 2308bf80f4bSopenharmony_ci if (auto ctor = (*it)->GetInterface<ILifecycle>()) { 2318bf80f4bSopenharmony_ci OBJ_REG_LOG("\tBuilding %s", BASE_NS::string((*it)->GetClassName()).c_str()); 2328bf80f4bSopenharmony_ci if (!ctor->Build(data)) { 2338bf80f4bSopenharmony_ci return false; 2348bf80f4bSopenharmony_ci } 2358bf80f4bSopenharmony_ci } 2368bf80f4bSopenharmony_ci } 2378bf80f4bSopenharmony_ci return true; 2388bf80f4bSopenharmony_ci} 2398bf80f4bSopenharmony_ci 2408bf80f4bSopenharmony_ciIObject::Ptr ObjectRegistry::Create(ObjectId uid, const CreateInfo& createInfo, const IMetadata::Ptr& data) const 2418bf80f4bSopenharmony_ci{ 2428bf80f4bSopenharmony_ci CheckGC(); 2438bf80f4bSopenharmony_ci 2448bf80f4bSopenharmony_ci auto instid = createInfo.instanceId; 2458bf80f4bSopenharmony_ci 2468bf80f4bSopenharmony_ci if (instid == BASE_NS::Uid {}) { 2478bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 2488bf80f4bSopenharmony_ci if (auto so = FindSingleton(uid.ToUid())) { 2498bf80f4bSopenharmony_ci return so; 2508bf80f4bSopenharmony_ci } 2518bf80f4bSopenharmony_ci instid = GenerateInstanceId(random_->GetRandom()); 2528bf80f4bSopenharmony_ci } else { 2538bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 2548bf80f4bSopenharmony_ci if (auto so = FindSingleton(uid.ToUid())) { 2558bf80f4bSopenharmony_ci return so; 2568bf80f4bSopenharmony_ci } 2578bf80f4bSopenharmony_ci // make sure that an object with specified instanceid does not exist already. 2588bf80f4bSopenharmony_ci auto it = instancesByUid_.find(instid); 2598bf80f4bSopenharmony_ci if (it != instancesByUid_.end() && !it->second.ptr.expired()) { 2608bf80f4bSopenharmony_ci CORE_LOG_F("Object with instance id %s already exists.", instid.ToString().c_str()); 2618bf80f4bSopenharmony_ci return {}; 2628bf80f4bSopenharmony_ci } 2638bf80f4bSopenharmony_ci } 2648bf80f4bSopenharmony_ci OBJ_REG_LOG("Create instance of %s {instance id %s}", GetClassName(uid).c_str(), instid.ToString().c_str()); 2658bf80f4bSopenharmony_ci BASE_NS::vector<IObject::Ptr> classes; 2668bf80f4bSopenharmony_ci auto t = CreateInternal(uid.ToUid(), classes); 2678bf80f4bSopenharmony_ci if (t.successful && !classes.empty()) { 2688bf80f4bSopenharmony_ci if (PostCreate(uid.ToUid(), instid.ToUid(), t, createInfo, classes, data)) { 2698bf80f4bSopenharmony_ci return classes.front(); 2708bf80f4bSopenharmony_ci } 2718bf80f4bSopenharmony_ci } 2728bf80f4bSopenharmony_ci 2738bf80f4bSopenharmony_ci CORE_LOG_F("Could not create instance of %s", GetClassName(uid.ToUid()).c_str()); 2748bf80f4bSopenharmony_ci return nullptr; 2758bf80f4bSopenharmony_ci} 2768bf80f4bSopenharmony_ci 2778bf80f4bSopenharmony_cibool ObjectRegistry::PostCreate(const BASE_NS::Uid& uid, InstanceId instid, const CreateResult& t, 2788bf80f4bSopenharmony_ci const CreateInfo& createInfo, const BASE_NS::vector<IObject::Ptr>& classes, const IMetadata::Ptr& data) const 2798bf80f4bSopenharmony_ci{ 2808bf80f4bSopenharmony_ci SetObjectInstanceIds(classes, instid); 2818bf80f4bSopenharmony_ci 2828bf80f4bSopenharmony_ci if (!BuildObject(classes, data)) { 2838bf80f4bSopenharmony_ci CORE_LOG_F("Failed to build object (%s).", GetClassName(uid).c_str()); 2848bf80f4bSopenharmony_ci return false; 2858bf80f4bSopenharmony_ci } 2868bf80f4bSopenharmony_ci 2878bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 2888bf80f4bSopenharmony_ci auto& i = instancesByUid_[instid]; 2898bf80f4bSopenharmony_ci if (!i.ptr.expired()) { 2908bf80f4bSopenharmony_ci // seems someone beat us to it 2918bf80f4bSopenharmony_ci CORE_LOG_F("Object with instance id %s already exists.", instid.ToString().c_str()); 2928bf80f4bSopenharmony_ci return false; 2938bf80f4bSopenharmony_ci } 2948bf80f4bSopenharmony_ci i = ObjectInstance { classes.front(), t.category }; 2958bf80f4bSopenharmony_ci 2968bf80f4bSopenharmony_ci if (t.singleton) { 2978bf80f4bSopenharmony_ci singletons_[uid] = classes.front(); // Store singleton weakref 2988bf80f4bSopenharmony_ci } 2998bf80f4bSopenharmony_ci if (createInfo.isGloballyAvailable) { 3008bf80f4bSopenharmony_ci CORE_LOG_D("Registering global object: %s [%s]", GetClassName(uid).c_str(), instid.ToString().c_str()); 3018bf80f4bSopenharmony_ci globalObjects_[instid] = classes.front(); 3028bf80f4bSopenharmony_ci } 3038bf80f4bSopenharmony_ci return true; 3048bf80f4bSopenharmony_ci} 3058bf80f4bSopenharmony_ci 3068bf80f4bSopenharmony_ciIObject::Ptr ObjectRegistry::Create(ObjectId uid, const CreateInfo& createInfo) const 3078bf80f4bSopenharmony_ci{ 3088bf80f4bSopenharmony_ci return Create(uid, createInfo, nullptr); 3098bf80f4bSopenharmony_ci} 3108bf80f4bSopenharmony_ci 3118bf80f4bSopenharmony_ciIObject::Ptr ObjectRegistry::Create(const META_NS::ClassInfo& info, const CreateInfo& createInfo) const 3128bf80f4bSopenharmony_ci{ 3138bf80f4bSopenharmony_ci return Create(info.Id(), createInfo); 3148bf80f4bSopenharmony_ci} 3158bf80f4bSopenharmony_ci 3168bf80f4bSopenharmony_ciBASE_NS::vector<ObjectCategoryItem> ObjectRegistry::GetAllCategories() const 3178bf80f4bSopenharmony_ci{ 3188bf80f4bSopenharmony_ci static const BASE_NS::vector<ObjectCategoryItem> items = { { ObjectCategoryBits::WIDGET, "Widgets" }, 3198bf80f4bSopenharmony_ci { ObjectCategoryBits::ANIMATION, "Animations" }, { ObjectCategoryBits::LAYOUT, "Layouts" }, 3208bf80f4bSopenharmony_ci { ObjectCategoryBits::CURVE, "Curves" }, { ObjectCategoryBits::SHAPE, "Shapes" }, 3218bf80f4bSopenharmony_ci { ObjectCategoryBits::CONTAINER, "Containers" }, { ObjectCategoryBits::INTERNAL, "Internals" }, 3228bf80f4bSopenharmony_ci { ObjectCategoryBits::APPLICATION, "Application specifics" }, 3238bf80f4bSopenharmony_ci { ObjectCategoryBits::ANIMATION_MODIFIER, "Animation modifier" }, 3248bf80f4bSopenharmony_ci { ObjectCategoryBits::NO_CATEGORY, "Not categorized" } }; 3258bf80f4bSopenharmony_ci return items; 3268bf80f4bSopenharmony_ci} 3278bf80f4bSopenharmony_ci 3288bf80f4bSopenharmony_ciIObjectFactory::ConstPtr ObjectRegistry::GetObjectFactory(const ObjectId& uid) const 3298bf80f4bSopenharmony_ci{ 3308bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 3318bf80f4bSopenharmony_ci return classRegistry_.GetObjectFactory(uid.ToUid()); 3328bf80f4bSopenharmony_ci} 3338bf80f4bSopenharmony_ci 3348bf80f4bSopenharmony_ciBASE_NS::vector<IClassInfo::ConstPtr> ObjectRegistry::GetAllTypes( 3358bf80f4bSopenharmony_ci ObjectCategoryBits category, bool strict, bool excludeDeprecated) const 3368bf80f4bSopenharmony_ci{ 3378bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 3388bf80f4bSopenharmony_ci return classRegistry_.GetAllTypes(category, strict, excludeDeprecated); 3398bf80f4bSopenharmony_ci} 3408bf80f4bSopenharmony_ci 3418bf80f4bSopenharmony_civoid ObjectRegistry::CheckGC() const 3428bf80f4bSopenharmony_ci{ 3438bf80f4bSopenharmony_ci if (purgeCounter_ > DISPOSAL_THRESHOLD && disposalInProgress_.test_and_set()) { 3448bf80f4bSopenharmony_ci { 3458bf80f4bSopenharmony_ci std::unique_lock lock { disposalMutex_ }; 3468bf80f4bSopenharmony_ci disposalsStorage_.swap(disposals_); 3478bf80f4bSopenharmony_ci purgeCounter_ = 0; 3488bf80f4bSopenharmony_ci } 3498bf80f4bSopenharmony_ci DoDisposal(disposalsStorage_); 3508bf80f4bSopenharmony_ci disposalsStorage_.clear(); 3518bf80f4bSopenharmony_ci disposalInProgress_.clear(); 3528bf80f4bSopenharmony_ci } 3538bf80f4bSopenharmony_ci} 3548bf80f4bSopenharmony_ci 3558bf80f4bSopenharmony_civoid ObjectRegistry::GC() const 3568bf80f4bSopenharmony_ci{ 3578bf80f4bSopenharmony_ci for (auto it = instancesByUid_.begin(); it != instancesByUid_.end();) { 3588bf80f4bSopenharmony_ci if (it->second.ptr.expired()) { 3598bf80f4bSopenharmony_ci it = instancesByUid_.erase(it); 3608bf80f4bSopenharmony_ci } else { 3618bf80f4bSopenharmony_ci ++it; 3628bf80f4bSopenharmony_ci } 3638bf80f4bSopenharmony_ci } 3648bf80f4bSopenharmony_ci for (auto it = singletons_.begin(); it != singletons_.end();) { 3658bf80f4bSopenharmony_ci if (it->second.expired()) { 3668bf80f4bSopenharmony_ci it = singletons_.erase(it); 3678bf80f4bSopenharmony_ci } else { 3688bf80f4bSopenharmony_ci ++it; 3698bf80f4bSopenharmony_ci } 3708bf80f4bSopenharmony_ci } 3718bf80f4bSopenharmony_ci for (auto it = globalObjects_.begin(); it != globalObjects_.end();) { 3728bf80f4bSopenharmony_ci if (it->second.expired()) { 3738bf80f4bSopenharmony_ci it = globalObjects_.erase(it); 3748bf80f4bSopenharmony_ci } else { 3758bf80f4bSopenharmony_ci ++it; 3768bf80f4bSopenharmony_ci } 3778bf80f4bSopenharmony_ci } 3788bf80f4bSopenharmony_ci} 3798bf80f4bSopenharmony_ci 3808bf80f4bSopenharmony_civoid ObjectRegistry::Purge() 3818bf80f4bSopenharmony_ci{ 3828bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 3838bf80f4bSopenharmony_ci GC(); 3848bf80f4bSopenharmony_ci} 3858bf80f4bSopenharmony_ci 3868bf80f4bSopenharmony_civoid ObjectRegistry::DoDisposal(const BASE_NS::vector<InstanceId>& uids) const 3878bf80f4bSopenharmony_ci{ 3888bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 3898bf80f4bSopenharmony_ci for (auto&& v : uids) { 3908bf80f4bSopenharmony_ci auto it = instancesByUid_.find(v); 3918bf80f4bSopenharmony_ci if (it != instancesByUid_.end()) { 3928bf80f4bSopenharmony_ci instancesByUid_.erase(it); 3938bf80f4bSopenharmony_ci auto it = singletons_.find(v); 3948bf80f4bSopenharmony_ci if (it != singletons_.end()) { 3958bf80f4bSopenharmony_ci singletons_.erase(it); 3968bf80f4bSopenharmony_ci } 3978bf80f4bSopenharmony_ci } 3988bf80f4bSopenharmony_ci } 3998bf80f4bSopenharmony_ci} 4008bf80f4bSopenharmony_ci 4018bf80f4bSopenharmony_civoid ObjectRegistry::DisposeObject(const InstanceId& uid) const 4028bf80f4bSopenharmony_ci{ 4038bf80f4bSopenharmony_ci std::unique_lock lock { disposalMutex_ }; 4048bf80f4bSopenharmony_ci disposals_.push_back(uid); 4058bf80f4bSopenharmony_ci ++purgeCounter_; 4068bf80f4bSopenharmony_ci} 4078bf80f4bSopenharmony_ci 4088bf80f4bSopenharmony_ciIMetadata::Ptr ObjectRegistry::ConstructMetadata() const 4098bf80f4bSopenharmony_ci{ 4108bf80f4bSopenharmony_ci return IMetadata::Ptr { new Internal::Metadata }; 4118bf80f4bSopenharmony_ci} 4128bf80f4bSopenharmony_ci 4138bf80f4bSopenharmony_ciICallContext::Ptr ObjectRegistry::ConstructDefaultCallContext() const 4148bf80f4bSopenharmony_ci{ 4158bf80f4bSopenharmony_ci return ICallContext::Ptr { new DefaultCallContext }; 4168bf80f4bSopenharmony_ci} 4178bf80f4bSopenharmony_ci 4188bf80f4bSopenharmony_ciBASE_NS::vector<IObject::Ptr> ObjectRegistry::GetAllObjectInstances() const 4198bf80f4bSopenharmony_ci{ 4208bf80f4bSopenharmony_ci CheckGC(); 4218bf80f4bSopenharmony_ci BASE_NS::vector<IObject::Ptr> result; 4228bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 4238bf80f4bSopenharmony_ci result.reserve(instancesByUid_.size()); 4248bf80f4bSopenharmony_ci for (const auto& v : instancesByUid_) { 4258bf80f4bSopenharmony_ci if (auto strong = v.second.ptr.lock()) { 4268bf80f4bSopenharmony_ci result.emplace_back(strong); 4278bf80f4bSopenharmony_ci } 4288bf80f4bSopenharmony_ci } 4298bf80f4bSopenharmony_ci return result; 4308bf80f4bSopenharmony_ci} 4318bf80f4bSopenharmony_ci 4328bf80f4bSopenharmony_ciBASE_NS::vector<IObject::Ptr> ObjectRegistry::GetAllSingletonObjectInstances() const 4338bf80f4bSopenharmony_ci{ 4348bf80f4bSopenharmony_ci CheckGC(); 4358bf80f4bSopenharmony_ci BASE_NS::vector<IObject::Ptr> result; 4368bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 4378bf80f4bSopenharmony_ci if (!singletons_.empty()) { 4388bf80f4bSopenharmony_ci result.reserve(singletons_.size()); 4398bf80f4bSopenharmony_ci for (const auto& s : singletons_) { 4408bf80f4bSopenharmony_ci if (auto strong = s.second.lock()) { 4418bf80f4bSopenharmony_ci result.push_back(strong); 4428bf80f4bSopenharmony_ci } 4438bf80f4bSopenharmony_ci } 4448bf80f4bSopenharmony_ci } 4458bf80f4bSopenharmony_ci return result; 4468bf80f4bSopenharmony_ci} 4478bf80f4bSopenharmony_ci 4488bf80f4bSopenharmony_ciBASE_NS::vector<IObject::Ptr> ObjectRegistry::GetObjectInstancesByCategory( 4498bf80f4bSopenharmony_ci ObjectCategoryBits category, bool strict) const 4508bf80f4bSopenharmony_ci{ 4518bf80f4bSopenharmony_ci CheckGC(); 4528bf80f4bSopenharmony_ci BASE_NS::vector<IObject::Ptr> result; 4538bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 4548bf80f4bSopenharmony_ci for (const auto& i : instancesByUid_) { 4558bf80f4bSopenharmony_ci if (CheckCategoryBits(static_cast<ObjectCategoryBits>(i.second.category), category, strict)) { 4568bf80f4bSopenharmony_ci if (auto strong = i.second.ptr.lock()) { 4578bf80f4bSopenharmony_ci result.emplace_back(strong); 4588bf80f4bSopenharmony_ci } 4598bf80f4bSopenharmony_ci } 4608bf80f4bSopenharmony_ci } 4618bf80f4bSopenharmony_ci return result; 4628bf80f4bSopenharmony_ci} 4638bf80f4bSopenharmony_ci 4648bf80f4bSopenharmony_ciIObject::Ptr ObjectRegistry::FindSingleton(const BASE_NS::Uid uid) const 4658bf80f4bSopenharmony_ci{ 4668bf80f4bSopenharmony_ci auto it = singletons_.find(uid); 4678bf80f4bSopenharmony_ci return it != singletons_.end() ? it->second.lock() : nullptr; 4688bf80f4bSopenharmony_ci} 4698bf80f4bSopenharmony_ci 4708bf80f4bSopenharmony_ciIObject::Ptr ObjectRegistry::GetObjectInstanceByInstanceId(InstanceId uid) const 4718bf80f4bSopenharmony_ci{ 4728bf80f4bSopenharmony_ci if (uid == BASE_NS::Uid()) { 4738bf80f4bSopenharmony_ci // invalid/zero/empty UID. 4748bf80f4bSopenharmony_ci return nullptr; 4758bf80f4bSopenharmony_ci } 4768bf80f4bSopenharmony_ci 4778bf80f4bSopenharmony_ci CheckGC(); 4788bf80f4bSopenharmony_ci 4798bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 4808bf80f4bSopenharmony_ci 4818bf80f4bSopenharmony_ci // See if it's an singleton. 4828bf80f4bSopenharmony_ci auto sing = FindSingleton(uid.ToUid()); 4838bf80f4bSopenharmony_ci if (sing) { 4848bf80f4bSopenharmony_ci return sing; 4858bf80f4bSopenharmony_ci } 4868bf80f4bSopenharmony_ci 4878bf80f4bSopenharmony_ci // Non singletons then 4888bf80f4bSopenharmony_ci auto it2 = instancesByUid_.find(uid); 4898bf80f4bSopenharmony_ci if (it2 != instancesByUid_.end()) { 4908bf80f4bSopenharmony_ci if (auto strong = it2->second.ptr.lock()) { 4918bf80f4bSopenharmony_ci return strong; 4928bf80f4bSopenharmony_ci } 4938bf80f4bSopenharmony_ci } 4948bf80f4bSopenharmony_ci 4958bf80f4bSopenharmony_ci // No such instance then 4968bf80f4bSopenharmony_ci return nullptr; 4978bf80f4bSopenharmony_ci} 4988bf80f4bSopenharmony_ci 4998bf80f4bSopenharmony_ciBASE_NS::string ObjectRegistry::ExportToString(const IObjectRegistryExporter::Ptr& exporter) const 5008bf80f4bSopenharmony_ci{ 5018bf80f4bSopenharmony_ci return exporter ? exporter->ExportRegistry(this) : ""; 5028bf80f4bSopenharmony_ci} 5038bf80f4bSopenharmony_ci 5048bf80f4bSopenharmony_ciIObjectContext::Ptr ObjectRegistry::GetDefaultObjectContext() const 5058bf80f4bSopenharmony_ci{ 5068bf80f4bSopenharmony_ci { 5078bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 5088bf80f4bSopenharmony_ci if (defaultContext_) { 5098bf80f4bSopenharmony_ci return defaultContext_; 5108bf80f4bSopenharmony_ci } 5118bf80f4bSopenharmony_ci } 5128bf80f4bSopenharmony_ci 5138bf80f4bSopenharmony_ci IObjectContext::Ptr context = interface_pointer_cast<IObjectContext>( 5148bf80f4bSopenharmony_ci Create(ClassId::ObjectContext, { GlobalObjectInstance::DEFAULT_OBJECT_CONTEXT, true })); 5158bf80f4bSopenharmony_ci 5168bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 5178bf80f4bSopenharmony_ci // still not set? 5188bf80f4bSopenharmony_ci if (!defaultContext_) { 5198bf80f4bSopenharmony_ci defaultContext_ = context; 5208bf80f4bSopenharmony_ci } 5218bf80f4bSopenharmony_ci CORE_ASSERT(defaultContext_); 5228bf80f4bSopenharmony_ci return defaultContext_; 5238bf80f4bSopenharmony_ci} 5248bf80f4bSopenharmony_ci 5258bf80f4bSopenharmony_ciITaskQueue::Ptr ObjectRegistry::GetTaskQueue(const BASE_NS::Uid& queueId) const 5268bf80f4bSopenharmony_ci{ 5278bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 5288bf80f4bSopenharmony_ci if (auto queue = queues_.find(queueId); queue != queues_.end()) { 5298bf80f4bSopenharmony_ci return queue->second; 5308bf80f4bSopenharmony_ci } 5318bf80f4bSopenharmony_ci CORE_LOG_W("Cannot get task queue, task queue not registered: %s", BASE_NS::to_string(queueId).data()); 5328bf80f4bSopenharmony_ci return {}; 5338bf80f4bSopenharmony_ci} 5348bf80f4bSopenharmony_ci 5358bf80f4bSopenharmony_cibool ObjectRegistry::RegisterTaskQueue(const ITaskQueue::Ptr& queue, const BASE_NS::Uid& queueId) 5368bf80f4bSopenharmony_ci{ 5378bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 5388bf80f4bSopenharmony_ci if (!queue) { 5398bf80f4bSopenharmony_ci if (auto existing = queues_.find(queueId); existing != queues_.end()) { 5408bf80f4bSopenharmony_ci queues_.erase(existing); 5418bf80f4bSopenharmony_ci return true; 5428bf80f4bSopenharmony_ci } 5438bf80f4bSopenharmony_ci // Null queue but no existing queue found 5448bf80f4bSopenharmony_ci return false; 5458bf80f4bSopenharmony_ci } 5468bf80f4bSopenharmony_ci queues_[queueId] = queue; 5478bf80f4bSopenharmony_ci return true; 5488bf80f4bSopenharmony_ci} 5498bf80f4bSopenharmony_ci 5508bf80f4bSopenharmony_cibool ObjectRegistry::UnregisterTaskQueue(const BASE_NS::Uid& queueId) 5518bf80f4bSopenharmony_ci{ 5528bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 5538bf80f4bSopenharmony_ci if (auto existing = queues_.find(queueId); existing != queues_.end()) { 5548bf80f4bSopenharmony_ci queues_.erase(existing); 5558bf80f4bSopenharmony_ci return true; 5568bf80f4bSopenharmony_ci } 5578bf80f4bSopenharmony_ci return false; 5588bf80f4bSopenharmony_ci} 5598bf80f4bSopenharmony_ci 5608bf80f4bSopenharmony_cibool ObjectRegistry::HasTaskQueue(const BASE_NS::Uid& queueId) const 5618bf80f4bSopenharmony_ci{ 5628bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 5638bf80f4bSopenharmony_ci return queues_.find(queueId) != queues_.end(); 5648bf80f4bSopenharmony_ci} 5658bf80f4bSopenharmony_ci 5668bf80f4bSopenharmony_cibool ObjectRegistry::UnregisterAllTaskQueues() 5678bf80f4bSopenharmony_ci{ 5688bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 5698bf80f4bSopenharmony_ci queues_.clear(); 5708bf80f4bSopenharmony_ci return true; 5718bf80f4bSopenharmony_ci} 5728bf80f4bSopenharmony_ci 5738bf80f4bSopenharmony_cistatic ITaskQueue::WeakPtr& GetCurrentTaskQueueImpl() 5748bf80f4bSopenharmony_ci{ 5758bf80f4bSopenharmony_ci static thread_local ITaskQueue::WeakPtr q; 5768bf80f4bSopenharmony_ci return q; 5778bf80f4bSopenharmony_ci} 5788bf80f4bSopenharmony_ci 5798bf80f4bSopenharmony_ciITaskQueue::Ptr ObjectRegistry::GetCurrentTaskQueue() const 5808bf80f4bSopenharmony_ci{ 5818bf80f4bSopenharmony_ci return GetCurrentTaskQueueImpl().lock(); 5828bf80f4bSopenharmony_ci} 5838bf80f4bSopenharmony_ciITaskQueue::WeakPtr ObjectRegistry::SetCurrentTaskQueue(ITaskQueue::WeakPtr q) 5848bf80f4bSopenharmony_ci{ 5858bf80f4bSopenharmony_ci auto& impl = GetCurrentTaskQueueImpl(); 5868bf80f4bSopenharmony_ci auto res = impl; 5878bf80f4bSopenharmony_ci impl = q; 5888bf80f4bSopenharmony_ci return res; 5898bf80f4bSopenharmony_ci} 5908bf80f4bSopenharmony_ci 5918bf80f4bSopenharmony_civoid ObjectRegistry::RegisterInterpolator(TypeId propertyTypeUid, BASE_NS::Uid interpolatorClassUid) 5928bf80f4bSopenharmony_ci{ 5938bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 5948bf80f4bSopenharmony_ci interpolatorConstructors_[propertyTypeUid] = interpolatorClassUid; 5958bf80f4bSopenharmony_ci} 5968bf80f4bSopenharmony_ci 5978bf80f4bSopenharmony_civoid ObjectRegistry::UnregisterInterpolator(TypeId propertyTypeUid) 5988bf80f4bSopenharmony_ci{ 5998bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 6008bf80f4bSopenharmony_ci interpolatorConstructors_.erase(propertyTypeUid); 6018bf80f4bSopenharmony_ci} 6028bf80f4bSopenharmony_ci 6038bf80f4bSopenharmony_cibool ObjectRegistry::HasInterpolator(TypeId propertyTypeUid) const 6048bf80f4bSopenharmony_ci{ 6058bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 6068bf80f4bSopenharmony_ci return interpolatorConstructors_.contains(propertyTypeUid); 6078bf80f4bSopenharmony_ci} 6088bf80f4bSopenharmony_ci 6098bf80f4bSopenharmony_ciIInterpolator::Ptr ObjectRegistry::CreateInterpolator(TypeId propertyTypeUid) 6108bf80f4bSopenharmony_ci{ 6118bf80f4bSopenharmony_ci TypeId uid; 6128bf80f4bSopenharmony_ci { 6138bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 6148bf80f4bSopenharmony_ci if (auto it = interpolatorConstructors_.find(propertyTypeUid); it != interpolatorConstructors_.end()) { 6158bf80f4bSopenharmony_ci uid = it->second; 6168bf80f4bSopenharmony_ci } 6178bf80f4bSopenharmony_ci } 6188bf80f4bSopenharmony_ci if (uid != TypeId {}) { 6198bf80f4bSopenharmony_ci return interface_pointer_cast<IInterpolator>(Create(uid.ToUid(), CreateInfo {})); 6208bf80f4bSopenharmony_ci } 6218bf80f4bSopenharmony_ci // We don't have an interpolator for the given property type, return the default interpolator (which just steps the 6228bf80f4bSopenharmony_ci // value) 6238bf80f4bSopenharmony_ci CORE_LOG_D("No interpolator for property type %s, falling back to default interpolator", 6248bf80f4bSopenharmony_ci propertyTypeUid.ToString().c_str()); 6258bf80f4bSopenharmony_ci return interface_pointer_cast<IInterpolator>(IObjectRegistry::Create(ClassId::DefaultInterpolator)); 6268bf80f4bSopenharmony_ci} 6278bf80f4bSopenharmony_ci 6288bf80f4bSopenharmony_ciconst CORE_NS::IInterface* ObjectRegistry::GetInterface(const BASE_NS::Uid& uid) const 6298bf80f4bSopenharmony_ci{ 6308bf80f4bSopenharmony_ci const CORE_NS::IInterface* result = nullptr; 6318bf80f4bSopenharmony_ci if (uid == CORE_NS::IInterface::UID) { 6328bf80f4bSopenharmony_ci const IObjectRegistry* obj = static_cast<const IObjectRegistry*>(this); 6338bf80f4bSopenharmony_ci result = static_cast<const IInterface*>(obj); 6348bf80f4bSopenharmony_ci } 6358bf80f4bSopenharmony_ci if (uid == IObjectRegistry::UID) { 6368bf80f4bSopenharmony_ci result = static_cast<const IObjectRegistry*>(this); 6378bf80f4bSopenharmony_ci } 6388bf80f4bSopenharmony_ci if (uid == ITaskQueueRegistry::UID) { 6398bf80f4bSopenharmony_ci result = static_cast<const ITaskQueueRegistry*>(this); 6408bf80f4bSopenharmony_ci } 6418bf80f4bSopenharmony_ci return result; 6428bf80f4bSopenharmony_ci} 6438bf80f4bSopenharmony_ciCORE_NS::IInterface* ObjectRegistry::GetInterface(const BASE_NS::Uid& uid) 6448bf80f4bSopenharmony_ci{ 6458bf80f4bSopenharmony_ci CORE_NS::IInterface* result = nullptr; 6468bf80f4bSopenharmony_ci if (uid == CORE_NS::IInterface::UID) { 6478bf80f4bSopenharmony_ci IObjectRegistry* obj = static_cast<IObjectRegistry*>(this); 6488bf80f4bSopenharmony_ci result = static_cast<IInterface*>(obj); 6498bf80f4bSopenharmony_ci } 6508bf80f4bSopenharmony_ci if (uid == IObjectRegistry::UID) { 6518bf80f4bSopenharmony_ci result = static_cast<IObjectRegistry*>(this); 6528bf80f4bSopenharmony_ci } 6538bf80f4bSopenharmony_ci if (uid == ITaskQueueRegistry::UID) { 6548bf80f4bSopenharmony_ci result = static_cast<ITaskQueueRegistry*>(this); 6558bf80f4bSopenharmony_ci } 6568bf80f4bSopenharmony_ci return result; 6578bf80f4bSopenharmony_ci} 6588bf80f4bSopenharmony_civoid ObjectRegistry::Ref() {} 6598bf80f4bSopenharmony_civoid ObjectRegistry::Unref() {} 6608bf80f4bSopenharmony_ci 6618bf80f4bSopenharmony_ciMETA_NS::IPropertyRegister& ObjectRegistry::GetPropertyRegister() 6628bf80f4bSopenharmony_ci{ 6638bf80f4bSopenharmony_ci return *this; 6648bf80f4bSopenharmony_ci} 6658bf80f4bSopenharmony_ci 6668bf80f4bSopenharmony_ciMETA_NS::IProperty::Ptr ObjectRegistry::Create(const ObjectId& object, BASE_NS::string_view name) const 6678bf80f4bSopenharmony_ci{ 6688bf80f4bSopenharmony_ci if (object == ClassId::StackProperty) { 6698bf80f4bSopenharmony_ci auto p = META_NS::IProperty::Ptr(new META_NS::Internal::StackProperty(BASE_NS::string(name))); 6708bf80f4bSopenharmony_ci if (auto i = interface_cast<IPropertyInternal>(p)) { 6718bf80f4bSopenharmony_ci i->SetSelf(p); 6728bf80f4bSopenharmony_ci } 6738bf80f4bSopenharmony_ci return p; 6748bf80f4bSopenharmony_ci } 6758bf80f4bSopenharmony_ci return nullptr; 6768bf80f4bSopenharmony_ci} 6778bf80f4bSopenharmony_ciIBind::Ptr ObjectRegistry::CreateBind() const 6788bf80f4bSopenharmony_ci{ 6798bf80f4bSopenharmony_ci return interface_pointer_cast<IBind>(Create(ClassId::Bind, CreateInfo {})); 6808bf80f4bSopenharmony_ci} 6818bf80f4bSopenharmony_ciIAny& ObjectRegistry::InvalidAny() const 6828bf80f4bSopenharmony_ci{ 6838bf80f4bSopenharmony_ci static DummyAny any; 6848bf80f4bSopenharmony_ci return any; 6858bf80f4bSopenharmony_ci} 6868bf80f4bSopenharmony_ciIAny::Ptr ObjectRegistry::ConstructAny(const ObjectId& id) const 6878bf80f4bSopenharmony_ci{ 6888bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 6898bf80f4bSopenharmony_ci auto it = anyBuilders_.find(id); 6908bf80f4bSopenharmony_ci return it != anyBuilders_.end() ? it->second->Construct() : nullptr; 6918bf80f4bSopenharmony_ci} 6928bf80f4bSopenharmony_cibool ObjectRegistry::IsAnyRegistered(const ObjectId& id) const 6938bf80f4bSopenharmony_ci{ 6948bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 6958bf80f4bSopenharmony_ci return anyBuilders_.find(id) != anyBuilders_.end(); 6968bf80f4bSopenharmony_ci} 6978bf80f4bSopenharmony_civoid ObjectRegistry::RegisterAny(BASE_NS::shared_ptr<AnyBuilder> builder) 6988bf80f4bSopenharmony_ci{ 6998bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 7008bf80f4bSopenharmony_ci if (anyBuilders_.find(builder->GetObjectId()) != anyBuilders_.end()) { 7018bf80f4bSopenharmony_ci CORE_LOG_W("Any already registered [id=%s]", builder->GetObjectId().ToString().c_str()); 7028bf80f4bSopenharmony_ci } 7038bf80f4bSopenharmony_ci anyBuilders_[builder->GetObjectId()] = builder; 7048bf80f4bSopenharmony_ci} 7058bf80f4bSopenharmony_civoid ObjectRegistry::UnregisterAny(const ObjectId& id) 7068bf80f4bSopenharmony_ci{ 7078bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 7088bf80f4bSopenharmony_ci anyBuilders_.erase(id); 7098bf80f4bSopenharmony_ci} 7108bf80f4bSopenharmony_ciIGlobalSerializationData& ObjectRegistry::GetGlobalSerializationData() 7118bf80f4bSopenharmony_ci{ 7128bf80f4bSopenharmony_ci return *this; 7138bf80f4bSopenharmony_ci} 7148bf80f4bSopenharmony_ciSerializationSettings ObjectRegistry::GetDefaultSettings() const 7158bf80f4bSopenharmony_ci{ 7168bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 7178bf80f4bSopenharmony_ci return defaultSettings_; 7188bf80f4bSopenharmony_ci} 7198bf80f4bSopenharmony_civoid ObjectRegistry::SetDefaultSettings(const SerializationSettings& settings) 7208bf80f4bSopenharmony_ci{ 7218bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 7228bf80f4bSopenharmony_ci defaultSettings_ = settings; 7238bf80f4bSopenharmony_ci} 7248bf80f4bSopenharmony_civoid ObjectRegistry::RegisterGlobalObject(const IObject::Ptr& object) 7258bf80f4bSopenharmony_ci{ 7268bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 7278bf80f4bSopenharmony_ci if (auto p = interface_cast<IObjectInstance>(object)) { 7288bf80f4bSopenharmony_ci globalObjects_[p->GetInstanceId()] = object; 7298bf80f4bSopenharmony_ci } 7308bf80f4bSopenharmony_ci} 7318bf80f4bSopenharmony_civoid ObjectRegistry::UnregisterGlobalObject(const IObject::Ptr& object) 7328bf80f4bSopenharmony_ci{ 7338bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 7348bf80f4bSopenharmony_ci if (auto p = interface_cast<IObjectInstance>(object)) { 7358bf80f4bSopenharmony_ci globalObjects_.erase(p->GetInstanceId()); 7368bf80f4bSopenharmony_ci } 7378bf80f4bSopenharmony_ci} 7388bf80f4bSopenharmony_ciIObject::Ptr ObjectRegistry::GetGlobalObject(const InstanceId& id) const 7398bf80f4bSopenharmony_ci{ 7408bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 7418bf80f4bSopenharmony_ci auto it = globalObjects_.find(id); 7428bf80f4bSopenharmony_ci return it != globalObjects_.end() ? it->second.lock() : nullptr; 7438bf80f4bSopenharmony_ci} 7448bf80f4bSopenharmony_civoid ObjectRegistry::RegisterValueSerializer(const IValueSerializer::Ptr& s) 7458bf80f4bSopenharmony_ci{ 7468bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 7478bf80f4bSopenharmony_ci valueSerializers_[s->GetTypeId()] = s; 7488bf80f4bSopenharmony_ci} 7498bf80f4bSopenharmony_civoid ObjectRegistry::UnregisterValueSerializer(const TypeId& id) 7508bf80f4bSopenharmony_ci{ 7518bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 7528bf80f4bSopenharmony_ci valueSerializers_.erase(id); 7538bf80f4bSopenharmony_ci} 7548bf80f4bSopenharmony_ciIValueSerializer::Ptr ObjectRegistry::GetValueSerializer(const TypeId& id) const 7558bf80f4bSopenharmony_ci{ 7568bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 7578bf80f4bSopenharmony_ci auto it = valueSerializers_.find(id); 7588bf80f4bSopenharmony_ci return it != valueSerializers_.end() ? it->second : nullptr; 7598bf80f4bSopenharmony_ci} 7608bf80f4bSopenharmony_ci 7618bf80f4bSopenharmony_ciIEngineInternalValueAccess::Ptr ObjectRegistry::GetInternalValueAccess(const CORE_NS::PropertyTypeDecl& type) const 7628bf80f4bSopenharmony_ci{ 7638bf80f4bSopenharmony_ci std::shared_lock lock { mutex_ }; 7648bf80f4bSopenharmony_ci auto it = engineInternalAccess_.find(type); 7658bf80f4bSopenharmony_ci return it != engineInternalAccess_.end() ? it->second : nullptr; 7668bf80f4bSopenharmony_ci} 7678bf80f4bSopenharmony_civoid ObjectRegistry::RegisterInternalValueAccess( 7688bf80f4bSopenharmony_ci const CORE_NS::PropertyTypeDecl& type, IEngineInternalValueAccess::Ptr ptr) 7698bf80f4bSopenharmony_ci{ 7708bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 7718bf80f4bSopenharmony_ci engineInternalAccess_[type] = BASE_NS::move(ptr); 7728bf80f4bSopenharmony_ci} 7738bf80f4bSopenharmony_civoid ObjectRegistry::UnregisterInternalValueAccess(const CORE_NS::PropertyTypeDecl& type) 7748bf80f4bSopenharmony_ci{ 7758bf80f4bSopenharmony_ci std::unique_lock lock { mutex_ }; 7768bf80f4bSopenharmony_ci engineInternalAccess_.erase(type); 7778bf80f4bSopenharmony_ci} 7788bf80f4bSopenharmony_ciIEngineData& ObjectRegistry::GetEngineData() 7798bf80f4bSopenharmony_ci{ 7808bf80f4bSopenharmony_ci return *this; 7818bf80f4bSopenharmony_ci} 7828bf80f4bSopenharmony_ciMETA_END_NAMESPACE() 783