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 interfaceId;
44 bool readOnly {};
45 TypeId propertyType;
46 const StaticMetadata* data {};
47
IsValidMetadataInfo48 bool IsValid() const
49 {
50 return !name.empty();
51 }
52 };
53
54 inline bool operator==(const MetadataInfo& l, const MetadataInfo& r)
55 {
56 return l.type == r.type && l.name == r.name && l.interfaceId == r.interfaceId && l.readOnly == r.readOnly &&
57 l.propertyType == r.propertyType;
58 }
59 inline bool operator!=(const MetadataInfo& l, const MetadataInfo& r)
60 {
61 return !(l == r);
62 }
63
64 /**
65 * @brief The IMetadata interface defines a queryable metadata interface for retrieving object properties and functions.
66 */
67 class IMetadata : public CORE_NS::IInterface {
68 META_INTERFACE(CORE_NS::IInterface, IMetadata)
69 public:
70 /**
71 * @brief Returns all properties explicitly added or instantiated from static metadata
72 */
73 virtual BASE_NS::vector<IProperty::Ptr> GetProperties() = 0;
74 virtual BASE_NS::vector<IProperty::ConstPtr> GetProperties() const = 0;
75 /**
76 * @brief Returns all functions explicitly added or instantiated from static metadata
77 */
78 virtual BASE_NS::vector<IFunction::Ptr> GetFunctions() = 0;
79 virtual BASE_NS::vector<IFunction::ConstPtr> GetFunctions() const = 0;
80 /**
81 * @brief Returns all events explicitly added or instantiated from static metadata
82 */
83 virtual BASE_NS::vector<IEvent::Ptr> GetEvents() = 0;
84 virtual BASE_NS::vector<IEvent::ConstPtr> GetEvents() const = 0;
85
86 /**
87 * @brief Get all metadata for requested types
88 * @Note This combines static metadata and existing runtime data
89 */
90 virtual BASE_NS::vector<MetadataInfo> GetAllMetadatas(MetadataType types) const = 0;
91
92 /**
93 * @brief Get metadata for requested entity, the first matching name is returned if type matches
94 */
95 virtual MetadataInfo GetMetadata(MetadataType type, BASE_NS::string_view name) const = 0;
96
97 /**
98 * @brief Returns the property with a given name.
99 * @param name Name of the property to retrieve.
100 * @return The property or nullptr if such property does not exist.
101 */
102 virtual IProperty::Ptr GetProperty(BASE_NS::string_view name, MetadataQuery) = 0;
GetProperty(BASE_NS::string_view name)103 IProperty::Ptr GetProperty(BASE_NS::string_view name)
104 {
105 return GetProperty(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
106 }
107 virtual IProperty::ConstPtr GetProperty(BASE_NS::string_view name, MetadataQuery) const = 0;
GetProperty(BASE_NS::string_view name)108 IProperty::ConstPtr GetProperty(BASE_NS::string_view name) const
109 {
110 return GetProperty(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
111 }
112 /**
113 * @brief Returns the function with a given name
114 * @param name Name of the function to retrieve.
115 * @return The function or nullptr if such function does not exist.
116 */
117 virtual IFunction::Ptr GetFunction(BASE_NS::string_view name, MetadataQuery) = 0;
GetFunction(BASE_NS::string_view name)118 IFunction::Ptr GetFunction(BASE_NS::string_view name)
119 {
120 return GetFunction(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
121 }
122 virtual IFunction::ConstPtr GetFunction(BASE_NS::string_view name, MetadataQuery) const = 0;
GetFunction(BASE_NS::string_view name)123 IFunction::ConstPtr GetFunction(BASE_NS::string_view name) const
124 {
125 return GetFunction(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
126 }
127
128 /**
129 * @brief Returns the event with a given name
130 * @param name Name of the event to retrieve.
131 * @return The event or nullptr if such event does not exist.
132 */
133 virtual IEvent::Ptr GetEvent(BASE_NS::string_view name, MetadataQuery) = 0;
GetEvent(BASE_NS::string_view name)134 IEvent::Ptr GetEvent(BASE_NS::string_view name)
135 {
136 return GetEvent(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
137 }
138 virtual IEvent::ConstPtr GetEvent(BASE_NS::string_view name, MetadataQuery) const = 0;
GetEvent(BASE_NS::string_view name)139 IEvent::ConstPtr GetEvent(BASE_NS::string_view name) const
140 {
141 return GetEvent(name, MetadataQuery::CONSTRUCT_ON_REQUEST);
142 }
143
144 /**
145 * @brief Add function to metadata
146 */
147 virtual bool AddFunction(const IFunction::Ptr&) = 0;
148 /**
149 * @brief Remove function from metadata
150 */
151 virtual bool RemoveFunction(const IFunction::Ptr&) = 0;
152
153 /**
154 * @brief Add property to metadata
155 */
156 virtual bool AddProperty(const IProperty::Ptr&) = 0;
157 /**
158 * @brief Remove property from metadata
159 */
160 virtual bool RemoveProperty(const IProperty::Ptr&) = 0;
161
162 /**
163 * @brief Add event to metadata
164 */
165 virtual bool AddEvent(const IEvent::Ptr&) = 0;
166 /**
167 * @brief Remove event from metadata
168 */
169 virtual bool RemoveEvent(const IEvent::Ptr&) = 0;
170
171 // templated helper for named property fetching. handles typing etc.
172 // returns null if not found or type is not matching.
173 template<typename ValueType>
174 Property<ValueType> GetProperty(BASE_NS::string_view name, MetadataQuery req = MetadataQuery::CONSTRUCT_ON_REQUEST)
175 {
176 return GetProperty(name, req);
177 }
178 template<typename ValueType>
179 Property<const ValueType> GetProperty(
180 BASE_NS::string_view name, MetadataQuery req = MetadataQuery::CONSTRUCT_ON_REQUEST) const
181 {
182 return GetProperty(name, req);
183 }
184 template<typename ValueType>
185 ArrayProperty<ValueType> GetArrayProperty(
186 BASE_NS::string_view name, MetadataQuery req = MetadataQuery::CONSTRUCT_ON_REQUEST)
187 {
188 return GetProperty(name, req);
189 }
190 template<typename ValueType>
191 ArrayProperty<const ValueType> GetArrayProperty(
192 BASE_NS::string_view name, MetadataQuery req = MetadataQuery::CONSTRUCT_ON_REQUEST) const
193 {
194 return GetProperty(name, req);
195 }
196 };
197
198 template<typename ValueType>
199 constexpr auto GetValue(const META_NS::IMetadata* meta, BASE_NS::string_view name, ValueType defaultValue = {}) noexcept
200 {
201 if (meta) {
202 if (auto property = meta->GetProperty<ValueType>(name)) {
203 return GetValue(property, defaultValue);
204 }
205 }
206 return BASE_NS::move(defaultValue);
207 }
208
209 template<typename ValueType, typename Interface,
210 typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<BASE_NS::remove_const_t<Interface>*>>>
211 constexpr auto GetValue(
212 const BASE_NS::shared_ptr<Interface>& intf, BASE_NS::string_view name, ValueType defaultValue = {}) noexcept
213 {
214 return GetValue<ValueType>(interface_cast<IMetadata>(intf), name, defaultValue);
215 }
216
217 template<typename ValueType, typename Interface,
218 typename = BASE_NS::enable_if_t<IsKindOfIInterface_v<BASE_NS::remove_const_t<Interface>*>>>
219 constexpr auto GetValue(
220 const BASE_NS::weak_ptr<Interface>& intf, BASE_NS::string_view name, ValueType defaultValue = {}) noexcept
221 {
222 return GetValue<ValueType>(interface_pointer_cast<IMetadata>(intf), name, defaultValue);
223 }
224
225 template<typename ValueType>
SetValue(META_NS::IMetadata * meta,BASE_NS::string_view name,const ValueType & value)226 constexpr bool SetValue(META_NS::IMetadata* meta, BASE_NS::string_view name, const ValueType& value) noexcept
227 {
228 if (meta) {
229 if (auto property = meta->GetProperty<ValueType>(name)) {
230 return SetValue(property, value);
231 }
232 }
233 return false;
234 }
235
236 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)237 constexpr auto SetValue(
238 const BASE_NS::shared_ptr<Interface>& intf, BASE_NS::string_view name, const ValueType& value) noexcept
239 {
240 return SetValue(interface_cast<IMetadata>(intf), name, value);
241 }
242
243 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)244 constexpr bool SetValue(
245 const BASE_NS::weak_ptr<Interface>& intf, BASE_NS::string_view name, const ValueType& value) noexcept
246 {
247 return SetValue(interface_pointer_cast<IMetadata>(intf), name, value);
248 }
249
250 META_END_NAMESPACE()
251
252 META_INTERFACE_TYPE(META_NS::IMetadata)
253
254 #endif
255