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_BASE_OBJECT_FWD_H
17 #define META_EXT_BASE_OBJECT_FWD_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/object_factory.h>
26 #include <meta/interface/builtin_objects.h>
27 #include <meta/interface/interface_helpers.h>
28 #include <meta/interface/intf_derived.h>
29 #include <meta/interface/intf_lifecycle.h>
30 #include <meta/interface/intf_metadata.h>
31 #include <meta/interface/intf_object.h>
32 #include <meta/interface/intf_object_context.h>
33 #include <meta/interface/intf_object_flags.h>
34 #include <meta/interface/intf_object_registry.h>
35
36 #include "object_factory.h"
37
META_BEGIN_NAMESPACE()38 META_BEGIN_NAMESPACE()
39 /**
40 * @brief A helper class for implementing a class which implements a basic set of object interfaces.
41 * @note Usually when inheriting from this template directly SuperClassInfo should be META_NS::ClassId::BaseObject.
42 */
43 class BaseObjectFwd : public IntroduceInterfaces<IObjectInstance, IObjectFlags, IDerived, ILifecycle, IStaticMetadata> {
44 using Super = IntroduceInterfaces<IObjectInstance, IObjectFlags, IDerived, ILifecycle, IStaticMetadata>;
45
46 public:
47 inline static const nullptr_t STATIC_METADATA {};
48 static const StaticObjectMetadata* StaticMetadata()
49 {
50 static const META_NS::StaticObjectMetadata objdata { nullptr, nullptr,
51 META_NS::GetAggregateMetadata(ClassId::BaseObject), nullptr, 0 };
52 return &objdata;
53 }
54 const StaticObjectMetadata* GetStaticMetadata() const override
55 {
56 return StaticMetadata();
57 }
58
59 public:
60 // using declaration doesn't work with vc, still thinks the function access is protected
61 CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) override
62 {
63 return Super::GetInterface(uid);
64 }
65 const CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) const override
66 {
67 return Super::GetInterface(uid);
68 }
69 template<typename Type>
70 constexpr Type* GetInterface() noexcept
71 {
72 return static_cast<Type*>(Super::StaticGetInterface(Type::UID));
73 }
74 template<typename Type>
75 constexpr const Type* GetInterface() const noexcept
76 {
77 auto* me = const_cast<BaseObjectFwd*>(this);
78 return static_cast<const Type*>(me->StaticGetInterface(Type::UID));
79 }
80
81 public: // IObject
82 InstanceId GetInstanceId() const override
83 {
84 return object_->GetInstanceId();
85 }
86 BASE_NS::string GetName() const override
87 {
88 return object_->GetName();
89 }
90 IObject::Ptr Resolve(const RefUri& uri) const override
91 {
92 return object_->Resolve(uri);
93 }
94 template<typename Interface>
95 typename Interface::Ptr Resolve(const RefUri& uri) const
96 {
97 return interface_pointer_cast<Interface>(object_->Resolve(uri));
98 }
99 IObject::Ptr GetSelf() const override
100 {
101 return object_ ? object_->GetSelf() : nullptr;
102 }
103 template<typename Interface>
104 typename Interface::Ptr GetSelf() const
105 {
106 return interface_pointer_cast<Interface>(GetSelf());
107 }
108 BASE_NS::vector<BASE_NS::Uid> GetInterfaces() const override
109 {
110 return GetStaticInterfaces();
111 }
112
113 static BASE_NS::vector<BASE_NS::Uid> GetStaticInterfaces()
114 {
115 return Super::GetInterfacesVector();
116 }
117
118 public: // IObjectFlags
119 ObjectFlagBitsValue GetObjectFlags() const override
120 {
121 if (auto flags = interface_cast<IObjectFlags>(object_)) {
122 return flags->GetObjectFlags();
123 }
124 return {};
125 }
126 void SetObjectFlags(const ObjectFlagBitsValue& value) override
127 {
128 if (auto flags = interface_cast<IObjectFlags>(object_)) {
129 flags->SetObjectFlags(value);
130 }
131 }
132 ObjectFlagBitsValue GetObjectDefaultFlags() const override
133 {
134 if (auto flags = interface_cast<IObjectFlags>(object_)) {
135 return flags->GetObjectDefaultFlags();
136 }
137 return {};
138 }
139
140 protected: // ILifecycle
141 bool Build(const IMetadata::Ptr& data) override
142 {
143 #ifdef _DEBUG
144 // Object registry calls this
145 if (buildCalled_) {
146 CORE_LOG_E("Do not call Build explicitly from derived class!");
147 }
148 buildCalled_ = true;
149 #endif
150 return true;
151 }
152
153 void SetInstanceId(InstanceId uid) override
154 {
155 // Object registry does this
156 }
157 void Destroy() override
158 {
159 if (auto builder = interface_cast<META_NS::ILifecycle>(object_)) {
160 builder->Destroy();
161 }
162 }
163
164 protected: // IDerived
165 void SetSuperInstance(const META_NS::IObject::Ptr& /*aggr*/, const META_NS::IObject::Ptr& super) override
166 {
167 #ifdef _DEBUG
168 // Object registry calls this
169 if (object_) {
170 CORE_LOG_E("Do not call SetSuperInstance explicitly from derived class!");
171 }
172 #endif
173 object_ = interface_pointer_cast<IObjectInstance>(super); // Save the strong reference to super.
174 assert(object_);
175 }
176
177 protected:
178 IObject::Ptr GetBase() const noexcept
179 {
180 return object_;
181 }
182
183 template<typename Type>
184 constexpr Type* GetBaseAs()
185 {
186 auto* t = object_->GetInterface<Type>();
187 CORE_ASSERT_MSG(t, "Invalid interface %s for base", BASE_NS::to_string(Type::UID).c_str());
188 return t;
189 }
190 template<typename Type>
191 constexpr const Type* GetBaseAs() const
192 {
193 return const_cast<BaseObjectFwd*>(this)->GetBaseAs<Type>();
194 }
195
196 protected:
197 BaseObjectFwd() = default;
198 ~BaseObjectFwd() override = default;
199 META_NO_COPY_MOVE(BaseObjectFwd)
200
201 private:
202 IObjectInstance::Ptr object_;
203 #ifdef _DEBUG
204 bool buildCalled_ {};
205 #endif
206 };
207
208 META_END_NAMESPACE()
209
210 #endif
211