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_METADATA_HELPERS_H
17 #define META_EXT_METADATA_HELPERS_H
18
19 #include <meta/interface/intf_metadata.h>
20 #include <meta/interface/intf_object.h>
21 #include <meta/interface/property/intf_property_internal.h>
22 #include <meta/interface/static_object_metadata.h>
23
META_BEGIN_NAMESPACE()24 META_BEGIN_NAMESPACE()
25
26 /**
27 * @brief Helper to construct/add properties to newly created object using the static metadata.
28 */
29 template<typename Self>
30 void ConstructPropertiesFromMetadata(Self* self, const StaticObjectMetadata& sm, const IMetadata::Ptr& meta)
31 {
32 for (auto&& pm : sm.properties) {
33 auto p = meta->GetPropertyByName(pm.name);
34 if (p) {
35 if (!pm.init(self, p)) {
36 p = nullptr;
37 }
38 }
39 if (!p) {
40 p = pm.create();
41 if (!pm.init(self, p)) {
42 CORE_ASSERT_MSG(false, "Failed to initialise property");
43 return;
44 }
45 meta->AddProperty(p);
46 }
47 if (auto pp = interface_cast<IPropertyInternal>(p)) {
48 if (auto s = self->GetInterface(IObjectInstance::UID)) {
49 pp->SetOwner(static_cast<IObjectInstance*>(s)->GetSelf());
50 }
51 }
52 }
53 }
54
55 /**
56 * @brief Helper to construct or init event.
57 */
58 template<typename Self>
ConstructOrInitEvent(IEvent::Ptr & p,Self * self,const EventMetadata & pm)59 bool ConstructOrInitEvent(IEvent::Ptr& p, Self* self, const EventMetadata& pm)
60 {
61 if (p) {
62 if (!pm.init(self, p)) {
63 p = nullptr;
64 }
65 }
66 if (!p) {
67 p = pm.create();
68 if (!pm.init(self, p)) {
69 CORE_ASSERT_MSG(false, "Failed to initialise event");
70 return false;
71 }
72 return true;
73 }
74 return false;
75 }
76
77 /**
78 * @brief Helper to construct/add events to newly created object using the static metadata.
79 */
80 template<typename Self>
ConstructEventsFromMetadata(Self * self,const StaticObjectMetadata & sm,const IMetadata::Ptr & meta)81 void ConstructEventsFromMetadata(Self* self, const StaticObjectMetadata& sm, const IMetadata::Ptr& meta)
82 {
83 for (auto&& pm : sm.events) {
84 auto p = meta->GetEventByName(pm.name);
85 if (ConstructOrInitEvent(p, self, pm)) {
86 meta->AddEvent(p);
87 }
88 }
89 }
90
91 /**
92 * @brief Helper to construct/add meta functions to newly created object using the static metadata.
93 */
94 template<typename Self>
ConstructFunctionsFromMetadata(Self * self,const StaticObjectMetadata & sm,const IMetadata::Ptr & meta)95 void ConstructFunctionsFromMetadata(Self* self, const StaticObjectMetadata& sm, const IMetadata::Ptr& meta)
96 {
97 for (auto&& pm : sm.functions) {
98 auto p = pm.create(self);
99 if (!p) {
100 CORE_ASSERT_MSG(false, "Failed to create function");
101 return;
102 }
103 meta->AddFunction(p);
104 }
105 }
106
107 /**
108 * @brief Add static metadata machinery to object. This is usually done by ObjectFwd and a like helpers.
109 */
110 #define STATIC_METADATA_MACHINERY(classinfo, baseclass) \
111 using Impl = baseclass; \
112 \
113 protected: \
114 bool IsFirstInit() \
115 { \
116 static bool init = (isFirstInit_ = true); \
117 return isFirstInit_; \
118 } \
119 template<typename Type> \
120 META_NS::nullptr_t RegisterStaticPropertyMetadata(const META_NS::InterfaceInfo& intf, BASE_NS::string_view name, \
121 META_NS::ObjectFlagBitsValue flags, META_NS::Internal::PCtor* ctor, META_NS::Internal::PMemberInit* init) \
122 { \
123 if (IsFirstInit()) { \
124 StaticObjectMeta().properties.push_back( \
125 META_NS::PropertyMetadata { name, intf, flags, META_NS::UidFromType<Type>(), ctor, init }); \
126 } \
127 return nullptr; \
128 } \
129 template<typename Type> \
130 META_NS::nullptr_t RegisterStaticEventMetadata(const META_NS::InterfaceInfo& intf, BASE_NS::string_view name, \
131 META_NS::Internal::ECtor* ctor, META_NS::Internal::EMemberInit* init) \
132 { \
133 if (IsFirstInit()) { \
134 StaticObjectMeta().events.push_back(META_NS::EventMetadata { name, intf, Type::UID, ctor, init }); \
135 } \
136 return nullptr; \
137 } \
138 META_NS::nullptr_t RegisterStaticFunctionMetadata(const META_NS::InterfaceInfo& intf, BASE_NS::string_view name, \
139 META_NS::Internal::FCtor* ctor, META_NS::Internal::FContext* context) \
140 { \
141 if (IsFirstInit()) { \
142 StaticObjectMeta().functions.push_back(META_NS::FunctionMetadata { name, intf, ctor, context }); \
143 } \
144 return nullptr; \
145 } \
146 \
147 private: \
148 bool isFirstInit_ {}; \
149 static META_NS::StaticObjectMetadata& StaticObjectMeta() \
150 { \
151 static META_NS::StaticObjectMetadata meta { classinfo, &Impl::GetStaticObjectMetadata() }; \
152 return meta; \
153 } \
154 \
155 public: \
156 static const META_NS::StaticObjectMetadata& GetStaticObjectMetadata() \
157 { \
158 return StaticObjectMeta(); \
159 } \
160 \
161 private:
162
163 #define STATIC_METADATA_MACHINERY_WITH_CONCRETE_BASE(classinfo, baseclass) \
164 STATIC_METADATA_MACHINERY(classinfo, baseclass) \
165 protected: \
166 const META_NS::StaticObjectMetadata& GetStaticMetadata() const override \
167 { \
168 return GetStaticObjectMetadata(); \
169 } \
170 void SetMetadata(const META_NS::IMetadata::Ptr& meta) override \
171 { \
172 Impl::SetMetadata(meta); \
173 META_NS::ConstructPropertiesFromMetadata(this, StaticObjectMeta(), meta); \
174 META_NS::ConstructEventsFromMetadata(this, StaticObjectMeta(), meta); \
175 META_NS::ConstructFunctionsFromMetadata(this, StaticObjectMeta(), meta); \
176 }
177
178 #define STATIC_METADATA_WITH_CONCRETE_BASE(introduced, baseclass) \
179 STATIC_METADATA_MACHINERY_WITH_CONCRETE_BASE(ClassInfo, baseclass)
180
181 META_END_NAMESPACE()
182
183 #endif
184