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 "meta_object_lib.h"
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <shared_mutex>
198bf80f4bSopenharmony_ci
208bf80f4bSopenharmony_ci#include <meta/interface/animation/builtin_animations.h>
218bf80f4bSopenharmony_ci
228bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE()
238bf80f4bSopenharmony_ci
248bf80f4bSopenharmony_ciusing CORE_NS::MutexHandle;
258bf80f4bSopenharmony_ciusing CORE_NS::MutexType;
268bf80f4bSopenharmony_ci
278bf80f4bSopenharmony_ci#if defined(__ANDROID__)
288bf80f4bSopenharmony_ciusing InternalMutexType = std::mutex;
298bf80f4bSopenharmony_ci#else
308bf80f4bSopenharmony_ci// std::mutex on vc2017 is 80 bytes and much slower than std::shared_mutex
318bf80f4bSopenharmony_ciusing InternalMutexType = std::shared_mutex;
328bf80f4bSopenharmony_ci#endif
338bf80f4bSopenharmony_ci
348bf80f4bSopenharmony_ciconstexpr bool USE_IN_PLACE_MUTEX =
358bf80f4bSopenharmony_ci    sizeof(InternalMutexType) <= sizeof(MutexHandle::storage) && alignof(InternalMutexType) <= alignof(MutexHandle);
368bf80f4bSopenharmony_ci
378bf80f4bSopenharmony_cistatic void CreateMutex(MutexType, MutexHandle& handle)
388bf80f4bSopenharmony_ci{
398bf80f4bSopenharmony_ci    // do we have suitable storage for constructing mutex in-place
408bf80f4bSopenharmony_ci    if constexpr (USE_IN_PLACE_MUTEX) {
418bf80f4bSopenharmony_ci        new (handle.storage) InternalMutexType;
428bf80f4bSopenharmony_ci    } else {
438bf80f4bSopenharmony_ci        handle.ptr = new InternalMutexType;
448bf80f4bSopenharmony_ci    }
458bf80f4bSopenharmony_ci}
468bf80f4bSopenharmony_ci
478bf80f4bSopenharmony_cistatic void DestroyMutex(MutexHandle& handle)
488bf80f4bSopenharmony_ci{
498bf80f4bSopenharmony_ci    if constexpr (USE_IN_PLACE_MUTEX) {
508bf80f4bSopenharmony_ci        static_cast<InternalMutexType*>(static_cast<void*>(handle.storage))->~InternalMutexType();
518bf80f4bSopenharmony_ci    } else {
528bf80f4bSopenharmony_ci        delete static_cast<InternalMutexType*>(handle.ptr);
538bf80f4bSopenharmony_ci    }
548bf80f4bSopenharmony_ci}
558bf80f4bSopenharmony_ci
568bf80f4bSopenharmony_cistatic bool LockMutex(MutexHandle& handle)
578bf80f4bSopenharmony_ci{
588bf80f4bSopenharmony_ci    if constexpr (USE_IN_PLACE_MUTEX) {
598bf80f4bSopenharmony_ci        static_cast<InternalMutexType*>(static_cast<void*>(handle.storage))->lock();
608bf80f4bSopenharmony_ci    } else {
618bf80f4bSopenharmony_ci        static_cast<InternalMutexType*>(handle.ptr)->lock();
628bf80f4bSopenharmony_ci    }
638bf80f4bSopenharmony_ci    return true;
648bf80f4bSopenharmony_ci}
658bf80f4bSopenharmony_ci
668bf80f4bSopenharmony_cistatic bool UnlockMutex(MutexHandle& handle)
678bf80f4bSopenharmony_ci{
688bf80f4bSopenharmony_ci    if constexpr (USE_IN_PLACE_MUTEX) {
698bf80f4bSopenharmony_ci        static_cast<InternalMutexType*>(static_cast<void*>(handle.storage))->unlock();
708bf80f4bSopenharmony_ci    } else {
718bf80f4bSopenharmony_ci        static_cast<InternalMutexType*>(handle.ptr)->unlock();
728bf80f4bSopenharmony_ci    }
738bf80f4bSopenharmony_ci    return true;
748bf80f4bSopenharmony_ci}
758bf80f4bSopenharmony_ci
768bf80f4bSopenharmony_cistatic uint64_t GetThreadId()
778bf80f4bSopenharmony_ci{
788bf80f4bSopenharmony_ci    thread_local const char variable {};
798bf80f4bSopenharmony_ci    return reinterpret_cast<uint64_t>(&variable);
808bf80f4bSopenharmony_ci}
818bf80f4bSopenharmony_ci
828bf80f4bSopenharmony_cinamespace Internal {
838bf80f4bSopenharmony_civoid RegisterEntities(IObjectRegistry& registry);
848bf80f4bSopenharmony_civoid UnRegisterEntities(IObjectRegistry& registry);
858bf80f4bSopenharmony_civoid RegisterValueSerializers(IObjectRegistry& registry);
868bf80f4bSopenharmony_civoid UnRegisterValueSerializers(IObjectRegistry& registry);
878bf80f4bSopenharmony_civoid RegisterAnys(IObjectRegistry& registry);
888bf80f4bSopenharmony_civoid UnRegisterAnys(IObjectRegistry& registry);
898bf80f4bSopenharmony_civoid RegisterEngineTypes(IObjectRegistry& registry);
908bf80f4bSopenharmony_civoid UnRegisterEngineTypes(IObjectRegistry& registry);
918bf80f4bSopenharmony_ci} // namespace Internal
928bf80f4bSopenharmony_ci
938bf80f4bSopenharmony_ciconst CORE_NS::IInterface* MetaObjectLib::GetInterface(const BASE_NS::Uid& uid) const
948bf80f4bSopenharmony_ci{
958bf80f4bSopenharmony_ci    if (uid == IMetaObjectLib::UID) {
968bf80f4bSopenharmony_ci        return this;
978bf80f4bSopenharmony_ci    }
988bf80f4bSopenharmony_ci    if (uid == CORE_NS::IInterface::UID) {
998bf80f4bSopenharmony_ci        return this;
1008bf80f4bSopenharmony_ci    }
1018bf80f4bSopenharmony_ci    return nullptr;
1028bf80f4bSopenharmony_ci}
1038bf80f4bSopenharmony_ci
1048bf80f4bSopenharmony_ciCORE_NS::IInterface* MetaObjectLib::GetInterface(const BASE_NS::Uid& uid)
1058bf80f4bSopenharmony_ci{
1068bf80f4bSopenharmony_ci    const auto* p = this;
1078bf80f4bSopenharmony_ci    return const_cast<CORE_NS::IInterface*>(p->MetaObjectLib::GetInterface(uid));
1088bf80f4bSopenharmony_ci}
1098bf80f4bSopenharmony_ci
1108bf80f4bSopenharmony_ciMetaObjectLib::MetaObjectLib()
1118bf80f4bSopenharmony_ci    : sapi_ { { CreateMutex, DestroyMutex, LockMutex, UnlockMutex }, GetThreadId }
1128bf80f4bSopenharmony_ci{
1138bf80f4bSopenharmony_ci    if (USE_IN_PLACE_MUTEX) {
1148bf80f4bSopenharmony_ci        CORE_LOG_D("Using in-place mutex");
1158bf80f4bSopenharmony_ci    } else {
1168bf80f4bSopenharmony_ci        CORE_LOG_D("Not using in-place mutex");
1178bf80f4bSopenharmony_ci    }
1188bf80f4bSopenharmony_ci}
1198bf80f4bSopenharmony_ci
1208bf80f4bSopenharmony_civoid MetaObjectLib::Initialize()
1218bf80f4bSopenharmony_ci{
1228bf80f4bSopenharmony_ci    registry_ = new ObjectRegistry;
1238bf80f4bSopenharmony_ci    Internal::RegisterAnys(*registry_);
1248bf80f4bSopenharmony_ci    Internal::RegisterEntities(*registry_);
1258bf80f4bSopenharmony_ci    Internal::RegisterValueSerializers(*registry_);
1268bf80f4bSopenharmony_ci    Internal::RegisterEngineTypes(*registry_);
1278bf80f4bSopenharmony_ci}
1288bf80f4bSopenharmony_ci
1298bf80f4bSopenharmony_civoid MetaObjectLib::Uninitialize()
1308bf80f4bSopenharmony_ci{
1318bf80f4bSopenharmony_ci    Internal::UnRegisterEngineTypes(*registry_);
1328bf80f4bSopenharmony_ci    Internal::UnRegisterValueSerializers(*registry_);
1338bf80f4bSopenharmony_ci    Internal::UnRegisterEntities(*registry_);
1348bf80f4bSopenharmony_ci    Internal::UnRegisterAnys(*registry_);
1358bf80f4bSopenharmony_ci}
1368bf80f4bSopenharmony_ci
1378bf80f4bSopenharmony_ciMetaObjectLib::~MetaObjectLib()
1388bf80f4bSopenharmony_ci{
1398bf80f4bSopenharmony_ci    animationController_.reset();
1408bf80f4bSopenharmony_ci    registry_->Purge();
1418bf80f4bSopenharmony_ci    delete registry_;
1428bf80f4bSopenharmony_ci}
1438bf80f4bSopenharmony_ci
1448bf80f4bSopenharmony_ciIObjectRegistry& MetaObjectLib::GetObjectRegistry() const
1458bf80f4bSopenharmony_ci{
1468bf80f4bSopenharmony_ci    return *registry_;
1478bf80f4bSopenharmony_ci}
1488bf80f4bSopenharmony_ci
1498bf80f4bSopenharmony_ciITaskQueueRegistry& MetaObjectLib::GetTaskQueueRegistry() const
1508bf80f4bSopenharmony_ci{
1518bf80f4bSopenharmony_ci    return *static_cast<ITaskQueueRegistry*>(registry_);
1528bf80f4bSopenharmony_ci}
1538bf80f4bSopenharmony_ci
1548bf80f4bSopenharmony_ciIAnimationController::Ptr MetaObjectLib::GetAnimationController() const
1558bf80f4bSopenharmony_ci{
1568bf80f4bSopenharmony_ci    std::call_once(animInit_, [&] {
1578bf80f4bSopenharmony_ci        auto iregistry = static_cast<IObjectRegistry*>(registry_);
1588bf80f4bSopenharmony_ci        animationController_ = iregistry->Create<IAnimationController>(ClassId::AnimationController);
1598bf80f4bSopenharmony_ci    });
1608bf80f4bSopenharmony_ci    return animationController_;
1618bf80f4bSopenharmony_ci}
1628bf80f4bSopenharmony_ci
1638bf80f4bSopenharmony_ciconst CORE_NS::SyncApi& MetaObjectLib::GetSyncApi() const
1648bf80f4bSopenharmony_ci{
1658bf80f4bSopenharmony_ci    return sapi_;
1668bf80f4bSopenharmony_ci}
1678bf80f4bSopenharmony_ci
1688bf80f4bSopenharmony_ciMETA_END_NAMESPACE()
169