• 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 #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 using "aggregate inheritance" which implements a basic set of object
41  * interfaces.
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