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_IMPLEMENTATION_MACROS_H
17 #define META_EXT_IMPLEMENTATION_MACROS_H
18
19 #include <meta/base/namespace.h>
20 #include <meta/base/shared_ptr.h>
21 #include <meta/ext/event_impl.h>
22 #include <meta/ext/object_factory.h>
23 #include <meta/interface/interface_macros.h>
24 #include <meta/interface/intf_object_flags.h>
25 #include <meta/interface/intf_object_registry.h>
26 #include <meta/interface/metadata_query.h>
27 #include <meta/interface/property/construct_array_property.h>
28 #include <meta/interface/property/construct_property.h>
29
30 /**
31 * @brief Access property variable introduced with META_IMPLEMENT_*_PROPERTY
32 */
33 #define META_ACCESS_PROPERTY(name) name()
34 #define META_ACCESS_PROPERTY_VALUE(name) name()->GetValue()
35 /**
36 * @brief Access event variable introduced with META_IMPLEMENT_*_EVENT
37 */
38 #define META_ACCESS_EVENT(name) name()
39
40 #define META_VALUE_PTR(interface, classId) ::META_NS::ValuePtrImpl<interface>::Instance<classId>
41
META_BEGIN_NAMESPACE()42 META_BEGIN_NAMESPACE()
43 constexpr ObjectFlagBitsValue DEFAULT_PROPERTY_FLAGS = ObjectFlagBitsValue { ObjectFlagBits::SERIALIZE };
44 constexpr ObjectFlagBitsValue DEFAULT_PROPERTY_FLAGS_NO_SER = ObjectFlagBitsValue { ObjectFlagBits::NONE };
45 struct NoInterface {
46 constexpr static const META_NS::InterfaceInfo INTERFACE_INFO {};
47 constexpr static const BASE_NS::Uid UID {};
48 };
49
50 template<typename Type>
CreatePropertyImpl(BASE_NS::string_view name,Internal::MetaValue * def,ObjectFlagBitsValue flags)51 IProperty::Ptr CreatePropertyImpl(BASE_NS::string_view name, Internal::MetaValue* def, ObjectFlagBitsValue flags)
52 {
53 flags |= ObjectFlagBits::NATIVE;
54 IAny::Ptr value;
55 if (def) {
56 value = def();
57 }
58 if constexpr (BASE_NS::is_array_v<Type>) {
59 if (value) {
60 return META_NS::ConstructArrayPropertyAny<BASE_NS::remove_extent_t<Type>>(name, *value, flags);
61 }
62 return META_NS::ConstructArrayProperty<BASE_NS::remove_extent_t<Type>>(name, {}, flags);
63 } else {
64 if (value) {
65 return META_NS::ConstructPropertyAny<Type>(name, *value, flags);
66 }
67 return META_NS::ConstructProperty<Type>(name, {}, flags);
68 }
69 }
70
71 template<typename Type, uint64_t Flags>
CreatePropertyConstructor()72 Internal::MetadataCtor* CreatePropertyConstructor()
73 {
74 return [](const BASE_NS::shared_ptr<IOwner>&, const StaticMetadata& d) {
75 return interface_pointer_cast<CORE_NS::IInterface>(
76 META_NS::CreatePropertyImpl<Type>(d.name, d.runtimeValue, ObjectFlagBitsValue(Flags)));
77 };
78 }
79
80 template<typename Type>
CreateEventConstructor()81 Internal::MetadataCtor* CreateEventConstructor()
82 {
83 return [](const BASE_NS::shared_ptr<IOwner>&, const StaticMetadata& d) {
84 return interface_pointer_cast<CORE_NS::IInterface>(CreateShared<EventImpl<Type>>(d.name));
85 };
86 }
87
88 template<typename Interface, auto MemFun>
CreateFunctionConstructor()89 Internal::MetadataCtor* CreateFunctionConstructor()
90 {
91 return [](const BASE_NS::shared_ptr<IOwner>& owner, const StaticMetadata& d) {
92 return interface_pointer_cast<CORE_NS::IInterface>(
93 CreateFunction(d.name, interface_pointer_cast<Interface>(owner), MemFun, d.runtimeValue));
94 };
95 }
96
97 template<size_t Size>
MetadataArraySize(const StaticMetadata (&)[Size])98 constexpr size_t MetadataArraySize(const StaticMetadata (&)[Size])
99 {
100 return Size;
101 }
MetadataArraySize(const nullptr_t &)102 constexpr size_t MetadataArraySize(const nullptr_t&)
103 {
104 return 0;
105 }
106
GetAggregateMetadata(const ObjectId & id)107 inline const StaticObjectMetadata* GetAggregateMetadata(const ObjectId& id)
108 {
109 auto f = GetObjectRegistry().GetObjectFactory(id);
110 return f ? f->GetClassStaticMetadata() : nullptr;
111 }
112
113 template<typename Type, typename Base, typename Data>
CreateStaticMetadata(const Data & data,const StaticObjectMetadata * base,const ClassInfo * classInfo,const StaticObjectMetadata * aggregate)114 inline StaticObjectMetadata CreateStaticMetadata(const Data& data, const StaticObjectMetadata* base,
115 const ClassInfo* classInfo, const StaticObjectMetadata* aggregate)
116 {
117 size_t size = META_NS::MetadataArraySize(data);
118 bool baseDataSame = size && base && data == base->metadata;
119 return StaticObjectMetadata { classInfo, base, aggregate, baseDataSame ? nullptr : data, baseDataSame ? 0 : size };
120 }
121
122 META_END_NAMESPACE()
123
124 #define META_IMPLEMENT_STATIC_DATA_DEPIMPL(myClass, classInfo, baseClass) \
125 private: \
126 using Super = baseClass; \
127 \
128 public: \
129 static const META_NS::StaticObjectMetadata* StaticMetadata() \
130 { \
131 static const META_NS::StaticObjectMetadata objdata { META_NS::CreateStaticMetadata<myClass, baseClass>( \
132 myClass::STATIC_METADATA, baseClass::StaticMetadata(), classInfo, nullptr) }; \
133 return &objdata; \
134 } \
135 const META_NS::StaticObjectMetadata* GetStaticMetadata() const override \
136 { \
137 return StaticMetadata(); \
138 }
139
140 #define META_IMPLEMENT_STATIC_DATA_AGGRIMPL(myClass, classInfo, baseClass, aggrClass) \
141 private: \
142 using Super = baseClass; \
143 \
144 public: \
145 static const META_NS::StaticObjectMetadata* StaticMetadata() \
146 { \
147 static const META_NS::StaticObjectMetadata objdata { META_NS::CreateStaticMetadata<myClass, baseClass>( \
148 myClass::STATIC_METADATA, baseClass::StaticMetadata(), classInfo, \
149 META_NS::GetAggregateMetadata(aggrClass)) }; \
150 return &objdata; \
151 } \
152 const META_NS::StaticObjectMetadata* GetStaticMetadata() const override \
153 { \
154 return StaticMetadata(); \
155 }
156
157 #define META_BEGIN_STATIC_DATA() inline static const META_NS::StaticMetadata STATIC_METADATA[] = {
158 #define META_END_STATIC_DATA() \
159 } \
160 ;
161
162 #define META_IMPLEMENT_OBJECT_TYPE_INTERFACE(classInfo) \
163 META_NS::ObjectId GetClassId() const override \
164 { \
165 return classInfo.Id(); \
166 } \
167 BASE_NS::string_view GetClassName() const override \
168 { \
169 return classInfo.Name(); \
170 } \
171 BASE_NS::vector<BASE_NS::Uid> GetInterfaces() const override \
172 { \
173 return GetInterfacesVector(); \
174 }
175
176 #define META_IMPLEMENT_OBJECT_BASE_AGGR(myClass, classInfo, baseClass, aggrClass) \
177 META_IMPLEMENT_STATIC_DATA_AGGRIMPL(myClass, &classInfo, baseClass, aggrClass) \
178 META_IMPLEMENT_OBJECT_TYPE_INTERFACE(classInfo) \
179 META_DEFINE_OBJECT_TYPE_INFO(myClass, classInfo)
180
181 #define META_IMPLEMENT_OBJECT_BASE(myClass, classInfo, baseClass) \
182 META_IMPLEMENT_STATIC_DATA_DEPIMPL(myClass, &classInfo, baseClass) \
183 META_IMPLEMENT_OBJECT_TYPE_INTERFACE(classInfo) \
184 META_DEFINE_OBJECT_TYPE_INFO(myClass, classInfo)
185
186 #define META_OBJECT(...) \
187 META_EXPAND( \
188 META_GET_MACRO4_IMPL(__VA_ARGS__, META_IMPLEMENT_OBJECT_BASE_AGGR, META_IMPLEMENT_OBJECT_BASE)(__VA_ARGS__))
189
190 #define META_IMPLEMENT_OBJECT_BASE_AGGR_NO_CLASSINFO(myClass, baseClass, aggrClass) \
191 META_IMPLEMENT_STATIC_DATA_AGGRIMPL(myClass, nullptr, baseClass, aggrClass)
192
193 #define META_IMPLEMENT_OBJECT_BASE_NO_CLASSINFO(myClass, baseClass) \
194 META_IMPLEMENT_STATIC_DATA_DEPIMPL(myClass, nullptr, baseClass)
195
196 #define META_OBJECT_NO_CLASSINFO(...) \
197 META_EXPAND(META_GET_MACRO3_IMPL(__VA_ARGS__, META_IMPLEMENT_OBJECT_BASE_AGGR_NO_CLASSINFO, \
198 META_IMPLEMENT_OBJECT_BASE_NO_CLASSINFO)(__VA_ARGS__))
199
200 #define META_INTF_CHECK(interface, type, name) interface::INTERFACE_INFO
201
202 // todo: check in META_STATIC_PROPERTY_DATA and META_STATIC_EVENT_DATA that name is part of the given interface
203 //--- PROPERTY DATA
204 #define META_IMPL_PROPERTY_DATA_VALUE_FLAGS(intf, type, name, value, flags) \
205 { META_NS::MetadataType::PROPERTY, META_INTF_CHECK(intf, type, name), #name, \
206 META_NS::CreatePropertyConstructor<type, META_NS::ObjectFlagBitsValue(flags).GetValue()>(), \
207 [] { return META_NS::ConstructAnyHelper<type>(value); } },
208 #define META_IMPL_PROPERTY_DATA_VALUE(intf, type, name, value) \
209 META_IMPL_PROPERTY_DATA_VALUE_FLAGS(intf, type, name, value, META_NS::DEFAULT_PROPERTY_FLAGS)
210 #define META_IMPL_PROPERTY_DATA(intf, type, name) META_IMPL_PROPERTY_DATA_VALUE(intf, type, name, {})
211
212 #define META_STATIC_PROPERTY_DATA(...) \
213 META_EXPAND(META_GET_MACRO5_IMPL(__VA_ARGS__, META_IMPL_PROPERTY_DATA_VALUE_FLAGS, META_IMPL_PROPERTY_DATA_VALUE, \
214 META_IMPL_PROPERTY_DATA)(__VA_ARGS__))
215 //---
216
217 //--- ARRAY PROPERTY DATA
218 #define META_IMPL_ARRAY_PROPERTY_DATA_VALUE_FLAGS(intf, type, name, value, flags) \
219 { META_NS::MetadataType::PROPERTY, META_INTF_CHECK(intf, type, name), #name, \
220 META_NS::CreatePropertyConstructor<type[], META_NS::ObjectFlagBitsValue(flags).GetValue()>(), \
221 [] { return META_NS::IAny::Ptr(META_NS::ConstructArrayAnyHelper<type>(value)); } },
222
223 #define META_IMPL_ARRAY_PROPERTY_DATA_VALUE(intf, type, name, value) \
224 META_IMPL_ARRAY_PROPERTY_DATA_VALUE_FLAGS(intf, type, name, value, META_NS::DEFAULT_PROPERTY_FLAGS)
225 #define META_IMPL_ARRAY_PROPERTY_DATA(intf, type, name) META_IMPL_ARRAY_PROPERTY_DATA_VALUE(intf, type, name, {})
226
227 #define META_STATIC_ARRAY_PROPERTY_DATA(...) \
228 META_EXPAND(META_GET_MACRO5_IMPL(__VA_ARGS__, META_IMPL_ARRAY_PROPERTY_DATA_VALUE_FLAGS, \
229 META_IMPL_ARRAY_PROPERTY_DATA_VALUE, META_IMPL_ARRAY_PROPERTY_DATA)(__VA_ARGS__))
230 //---
231
232 #define META_STATIC_EVENT_DATA(intf, type, name) \
233 { META_NS::MetadataType::EVENT, intf::INTERFACE_INFO, #name, META_NS::CreateEventConstructor<type>(), nullptr },
234
235 #define META_STATIC_FUNCTION_DATA(intf, func, ...) \
236 { META_NS::MetadataType::FUNCTION, intf::INTERFACE_INFO, #func, \
237 META_NS::CreateFunctionConstructor<intf, &intf ::func>(), [] { \
238 ::BASE_NS::string_view arr[] = { "", __VA_ARGS__ }; \
239 return META_NS::ConstructAny<META_NS::ICallContext::Ptr>( \
240 META_NS::CreateCallContext(&intf ::func, ::META_NS::ParamNameToView(arr))); \
241 } },
242
243 #define META_PRIVATE_PROPERTY_TYPED_IMPL(type, name) \
244 META_NS::Property<type> name() noexcept \
245 { \
246 return META_NS::Property<type> { this->GetProperty(#name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST) }; \
247 } \
248 META_NS::ConstProperty<type> name() const noexcept \
249 { \
250 return META_NS::ConstProperty<type> { this->GetProperty( \
251 #name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST) }; \
252 }
253
254 #define META_PRIVATE_ARRAY_PROPERTY_TYPED_IMPL(type, name) \
255 META_NS::ConstArrayProperty<type> name() const noexcept \
256 { \
257 return META_NS::ConstArrayProperty<type> { this->GetProperty( \
258 #name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST) }; \
259 } \
260 META_NS::ArrayProperty<type> name() noexcept \
261 { \
262 return META_NS::ArrayProperty<type> { this->GetProperty( \
263 #name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST) }; \
264 }
265
266 #define META_IMPLEMENT_READONLY_PROPERTY(type, name) \
267 ::META_NS::IProperty::ConstPtr Property##name() const noexcept override \
268 { \
269 return this->GetProperty(#name); \
270 } \
271 META_PRIVATE_PROPERTY_TYPED_IMPL(::META_NS::PropertyType_v<type>, name)
272
273 #define META_IMPLEMENT_CACHED_READONLY_PROPERTY(type, name) \
274 mutable META_NS::Property<::META_NS::PropertyType_v<type>> metaProperty##name##_; \
275 ::META_NS::IProperty::ConstPtr Property##name() const noexcept override \
276 { \
277 if (!metaProperty##name##_) { \
278 metaProperty##name##_ = this->GetProperty(#name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST); \
279 } \
280 return metaProperty##name##_; \
281 } \
282 META_PRIVATE_PROPERTY_TYPED_IMPL(::META_NS::PropertyType_v<type>, name)
283
284 #define META_IMPLEMENT_PROPERTY(type, name) \
285 META_IMPLEMENT_READONLY_PROPERTY(type, name) \
286 ::META_NS::IProperty::Ptr Property##name() noexcept override \
287 { \
288 ::META_NS::IProperty::Ptr p = this->GetProperty(#name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST); \
289 CORE_ASSERT(p); \
290 return p; \
291 }
292
293 #define META_IMPLEMENT_CACHED_PROPERTY(type, name) \
294 META_IMPLEMENT_CACHED_READONLY_PROPERTY(type, name) \
295 ::META_NS::IProperty::Ptr Property##name() noexcept override \
296 { \
297 if (!metaProperty##name##_) { \
298 metaProperty##name##_ = this->GetProperty(#name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST); \
299 CORE_ASSERT(metaProperty##name##_) \
300 } \
301 return metaProperty##name##_; \
302 }
303
304 #define META_IMPLEMENT_READONLY_ARRAY_PROPERTY(type, name) \
305 ::META_NS::IProperty::ConstPtr Property##name() const noexcept override \
306 { \
307 ::META_NS::IProperty::ConstPtr p = this->GetProperty(#name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST); \
308 CORE_ASSERT(p); \
309 return p; \
310 } \
311 META_PRIVATE_ARRAY_PROPERTY_TYPED_IMPL(type, name)
312
313 #define META_IMPLEMENT_CACHED_READONLY_ARRAY_PROPERTY(type, name) \
314 mutable META_NS::ArrayProperty<::META_NS::PropertyType_v<type>> metaProperty##name##_; \
315 ::META_NS::IProperty::ConstPtr Property##name() const noexcept override \
316 { \
317 if (!metaProperty##name##_) { \
318 metaProperty##name##_ = this->GetProperty(#name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST); \
319 CORE_ASSERT(metaProperty##name##_) \
320 } \
321 return metaProperty##name##_; \
322 } \
323 META_PRIVATE_ARRAY_PROPERTY_TYPED_IMPL(type, name)
324
325 #define META_IMPLEMENT_ARRAY_PROPERTY(type, name) \
326 META_IMPLEMENT_READONLY_ARRAY_PROPERTY(type, name) \
327 ::META_NS::IProperty::Ptr Property##name() noexcept override \
328 { \
329 return this->GetProperty(#name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST); \
330 }
331
332 #define META_IMPLEMENT_CACHED_ARRAY_PROPERTY(type, name) \
333 META_IMPLEMENT_CACHED_READONLY_PROPERTY(type, name) \
334 ::META_NS::IProperty::Ptr Property##name() noexcept override \
335 { \
336 if (!metaProperty##name##_) { \
337 metaProperty##name##_ = this->GetProperty(#name, META_NS::MetadataQuery::CONSTRUCT_ON_REQUEST); \
338 } \
339 return metaProperty##name##_; \
340 }
341
342 /**
343 * @brief Make forwarding function for the read-only property.
344 */
345 #define META_FORWARD_READONLY_PROPERTY(type, name, forwarder) \
346 META_NS::IProperty::ConstPtr Property##name() const noexcept override \
347 { \
348 return forwarder; \
349 } \
350 META_READONLY_PROPERTY_TYPED_IMPL(type, name)
351
352 /**
353 * @brief Make forwarding function for the property.
354 */
355 #define META_FORWARD_PROPERTY(type, name, forwarder) \
356 META_FORWARD_READONLY_PROPERTY(type, name, forwarder) \
357 META_NS::IProperty::Ptr Property##name() noexcept override \
358 { \
359 return forwarder; \
360 } \
361 META_PROPERTY_TYPED_IMPL(type, name)
362
363 #define META_FORWARD_BASE_READONLY_PROPERTY(type, name) \
364 META_FORWARD_READONLY_PROPERTY(type, name, this->Super::Property##name())
365
366 #define META_FORWARD_BASE_PROPERTY(type, name) META_FORWARD_PROPERTY(type, name, this->Super::Property##name())
367
368 #define META_FORWARD_READONLY_ARRAY_PROPERTY(type, name, forwarder) \
369 META_NS::IProperty::ConstPtr Property##name() const noexcept override \
370 { \
371 return forwarder; \
372 } \
373 META_READONLY_ARRAY_PROPERTY_TYPED_IMPL(type, name)
374
375 /**
376 * @brief Make forwarding function for the property.
377 */
378 #define META_FORWARD_ARRAY_PROPERTY(type, name, forwarder) \
379 META_FORWARD_READONLY_ARRAY_PROPERTY(type, name, forwarder) \
380 META_NS::IProperty::Ptr Property##name() noexcept override \
381 { \
382 return forwarder; \
383 } \
384 META_ARRAY_PROPERTY_TYPED_IMPL(type, name)
385
386 #define META_FORWARD_BASE_READONLY_ARRAY_PROPERTY(type, name) \
387 META_FORWARD_READONLY_ARRAY_PROPERTY(type, name, this->Super::Property##name())
388
389 #define META_FORWARD_BASE_ARRAY_PROPERTY(type, name) \
390 META_FORWARD_ARRAY_PROPERTY(type, name, this->Super::Property##name())
391
392 #define META_IMPLEMENT_EVENT(type, name) \
393 BASE_NS::shared_ptr<::META_NS::IEvent> Event##name(META_NS::MetadataQuery q) const override \
394 { \
395 BASE_NS::shared_ptr<const ::META_NS::IEvent> p = this->GetEvent(#name, q); \
396 return BASE_NS::shared_ptr<::META_NS::IEvent>(p, const_cast<META_NS::IEvent*>(p.get())); \
397 } \
398 META_EVENT_TYPED_IMPL(type, name)
399
400 #define META_FORWARD_EVENT(type, name, forwarder) \
401 BASE_NS::shared_ptr<::META_NS::IEvent> Event##name(META_NS::MetadataQuery q) const override \
402 { \
403 return forwarder(q); \
404 } \
405 META_EVENT_TYPED_IMPL(type, name)
406
407 #define META_FORWARD_EVENT_CLASS(type, name, targetClass) \
408 BASE_NS::shared_ptr<::META_NS::IEvent> Event##name(META_NS::MetadataQuery q) const override \
409 { \
410 return targetClass::Event##name(q); \
411 } \
412 ::META_NS::Event<type> name() const \
413 { \
414 return targetClass::Event##name(q); \
415 }
416
417 #endif
418