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 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 63 CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) override 64 { 65 return Super::GetInterface(uid); 66 } 67 const CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) const override 68 { 69 return Super::GetInterface(uid); 70 } 71 template<typename Type> 72 constexpr Type* GetInterface() noexcept 73 { 74 return static_cast<Type*>(Super::StaticGetInterface(Type::UID)); 75 } 76 template<typename Type> 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: 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 98 BASE_NS::string_view GetClassName() const override 99 { 100 return ClassInfo.Name(); 101 } 102 InstanceId GetInstanceId() const override 103 { 104 return object_->GetInstanceId(); 105 } 106 ObjectId GetClassId() const override 107 { 108 return ClassInfo.Id(); 109 } 110 BASE_NS::string GetName() const override 111 { 112 return object_->GetName(); 113 } 114 IObject::Ptr Resolve(const RefUri& uri) const override 115 { 116 return object_->Resolve(uri); 117 } 118 template<typename Interface> Resolve(const RefUri& uri) const119 typename Interface::Ptr Resolve(const RefUri& uri) const 120 { 121 return interface_pointer_cast<Interface>(object_->Resolve(uri)); 122 } 123 IObject::Ptr GetSelf() const override 124 { 125 return object_ ? object_->GetSelf() : nullptr; 126 } 127 template<typename Interface> GetSelf() const128 typename Interface::Ptr GetSelf() const 129 { 130 return interface_pointer_cast<Interface>(GetSelf()); 131 } 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 143 ObjectFlagBitsValue GetObjectFlags() const override 144 { 145 if (auto flags = interface_cast<IObjectFlags>(object_)) { 146 return flags->GetObjectFlags(); 147 } 148 return {}; 149 } 150 void SetObjectFlags(const ObjectFlagBitsValue& value) override 151 { 152 if (auto flags = interface_cast<IObjectFlags>(object_)) { 153 flags->SetObjectFlags(value); 154 } 155 } 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 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 177 void SetInstanceId(InstanceId uid) override 178 { 179 // Object registry does this 180 } 181 void Destroy() override 182 { 183 if (auto builder = interface_cast<META_NS::ILifecycle>(object_)) { 184 builder->Destroy(); 185 } 186 } 187 188 protected: // IDerived 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 } 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 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() const267 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; 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 318 IContainer::Ptr GetPropertyContainer() override 319 { 320 return meta_->GetPropertyContainer(); 321 } 322 323 IContainer::ConstPtr GetPropertyContainer() const override 324 { 325 return meta_->GetPropertyContainer(); 326 } 327 328 protected: 329 IMetadata::Ptr CloneMetadata() const override 330 { 331 return meta_->CloneMetadata(); 332 } 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 } 343 void RemoveProperty(const IProperty::Ptr& p) override 344 { 345 meta_->RemoveProperty(p); 346 } 347 void AddFunction(const IFunction::Ptr& p) override 348 { 349 meta_->AddFunction(p); 350 } 351 void RemoveFunction(const IFunction::Ptr& p) override 352 { 353 meta_->RemoveFunction(p); 354 } 355 void AddEvent(const IEvent::Ptr& p) override 356 { 357 meta_->AddEvent(p); 358 } 359 void RemoveEvent(const IEvent::Ptr& p) override 360 { 361 meta_->RemoveEvent(p); 362 } 363 void SetProperties(const BASE_NS::vector<IProperty::Ptr>& vec) override 364 { 365 meta_->SetProperties(vec); 366 } 367 void Merge(const IMetadata::Ptr& data) override 368 { 369 meta_->Merge(data); 370 } 371 BASE_NS::vector<META_NS::IProperty::Ptr> GetAllProperties() override 372 { 373 return meta_->GetAllProperties(); 374 } 375 BASE_NS::vector<META_NS::IProperty::ConstPtr> GetAllProperties() const override 376 { 377 return static_cast<const IMetadata*>(meta_.get())->GetAllProperties(); 378 } 379 BASE_NS::vector<IFunction::Ptr> GetAllFunctions() override 380 { 381 return meta_->GetAllFunctions(); 382 } 383 BASE_NS::vector<IFunction::ConstPtr> GetAllFunctions() const override 384 { 385 return static_cast<const IMetadata*>(meta_.get())->GetAllFunctions(); 386 } 387 BASE_NS::vector<IEvent::Ptr> GetAllEvents() override 388 { 389 return meta_->GetAllEvents(); 390 } 391 BASE_NS::vector<IEvent::ConstPtr> GetAllEvents() const override 392 { 393 return static_cast<const IMetadata*>(meta_.get())->GetAllEvents(); 394 } 395 396 IProperty::Ptr GetPropertyByName(BASE_NS::string_view name) override 397 { 398 return meta_->GetPropertyByName(name); 399 } 400 IProperty::ConstPtr GetPropertyByName(BASE_NS::string_view name) const override 401 { 402 return meta_->GetPropertyByName(name); 403 } 404 405 IFunction::ConstPtr GetFunctionByName(BASE_NS::string_view name) const override 406 { 407 return meta_->GetFunctionByName(name); 408 } 409 IFunction::Ptr GetFunctionByName(BASE_NS::string_view name) override 410 { 411 return meta_->GetFunctionByName(name); 412 } 413 IEvent::ConstPtr GetEventByName(BASE_NS::string_view name) const override 414 { 415 return meta_->GetEventByName(name); 416 } 417 IEvent::Ptr GetEventByName(BASE_NS::string_view name) override 418 { 419 return meta_->GetEventByName(name); 420 } 421 422 protected: // IMetadataInternal 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 431 IMetadata::Ptr GetMetadata() const override 432 { 433 return meta_; 434 } 435 436 const StaticObjectMetadata& GetStaticMetadata() const override 437 { 438 return FinalClass::GetStaticObjectMetadata(); 439 } 440 441 protected: // IObjectContextProvider 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: 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 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 482 bool Detach(const IObject::Ptr& attachment) override 483 { 484 return META_EXT_CALL_BASE(IAttach, Detach(attachment)); 485 } 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 } 490 bool HasAttachments() const override 491 { 492 return META_EXT_CALL_BASE(IAttach, HasAttachments()); 493 } 494 IContainer::Ptr GetAttachmentContainer(bool initializeAlways) const override 495 { 496 return META_EXT_CALL_BASE(IAttach, GetAttachmentContainer(initializeAlways)); 497 } 498 499 protected: // IContainerQuery 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