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_IMETADATA_H
17 #define META_INTERFACE_IMETADATA_H
18
19 #include <base/containers/array_view.h>
20 #include <base/containers/string_view.h>
21 #include <base/containers/vector.h>
22 #include <core/plugin/intf_interface.h>
23
24 #include <meta/api/util.h>
25 #include <meta/base/namespace.h>
26 #include <meta/base/types.h>
27 #include <meta/interface/interface_macros.h>
28 #include <meta/interface/intf_callable.h>
29 #include <meta/interface/intf_container.h>
30 #include <meta/interface/intf_function.h>
31 #include <meta/interface/intf_static_metadata.h>
32 #include <meta/interface/metadata_query.h>
33 #include <meta/interface/property/intf_property.h>
34 #include <meta/interface/static_object_metadata.h>
35
36 META_BEGIN_NAMESPACE()
37
38 META_REGISTER_INTERFACE(IMetadata, "5ad7917a-e744-48bb-b789-9446d3712cf9")
39
40 struct MetadataInfo {
41 MetadataType type {};
42 BASE_NS::string name;
43 TypeId propertyType;
44 };
45
46 inline bool operator==(const MetadataInfo& l, const MetadataInfo& r)
47 {
48 return l.type == r.type && l.name == r.name;
49 }
50 inline bool operator!=(const MetadataInfo& l, const MetadataInfo& r)
51 {
52 return !(l == r);
53 }
54
55 /**
56 * @brief The IMetadata interface defines a queryable metadata interface for retrieving object properties and functions.
57 */
58 class IMetadata : public CORE_NS::IInterface {
59 META_INTERFACE(CORE_NS::IInterface, IMetadata)
60 public:
61 /**
62 * @brief Returns all properties explicitly added or instantiated from static metadata
63 */
64 virtual BASE_NS::vector<IProperty::Ptr> GetProperties() = 0;
65 virtual BASE_NS::vector<IProperty::ConstPtr> GetProperties() const = 0;
66 /**
67 * @brief Returns all functions explicitly added or instantiated from static metadata
68 */
69 virtual BASE_NS::vector<IFunction::Ptr> GetFunctions() = 0;
70 virtual BASE_NS::vector<IFunction::ConstPtr> GetFunctions() const = 0;
71 /**
72 * @brief Returns all events explicitly added or instantiated from static metadata
73 */
74 virtual BASE_NS::vector<IEvent::Ptr> GetEvents() = 0;
75 virtual BASE_NS::vector<IEvent::ConstPtr> GetEvents() const = 0;
76
77 virtual BASE_NS::vector<MetadataInfo> GetAllMetadatas(MetadataType types) const = 0;
78
79 /**
80 * @brief Returns the property with a given name.
81 * @param name Name of the property to retrieve.
82 * @return The property or nullptr if such property does not exist.
83 */
84 virtual IProperty::Ptr GetProperty(BASE_NS::string_view name, MetadataQuery) = 0;
GetProperty(BASE_NS::string_view name)85 IProperty::Ptr GetProperty(BASE_NS::string_view name)
86 {
87 return GetProperty(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
88 }
89 virtual IProperty::ConstPtr GetProperty(BASE_NS::string_view name, MetadataQuery) const = 0;
GetProperty(BASE_NS::string_view name)90 IProperty::ConstPtr GetProperty(BASE_NS::string_view name) const
91 {
92 return GetProperty(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
93 }
94 /**
95 * @brief Returns the function with a given name
96 * @param name Name of the function to retrieve.
97 * @return The function or nullptr if such function does not exist.
98 */
99 virtual IFunction::Ptr GetFunction(BASE_NS::string_view name, MetadataQuery) = 0;
GetFunction(BASE_NS::string_view name)100 IFunction::Ptr GetFunction(BASE_NS::string_view name)
101 {
102 return GetFunction(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
103 }
104 virtual IFunction::ConstPtr GetFunction(BASE_NS::string_view name, MetadataQuery) const = 0;
GetFunction(BASE_NS::string_view name)105 IFunction::ConstPtr GetFunction(BASE_NS::string_view name) const
106 {
107 return GetFunction(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
108 }
109
110 /**
111 * @brief Returns the event with a given name
112 * @param name Name of the event to retrieve.
113 * @return The event or nullptr if such event does not exist.
114 */
115 virtual IEvent::Ptr GetEvent(BASE_NS::string_view name, MetadataQuery) = 0;
GetEvent(BASE_NS::string_view name)116 IEvent::Ptr GetEvent(BASE_NS::string_view name)
117 {
118 return GetEvent(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
119 }
120 virtual IEvent::ConstPtr GetEvent(BASE_NS::string_view name, MetadataQuery) const = 0;
GetEvent(BASE_NS::string_view name)121 IEvent::ConstPtr GetEvent(BASE_NS::string_view name) const
122 {
123 return GetEvent(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
124 }
125
126 /**
127 * @brief Add function to metadata
128 */
129 virtual bool AddFunction(const IFunction::Ptr&) = 0;
130 /**
131 * @brief Remove function from metadata
132 */
133 virtual bool RemoveFunction(const IFunction::Ptr&) = 0;
134
135 /**
136 * @brief Add property to metadata
137 */
138 virtual bool AddProperty(const IProperty::Ptr&) = 0;
139 /**
140 * @brief Remove property from metadata
141 */
142 virtual bool RemoveProperty(const IProperty::Ptr&) = 0;
143
144 /**
145 * @brief Add event to metadata
146 */
147 virtual bool AddEvent(const IEvent::Ptr&) = 0;
148 /**
149 * @brief Remove event from metadata
150 */
151 virtual bool RemoveEvent(const IEvent::Ptr&) = 0;
152
153 // templated helper for named property fetching. handles typing etc.
154 // returns null if not found or type is not matching.
155 template<typename ValueType>
156 Property<ValueType> GetProperty(BASE_NS::string_view name, MetadataQuery req = MetadataQuery::CONSTRUCT_ON_REQUEST)
157 {
158 return GetProperty(name, req);
159 }
160 template<typename ValueType>
161 Property<const ValueType> GetProperty(
162 BASE_NS::string_view name, MetadataQuery req = MetadataQuery::CONSTRUCT_ON_REQUEST) const
163 {
164 return GetProperty(name, req);
165 }
166 template<typename ValueType>
167 ArrayProperty<ValueType> GetArrayProperty(
168 BASE_NS::string_view name, MetadataQuery req = MetadataQuery::CONSTRUCT_ON_REQUEST)
169 {
170 return GetProperty(name, req);
171 }
172 template<typename ValueType>
173 ArrayProperty<const ValueType> GetArrayProperty(
174 BASE_NS::string_view name, MetadataQuery req = MetadataQuery::CONSTRUCT_ON_REQUEST) const
175 {
176 return GetProperty(name, req);
177 }
178 };
179
180 template<typename ValueType>
181 constexpr auto GetValue(const META_NS::IMetadata* meta, BASE_NS::string_view name, ValueType defaultValue = {}) noexcept
182 {
183 if (meta) {
184 if (auto property = meta->GetProperty<ValueType>(name)) {
185 return GetValue(property, defaultValue);
186 }
187 }
188 return BASE_NS::move(defaultValue);
189 }
190
191 template<typename ValueType, typename Interface,
192 typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<BASE_NS::remove_const_t<Interface>*>>>
193 constexpr auto GetValue(
194 const BASE_NS::shared_ptr<Interface>& intf, BASE_NS::string_view name, ValueType defaultValue = {}) noexcept
195 {
196 return GetValue<ValueType>(interface_cast<IMetadata>(intf), name, defaultValue);
197 }
198
199 template<typename ValueType, typename Interface,
200 typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<BASE_NS::remove_const_t<Interface>*>>>
201 constexpr auto GetValue(
202 const BASE_NS::weak_ptr<Interface>& intf, BASE_NS::string_view name, ValueType defaultValue = {}) noexcept
203 {
204 return GetValue<ValueType>(interface_pointer_cast<IMetadata>(intf), name, defaultValue);
205 }
206
207 template<typename ValueType>
SetValue(META_NS::IMetadata * meta,BASE_NS::string_view name,const ValueType & value)208 constexpr bool SetValue(META_NS::IMetadata* meta, BASE_NS::string_view name, const ValueType& value) noexcept
209 {
210 if (meta) {
211 if (auto property = meta->GetProperty<ValueType>(name)) {
212 return SetValue(property, value);
213 }
214 }
215 return false;
216 }
217
218 template<typename ValueType, typename Interface, typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<Interface*>>>
SetValue(const BASE_NS::shared_ptr<Interface> & intf,BASE_NS::string_view name,const ValueType & value)219 constexpr auto SetValue(
220 const BASE_NS::shared_ptr<Interface>& intf, BASE_NS::string_view name, const ValueType& value) noexcept
221 {
222 return SetValue(interface_cast<IMetadata>(intf), name, value);
223 }
224
225 template<typename ValueType, typename Interface, typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<Interface*>>>
SetValue(const BASE_NS::weak_ptr<Interface> & intf,BASE_NS::string_view name,const ValueType & value)226 constexpr bool SetValue(
227 const BASE_NS::weak_ptr<Interface>& intf, BASE_NS::string_view name, const ValueType& value) noexcept
228 {
229 return SetValue(interface_pointer_cast<IMetadata>(intf), name, value);
230 }
231
232 META_END_NAMESPACE()
233
234 META_INTERFACE_TYPE(META_NS::IMetadata)
235
236 #endif
237