• 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_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