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