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 #ifndef META_EXT_OBJECT_H
17 #define META_EXT_OBJECT_H
18
19 #include <base/util/uid_util.h>
20
21 #include <meta/base/interface_macros.h>
22 #include <meta/base/namespace.h>
23 #include <meta/base/types.h>
24 #include <meta/ext/implementation_macros.h>
25 #include <meta/ext/metadata_helpers.h>
26 #include <meta/ext/object_factory.h>
27 #include <meta/interface/interface_helpers.h>
28 #include <meta/interface/intf_attachment.h>
29 #include <meta/interface/intf_container_query.h>
30 #include <meta/interface/intf_derived.h>
31 #include <meta/interface/intf_lifecycle.h>
32 #include <meta/interface/intf_metadata.h>
33 #include <meta/interface/intf_object.h>
34 #include <meta/interface/intf_object_context.h>
35 #include <meta/interface/intf_object_flags.h>
36 #include <meta/interface/intf_object_registry.h>
37 #include <meta/interface/property/intf_property.h>
38 #include <meta/interface/static_object_metadata.h>
39
40 #include "object_factory.h"
41
META_BEGIN_NAMESPACE()42 META_BEGIN_NAMESPACE()
43 namespace Internal {
44 // dummy pure virtual to shutup compiler warnings
45 class DummyGetObjectRegistry {
46 virtual META_NS::IObjectRegistry& GetObjectRegistry() = 0;
47 };
48 } // namespace Internal
49
50 /**
51 * @brief A helper template class for implementing a class which implements a basic set of object interfaces.
52 * @note Usually when inheriting from this template directly SuperClassInfo should be META_NS::ClassId::BaseObject.
53 */
54 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, const META_NS::ClassInfo& SuperClassInfo,
55 class... Interfaces>
56 class BaseObjectFwd : public IntroduceInterfaces<IObjectInstance, IObjectFlags, IDerived, ILifecycle, Interfaces...>,
57 private Internal::DummyGetObjectRegistry {
58 using Fwd = BaseObjectFwd;
59 using Super = IntroduceInterfaces<IObjectInstance, IObjectFlags, IDerived, ILifecycle, Interfaces...>;
60
61 public:
62 // using declaration doesn't work with vc, still thinks the function access is protected
GetInterface(const BASE_NS::Uid & uid)63 CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) override
64 {
65 return Super::GetInterface(uid);
66 }
GetInterface(const BASE_NS::Uid & uid)67 const CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) const override
68 {
69 return Super::GetInterface(uid);
70 }
71 template<typename Type>
GetInterface()72 constexpr Type* GetInterface() noexcept
73 {
74 return static_cast<Type*>(Super::StaticGetInterface(Type::UID));
75 }
76 template<typename Type>
GetInterface()77 constexpr const Type* GetInterface() const noexcept
78 {
79 auto* me = const_cast<BaseObjectFwd*>(this);
80 return static_cast<const Type*>(me->StaticGetInterface(Type::UID));
81 }
82
83 public:
META_DEFINE_OBJECT_TYPE_INFO(FinalClass,ClassInfo)84 META_DEFINE_OBJECT_TYPE_INFO(FinalClass, ClassInfo)
85
86 public:
87 META_NS::IObjectRegistry& GetObjectRegistry() override
88 {
89 return META_NS::GetObjectRegistry();
90 }
91
GetStaticObjectMetadata()92 static const StaticObjectMetadata& GetStaticObjectMetadata()
93 {
94 return StaticObjectMeta();
95 }
96
97 public: // IObject
GetClassName()98 BASE_NS::string_view GetClassName() const override
99 {
100 return ClassInfo.Name();
101 }
GetInstanceId()102 InstanceId GetInstanceId() const override
103 {
104 return object_->GetInstanceId();
105 }
GetClassId()106 ObjectId GetClassId() const override
107 {
108 return ClassInfo.Id();
109 }
GetName()110 BASE_NS::string GetName() const override
111 {
112 return object_->GetName();
113 }
Resolve(const RefUri & uri)114 IObject::Ptr Resolve(const RefUri& uri) const override
115 {
116 return object_->Resolve(uri);
117 }
118 template<typename Interface>
Resolve(const RefUri & uri)119 typename Interface::Ptr Resolve(const RefUri& uri) const
120 {
121 return interface_pointer_cast<Interface>(object_->Resolve(uri));
122 }
GetSelf()123 IObject::Ptr GetSelf() const override
124 {
125 return object_ ? object_->GetSelf() : nullptr;
126 }
127 template<typename Interface>
GetSelf()128 typename Interface::Ptr GetSelf() const
129 {
130 return interface_pointer_cast<Interface>(GetSelf());
131 }
GetInterfaces()132 BASE_NS::vector<BASE_NS::Uid> GetInterfaces() const override
133 {
134 return GetStaticInterfaces();
135 }
136
GetStaticInterfaces()137 static BASE_NS::vector<BASE_NS::Uid> GetStaticInterfaces()
138 {
139 return Super::GetInterfacesVector();
140 }
141
142 public: // IObjectFlags
GetObjectFlags()143 ObjectFlagBitsValue GetObjectFlags() const override
144 {
145 if (auto flags = interface_cast<IObjectFlags>(object_)) {
146 return flags->GetObjectFlags();
147 }
148 return {};
149 }
SetObjectFlags(const ObjectFlagBitsValue & value)150 void SetObjectFlags(const ObjectFlagBitsValue& value) override
151 {
152 if (auto flags = interface_cast<IObjectFlags>(object_)) {
153 flags->SetObjectFlags(value);
154 }
155 }
GetObjectDefaultFlags()156 ObjectFlagBitsValue GetObjectDefaultFlags() const override
157 {
158 if (auto flags = interface_cast<IObjectFlags>(object_)) {
159 return flags->GetObjectDefaultFlags();
160 }
161 return {};
162 }
163
164 protected: // ILifecycle
Build(const IMetadata::Ptr & data)165 bool Build(const IMetadata::Ptr& data) override
166 {
167 #ifdef _DEBUG
168 // Object registry calls this
169 if (buildCalled_) {
170 CORE_LOG_E("Do not call Build explicitly from derived class!");
171 }
172 buildCalled_ = true;
173 #endif
174 return true;
175 }
176
SetInstanceId(InstanceId uid)177 void SetInstanceId(InstanceId uid) override
178 {
179 // Object registry does this
180 }
Destroy()181 void Destroy() override
182 {
183 if (auto builder = interface_cast<META_NS::ILifecycle>(object_)) {
184 builder->Destroy();
185 }
186 }
187
188 protected: // IDerived
SetSuperInstance(const META_NS::IObject::Ptr &,const META_NS::IObject::Ptr & super)189 void SetSuperInstance(const META_NS::IObject::Ptr& /*aggr*/, const META_NS::IObject::Ptr& super) override
190 {
191 #ifdef _DEBUG
192 // Object registry calls this
193 if (object_) {
194 CORE_LOG_E("Do not call SetSuperInstance explicitly from derived class!");
195 }
196 #endif
197 if (IsFirstInit()) {
198 if (auto i = interface_cast<IMetadataInternal>(super)) {
199 StaticObjectMeta().baseclass = &i->GetStaticMetadata();
200 }
201 }
202
203 object_ = interface_pointer_cast<IObjectInstance>(super); // Save the strong reference to super.
204 }
GetSuperClassUid()205 BASE_NS::Uid GetSuperClassUid() const override
206 {
207 return SuperClassInfo.Id().ToUid();
208 }
209
210 protected:
IsFirstInit()211 bool IsFirstInit()
212 {
213 static bool init = (isFirstInit_ = true);
214 return isFirstInit_;
215 }
216
217 template<typename Type>
RegisterStaticPropertyMetadata(const META_NS::InterfaceInfo & intf,BASE_NS::string_view name,ObjectFlagBitsValue flags,Internal::PCtor * ctor,Internal::PMemberInit * init)218 nullptr_t RegisterStaticPropertyMetadata(const META_NS::InterfaceInfo& intf, BASE_NS::string_view name,
219 ObjectFlagBitsValue flags, Internal::PCtor* ctor, Internal::PMemberInit* init)
220 {
221 if (IsFirstInit()) {
222 StaticObjectMeta().properties.push_back(
223 PropertyMetadata { name, intf, flags, UidFromType<Type>(), ctor, init });
224 }
225 return nullptr;
226 }
227
228 template<typename Type>
RegisterStaticEventMetadata(const META_NS::InterfaceInfo & intf,BASE_NS::string_view name,Internal::ECtor * ctor,Internal::EMemberInit * init)229 nullptr_t RegisterStaticEventMetadata(const META_NS::InterfaceInfo& intf, BASE_NS::string_view name,
230 Internal::ECtor* ctor, Internal::EMemberInit* init)
231 {
232 if (IsFirstInit()) {
233 StaticObjectMeta().events.push_back(EventMetadata { name, intf, Type::UID, ctor, init });
234 }
235 return nullptr;
236 }
237
RegisterStaticFunctionMetadata(const META_NS::InterfaceInfo & intf,BASE_NS::string_view name,Internal::FCtor * ctor,Internal::FContext * context)238 nullptr_t RegisterStaticFunctionMetadata(const META_NS::InterfaceInfo& intf, BASE_NS::string_view name,
239 Internal::FCtor* ctor, Internal::FContext* context)
240 {
241 if (IsFirstInit()) {
242 StaticObjectMeta().functions.push_back(FunctionMetadata { name, intf, ctor, context });
243 }
244 return nullptr;
245 }
246
247 protected:
StaticObjectMeta()248 static StaticObjectMetadata& StaticObjectMeta()
249 {
250 static StaticObjectMetadata meta { ClassInfo, nullptr };
251 return meta;
252 }
253
GetBase()254 IObject::Ptr GetBase() const noexcept
255 {
256 return object_;
257 }
258
259 template<typename Type>
GetBaseAs()260 constexpr Type* GetBaseAs()
261 {
262 auto* t = object_->GetInterface<Type>();
263 CORE_ASSERT_MSG(t, "Invalid interface %s for base", BASE_NS::to_string(Type::UID).c_str());
264 return t;
265 }
266 template<typename Type>
GetBaseAs()267 constexpr const Type* GetBaseAs() const
268 {
269 return const_cast<BaseObjectFwd*>(this)->GetBaseAs<Type>();
270 }
271
272 protected:
273 BaseObjectFwd() = default;
274 ~BaseObjectFwd() override = default;
META_NO_COPY_MOVE(BaseObjectFwd)275 META_NO_COPY_MOVE(BaseObjectFwd)
276
277 private:
278 bool isFirstInit_ {};
279 IObjectInstance::Ptr object_;
280 #ifdef _DEBUG
281 bool buildCalled_ {};
282 #endif
283 };
284
285 /**
286 * @brief A helper macro for classes deriving from BaseObjectFwd. Makes a forwarder for an interface
287 * property implemented by the super class.
288 */
289 #define META_EXT_BASE_READONLY_PROPERTY(Interface, Type, Name) \
290 META_FORWARD_READONLY_PROPERTY(Type, Name, Super::template GetBaseAs<Interface>()->Name())
291
292 /**
293 * @brief A helper macro for classes deriving from BaseObjectFwd. Makes a forwarder for an interface
294 * property defined by the super class.
295 */
296 #define META_EXT_BASE_PROPERTY(Interface, Type, Name) \
297 META_FORWARD_PROPERTY(Type, Name, Super::template GetBaseAs<Interface>()->Name())
298
299 /**
300 * @brief A helper macro for classes deriving from BaseObjectFwd. Calls a method through an interface defined
301 * by the super class.
302 */
303 #define META_EXT_CALL_BASE(Interface, Function) Super::template GetBaseAs<Interface>()->Function
304
305 /**
306 * @brief A helper template class for implementing a class which implements a basic set of object interfaces with
307 * the addition of Metadata related interfaces.
308 * @note Usually when inheriting from this template directly SuperClassInfo should be META_NS::ClassId::MetaObject.
309 */
310 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, const META_NS::ClassInfo& SuperClassInfo,
311 class... Interfaces>
312 class MetaObjectFwd : public BaseObjectFwd<FinalClass, ClassInfo, SuperClassInfo, IMetadata, IMetadataInternal,
313 IObjectContextProvider, Interfaces...> {
314 using Super = BaseObjectFwd<FinalClass, ClassInfo, SuperClassInfo, IMetadata, IMetadataInternal,
315 IObjectContextProvider, Interfaces...>;
316
317 protected: // IMetadata
GetPropertyContainer()318 IContainer::Ptr GetPropertyContainer() override
319 {
320 return meta_->GetPropertyContainer();
321 }
322
GetPropertyContainer()323 IContainer::ConstPtr GetPropertyContainer() const override
324 {
325 return meta_->GetPropertyContainer();
326 }
327
328 protected:
CloneMetadata()329 IMetadata::Ptr CloneMetadata() const override
330 {
331 return meta_->CloneMetadata();
332 }
AddProperty(const IProperty::Ptr & p)333 void AddProperty(const IProperty::Ptr& p) override
334 {
335 auto self = Super::GetSelf();
336 if (self) {
337 if (auto pp = interface_pointer_cast<IPropertyInternal>(p)) {
338 pp->SetOwner(self);
339 }
340 }
341 meta_->AddProperty(p);
342 }
RemoveProperty(const IProperty::Ptr & p)343 void RemoveProperty(const IProperty::Ptr& p) override
344 {
345 meta_->RemoveProperty(p);
346 }
AddFunction(const IFunction::Ptr & p)347 void AddFunction(const IFunction::Ptr& p) override
348 {
349 meta_->AddFunction(p);
350 }
RemoveFunction(const IFunction::Ptr & p)351 void RemoveFunction(const IFunction::Ptr& p) override
352 {
353 meta_->RemoveFunction(p);
354 }
AddEvent(const IEvent::Ptr & p)355 void AddEvent(const IEvent::Ptr& p) override
356 {
357 meta_->AddEvent(p);
358 }
RemoveEvent(const IEvent::Ptr & p)359 void RemoveEvent(const IEvent::Ptr& p) override
360 {
361 meta_->RemoveEvent(p);
362 }
SetProperties(const BASE_NS::vector<IProperty::Ptr> & vec)363 void SetProperties(const BASE_NS::vector<IProperty::Ptr>& vec) override
364 {
365 meta_->SetProperties(vec);
366 }
Merge(const IMetadata::Ptr & data)367 void Merge(const IMetadata::Ptr& data) override
368 {
369 meta_->Merge(data);
370 }
GetAllProperties()371 BASE_NS::vector<META_NS::IProperty::Ptr> GetAllProperties() override
372 {
373 return meta_->GetAllProperties();
374 }
GetAllProperties()375 BASE_NS::vector<META_NS::IProperty::ConstPtr> GetAllProperties() const override
376 {
377 return static_cast<const IMetadata*>(meta_.get())->GetAllProperties();
378 }
GetAllFunctions()379 BASE_NS::vector<IFunction::Ptr> GetAllFunctions() override
380 {
381 return meta_->GetAllFunctions();
382 }
GetAllFunctions()383 BASE_NS::vector<IFunction::ConstPtr> GetAllFunctions() const override
384 {
385 return static_cast<const IMetadata*>(meta_.get())->GetAllFunctions();
386 }
GetAllEvents()387 BASE_NS::vector<IEvent::Ptr> GetAllEvents() override
388 {
389 return meta_->GetAllEvents();
390 }
GetAllEvents()391 BASE_NS::vector<IEvent::ConstPtr> GetAllEvents() const override
392 {
393 return static_cast<const IMetadata*>(meta_.get())->GetAllEvents();
394 }
395
GetPropertyByName(BASE_NS::string_view name)396 IProperty::Ptr GetPropertyByName(BASE_NS::string_view name) override
397 {
398 return meta_->GetPropertyByName(name);
399 }
GetPropertyByName(BASE_NS::string_view name)400 IProperty::ConstPtr GetPropertyByName(BASE_NS::string_view name) const override
401 {
402 return meta_->GetPropertyByName(name);
403 }
404
GetFunctionByName(BASE_NS::string_view name)405 IFunction::ConstPtr GetFunctionByName(BASE_NS::string_view name) const override
406 {
407 return meta_->GetFunctionByName(name);
408 }
GetFunctionByName(BASE_NS::string_view name)409 IFunction::Ptr GetFunctionByName(BASE_NS::string_view name) override
410 {
411 return meta_->GetFunctionByName(name);
412 }
GetEventByName(BASE_NS::string_view name)413 IEvent::ConstPtr GetEventByName(BASE_NS::string_view name) const override
414 {
415 return meta_->GetEventByName(name);
416 }
GetEventByName(BASE_NS::string_view name)417 IEvent::Ptr GetEventByName(BASE_NS::string_view name) override
418 {
419 return meta_->GetEventByName(name);
420 }
421
422 protected: // IMetadataInternal
SetMetadata(const IMetadata::Ptr & meta)423 void SetMetadata(const IMetadata::Ptr& meta) override
424 {
425 meta_ = meta;
426 ConstructPropertiesFromMetadata(this, FinalClass::StaticObjectMeta(), meta);
427 ConstructEventsFromMetadata(this, FinalClass::StaticObjectMeta(), meta);
428 ConstructFunctionsFromMetadata(this, FinalClass::StaticObjectMeta(), meta);
429 }
430
GetMetadata()431 IMetadata::Ptr GetMetadata() const override
432 {
433 return meta_;
434 }
435
GetStaticMetadata()436 const StaticObjectMetadata& GetStaticMetadata() const override
437 {
438 return FinalClass::GetStaticObjectMetadata();
439 }
440
441 protected: // IObjectContextProvider
META_EXT_BASE_PROPERTY(IObjectContextProvider,IObjectContext::Ptr,ObjectContext)442 META_EXT_BASE_PROPERTY(IObjectContextProvider, IObjectContext::Ptr, ObjectContext)
443 void ResetObjectContext() override
444 {
445 META_EXT_CALL_BASE(IObjectContextProvider, ResetObjectContext());
446 }
447
448 protected:
449 MetaObjectFwd() = default;
450 ~MetaObjectFwd() override = default;
451 META_NO_COPY_MOVE(MetaObjectFwd)
452
453 private:
454 IMetadata::Ptr meta_;
455 };
456
457 /**
458 * @brief A helper template class for implementing a class which implements the full set of object interfaces.
459 * @note Usually this template should be used as the base class, unless SuperClassInfo is
460 * META_NS::ClassId::BaseObject or META_NS::ClassId::MetaObject.
461 */
462 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, const META_NS::ClassInfo& SuperClassInfo,
463 class... Interfaces>
464 class ObjectFwd : public MetaObjectFwd<FinalClass, ClassInfo, SuperClassInfo, IAttach, IContainerQuery, Interfaces...> {
465 using Super = MetaObjectFwd<FinalClass, ClassInfo, SuperClassInfo, IAttach, IContainerQuery, Interfaces...>;
466
467 public:
GetObjectRegistry()468 META_NS::IObjectRegistry& GetObjectRegistry() override
469 {
470 if (auto context = Super::ObjectContext()->GetValue()) {
471 return context->GetObjectRegistry();
472 }
473 return Super::GetObjectRegistry();
474 }
475
476 protected: // IAttach
Attach(const IObject::Ptr & attachment,const IObject::Ptr & dataContext)477 bool Attach(const IObject::Ptr& attachment, const IObject::Ptr& dataContext) override
478 {
479 return META_EXT_CALL_BASE(IAttach, Attach(attachment, dataContext));
480 }
481
Detach(const IObject::Ptr & attachment)482 bool Detach(const IObject::Ptr& attachment) override
483 {
484 return META_EXT_CALL_BASE(IAttach, Detach(attachment));
485 }
GetAttachments(const BASE_NS::vector<TypeId> & uids,bool strict)486 BASE_NS::vector<IObject::Ptr> GetAttachments(const BASE_NS::vector<TypeId>& uids, bool strict) const override
487 {
488 return META_EXT_CALL_BASE(IAttach, GetAttachments(uids, strict));
489 }
HasAttachments()490 bool HasAttachments() const override
491 {
492 return META_EXT_CALL_BASE(IAttach, HasAttachments());
493 }
GetAttachmentContainer(bool initializeAlways)494 IContainer::Ptr GetAttachmentContainer(bool initializeAlways) const override
495 {
496 return META_EXT_CALL_BASE(IAttach, GetAttachmentContainer(initializeAlways));
497 }
498
499 protected: // IContainerQuery
FindAllContainers(const IContainerQuery::ContainerFindOptions & options)500 BASE_NS::vector<IContainer::Ptr> FindAllContainers(
501 const IContainerQuery::ContainerFindOptions& options) const override
502 {
503 return META_EXT_CALL_BASE(IContainerQuery, FindAllContainers(options));
504 }
505
506 protected:
507 ObjectFwd() = default;
508 ~ObjectFwd() override = default;
509 META_NO_COPY_MOVE(ObjectFwd)
510 };
511
512 META_END_NAMESPACE()
513
514 #endif
515