• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "meta_object_lib.h"
17 
18 #include <shared_mutex>
19 
20 #include <meta/interface/animation/builtin_animations.h>
21 
22 META_BEGIN_NAMESPACE()
23 
24 using CORE_NS::MutexHandle;
25 using CORE_NS::MutexType;
26 
27 // std::mutex on vc2017 is 80 bytes and much slower than std::shared_mutex
28 using InternalMutexType = std::shared_mutex;
29 
30 constexpr bool USE_IN_PLACE_MUTEX =
31     sizeof(InternalMutexType) <= sizeof(MutexHandle::storage) && alignof(InternalMutexType) <= alignof(MutexHandle);
32 
CreateMutex(MutexType,MutexHandle & handle)33 static void CreateMutex(MutexType, MutexHandle& handle)
34 {
35     // do we have suitable storage for constructing mutex in-place
36     if constexpr (USE_IN_PLACE_MUTEX) {
37         new (handle.storage) InternalMutexType;
38     } else {
39         handle.ptr = new InternalMutexType;
40     }
41 }
42 
DestroyMutex(MutexHandle & handle)43 static void DestroyMutex(MutexHandle& handle)
44 {
45     if constexpr (USE_IN_PLACE_MUTEX) {
46         static_cast<InternalMutexType*>(static_cast<void*>(handle.storage))->~InternalMutexType();
47     } else {
48         delete static_cast<InternalMutexType*>(handle.ptr);
49     }
50 }
51 
LockMutex(MutexHandle & handle)52 static bool LockMutex(MutexHandle& handle)
53 {
54     if constexpr (USE_IN_PLACE_MUTEX) {
55         static_cast<InternalMutexType*>(static_cast<void*>(handle.storage))->lock();
56     } else {
57         static_cast<InternalMutexType*>(handle.ptr)->lock();
58     }
59     return true;
60 }
61 
UnlockMutex(MutexHandle & handle)62 static bool UnlockMutex(MutexHandle& handle)
63 {
64     if constexpr (USE_IN_PLACE_MUTEX) {
65         static_cast<InternalMutexType*>(static_cast<void*>(handle.storage))->unlock();
66     } else {
67         static_cast<InternalMutexType*>(handle.ptr)->unlock();
68     }
69     return true;
70 }
71 
GetThreadId()72 static uint64_t GetThreadId()
73 {
74     thread_local const char variable {};
75     return reinterpret_cast<uint64_t>(&variable);
76 }
77 
78 namespace Internal {
79 void RegisterEntities(IObjectRegistry& registry);
80 void UnRegisterEntities(IObjectRegistry& registry);
81 void RegisterValueSerializers(IObjectRegistry& registry);
82 void UnRegisterValueSerializers(IObjectRegistry& registry);
83 void RegisterAnys(IObjectRegistry& registry);
84 void UnRegisterAnys(IObjectRegistry& registry);
85 void RegisterEngineTypes(IObjectRegistry& registry);
86 void UnRegisterEngineTypes(IObjectRegistry& registry);
87 } // namespace Internal
88 
GetInterface(const BASE_NS::Uid & uid) const89 const CORE_NS::IInterface* MetaObjectLib::GetInterface(const BASE_NS::Uid& uid) const
90 {
91     if (uid == IMetaObjectLib::UID) {
92         return this;
93     }
94     if (uid == CORE_NS::IInterface::UID) {
95         return this;
96     }
97     return nullptr;
98 }
99 
GetInterface(const BASE_NS::Uid & uid)100 CORE_NS::IInterface* MetaObjectLib::GetInterface(const BASE_NS::Uid& uid)
101 {
102     const auto* p = this;
103     return const_cast<CORE_NS::IInterface*>(p->MetaObjectLib::GetInterface(uid));
104 }
105 
MetaObjectLib()106 MetaObjectLib::MetaObjectLib()
107     : sapi_ { { CreateMutex, DestroyMutex, LockMutex, UnlockMutex }, GetThreadId }
108 {
109     if (USE_IN_PLACE_MUTEX) {
110         CORE_LOG_D("Using in-place mutex");
111     } else {
112         CORE_LOG_D("Not using in-place mutex");
113     }
114 }
115 
Initialize()116 void MetaObjectLib::Initialize()
117 {
118     registry_ = new ObjectRegistry;
119     Internal::RegisterAnys(*registry_);
120     Internal::RegisterEntities(*registry_);
121     Internal::RegisterValueSerializers(*registry_);
122     Internal::RegisterEngineTypes(*registry_);
123 }
124 
Uninitialize()125 void MetaObjectLib::Uninitialize()
126 {
127     Internal::UnRegisterEngineTypes(*registry_);
128     Internal::UnRegisterValueSerializers(*registry_);
129     Internal::UnRegisterEntities(*registry_);
130     Internal::UnRegisterAnys(*registry_);
131 }
132 
~MetaObjectLib()133 MetaObjectLib::~MetaObjectLib()
134 {
135     animationController_.reset();
136     registry_->Purge();
137     delete registry_;
138 }
139 
GetObjectRegistry() const140 IObjectRegistry& MetaObjectLib::GetObjectRegistry() const
141 {
142     return *registry_;
143 }
144 
GetTaskQueueRegistry() const145 ITaskQueueRegistry& MetaObjectLib::GetTaskQueueRegistry() const
146 {
147     return *static_cast<ITaskQueueRegistry*>(registry_);
148 }
149 
GetAnimationController() const150 IAnimationController::Ptr MetaObjectLib::GetAnimationController() const
151 {
152     std::call_once(animInit_, [&] {
153         auto iregistry = static_cast<IObjectRegistry*>(registry_);
154         animationController_ = iregistry->Create<IAnimationController>(ClassId::AnimationController);
155     });
156     return animationController_;
157 }
158 
GetSyncApi() const159 const CORE_NS::SyncApi& MetaObjectLib::GetSyncApi() const
160 {
161     return sapi_;
162 }
163 
164 META_END_NAMESPACE()
165