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_INTERFACE_IOBJECT_H
17 #define META_INTERFACE_IOBJECT_H
18 
19 #include <core/plugin/intf_interface.h>
20 
21 #include <meta/base/bit_field.h>
22 #include <meta/base/ids.h>
23 #include <meta/base/meta_types.h>
24 #include <meta/base/namespace.h>
25 #include <meta/base/shared_ptr.h>
26 #include <meta/base/types.h>
27 
28 META_BEGIN_NAMESPACE()
29 
30 class IObjectRegistry;
31 class RefUri;
32 META_REGISTER_INTERFACE(IObject, "50c06aa7-0db7-435b-9c6f-c15cac8ef5c7")
33 
34 /**
35  * @brief The IObject interface defines an object that can contain bindable properties and functions
36  *        within meta object library scope. Such objects also provide a queryable metadata which can
37  *        be used for enumerating all the properties and functions exposed by a given object.
38  *
39  * @note  To implement IObject interface in a custom class, use (Base/Meta)ObjectFwd,
40  *        found in meta/ext/object.h.
41  */
42 class IObject : public CORE_NS::IInterface {
43     META_INTERFACE(CORE_NS::IInterface, IObject)
44 public:
45     /**
46      * @brief Returns the UId of the class which implements this interface.
47      */
48     virtual ObjectId GetClassId() const = 0;
49     /**
50      * @brief Returns the name of the class which implements this interface.
51      */
52     virtual BASE_NS::string_view GetClassName() const = 0;
53     /**
54      * @brief Returns the name of this object, as default this is the instance id.
55      */
56     virtual BASE_NS::string GetName() const = 0;
57     /**
58      * @brief Get uids of interfaces this object implements
59      */
60     virtual BASE_NS::vector<BASE_NS::Uid> GetInterfaces() const = 0;
61     /**
62      * @brief Tries to find the last object the uri points to using this object as base.
63      */
64     IObject::Ptr Resolve(const RefUri& uri) const;
65     /**
66      * @brief Get shared ptr to top most self, notice that this might be different object than "this".
67      * Note: Works by default only for objects constructed via ObjectRegistry
68      */
69     IObject::Ptr GetSelf() const;
70 };
71 
72 class IObjectInstance : public IObject {
73     META_INTERFACE(IObject, IObjectInstance, "c64b029b-1617-449f-8489-d1dd1a3c3227")
74 public:
75     /**
76      * @brief Return the framework assigned instance UID for the object instance.
77      */
78     virtual InstanceId GetInstanceId() const = 0;
79     /**
80      * @brief Tries to find the last object the uri points to using this object as base.
81      */
82     virtual IObject::Ptr Resolve(const RefUri& uri) const = 0;
83 
84     template<typename Interface>
Resolve(const RefUri & uri)85     typename Interface::Ptr Resolve(const RefUri& uri) const
86     {
87         return interface_pointer_cast<Interface>(Resolve(uri));
88     }
89     /**
90      * @brief Get shared ptr to top most self, notice that this might be different object than "this".
91      * Note: Works by default only for objects constructed via ObjectRegistry
92      */
93     virtual IObject::Ptr GetSelf() const = 0;
94 
95     template<typename Interface>
GetSelf()96     typename Interface::Ptr GetSelf() const
97     {
98         return interface_pointer_cast<Interface>(GetSelf());
99     }
100 };
101 
Resolve(const RefUri & uri)102 inline IObject::Ptr IObject::Resolve(const RefUri& uri) const
103 {
104     if (auto oi = GetInterface<IObjectInstance>()) {
105         return oi->Resolve(uri);
106     }
107     CORE_LOG_E("Called Resolve for non-IObjectInstance");
108     return nullptr;
109 }
110 
GetSelf()111 inline IObject::Ptr IObject::GetSelf() const
112 {
113     if (auto oi = GetInterface<IObjectInstance>()) {
114         return oi->GetSelf();
115     }
116     CORE_LOG_E("Called GetSelf for non-IObjectInstance");
117     return nullptr;
118 }
119 
120 template<typename T, typename = BASE_NS::enable_if<IsInterfacePtr_v<T>>>
GetSelf(const T & object)121 IObject::Ptr GetSelf(const T& object)
122 {
123     if (auto o = interface_cast<IObjectInstance>(object)) {
124         return o->GetSelf();
125     }
126     return nullptr;
127 }
128 
129 template<typename Intf, typename T, typename = BASE_NS::enable_if<IsInterfacePtr_v<T>>>
GetSelf(const T & object)130 typename Intf::Ptr GetSelf(const T& object)
131 {
132     if (auto o = interface_cast<IObjectInstance>(object)) {
133         return o->template GetSelf<Intf>();
134     }
135     return nullptr;
136 }
137 
138 template<typename T, typename = BASE_NS::enable_if<IsInterfacePtr_v<T>>>
Resolve(const T & object,const RefUri & uri)139 IObject::Ptr Resolve(const T& object, const RefUri& uri)
140 {
141     if (auto o = interface_cast<IObjectInstance>(object)) {
142         return o->Resolve(uri);
143     }
144     return nullptr;
145 }
146 
147 template<typename Intf, typename T, typename = BASE_NS::enable_if<IsInterfacePtr_v<T>>>
Resolve(const T & object,const RefUri & uri)148 typename Intf::Ptr Resolve(const T& object, const RefUri& uri)
149 {
150     if (auto o = interface_cast<IObjectInstance>(object)) {
151         return o->template Resolve<Intf>(uri);
152     }
153     return nullptr;
154 }
155 
156 META_INTERFACE_TYPE(IObject);
157 META_INTERFACE_TYPE(IObjectInstance);
158 
159 META_END_NAMESPACE()
160 
161 #endif
162