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/intf_owner.h>
22 #include <meta/interface/property/intf_property_internal.h>
23 #include <meta/interface/static_object_metadata.h>
24
META_BEGIN_NAMESPACE()25 META_BEGIN_NAMESPACE()
26
27 inline const StaticObjectMetadata* GetBaseClassMeta(const StaticObjectMetadata* d)
28 {
29 while (d && !d->aggregate) {
30 d = d->baseclass;
31 }
32 return d ? d->aggregate : nullptr;
33 }
34
GetBaseClassMeta(const IObject::ConstPtr & obj)35 inline const StaticObjectMetadata* GetBaseClassMeta(const IObject::ConstPtr& obj)
36 {
37 auto m = interface_cast<IStaticMetadata>(obj);
38 return m ? GetBaseClassMeta(m->GetStaticMetadata()) : nullptr;
39 }
40
GetBaseClass(const IObject::ConstPtr & obj)41 inline ObjectId GetBaseClass(const IObject::ConstPtr& obj)
42 {
43 if (auto m = GetBaseClassMeta(obj)) {
44 if (m->classInfo) {
45 return m->classInfo->Id();
46 }
47 }
48 return {};
49 }
50
FindStaticMetadataInClass(const StaticObjectMetadata & data,BASE_NS::string_view name,MetadataType type)51 inline const StaticMetadata* FindStaticMetadataInClass(
52 const StaticObjectMetadata& data, BASE_NS::string_view name, MetadataType type)
53 {
54 for (size_t i = 0; i != data.size; ++i) {
55 auto& p = data.metadata[i];
56 if (p.name == name && ((uint8_t(p.type) & uint8_t(type)) || type == MetadataType::UNKNOWN)) {
57 return &p;
58 }
59 }
60 return data.baseclass ? FindStaticMetadataInClass(*data.baseclass, name, type) : nullptr;
61 }
FindStaticMetadata(const StaticObjectMetadata & data,BASE_NS::string_view name,MetadataType type)62 inline const StaticMetadata* FindStaticMetadata(
63 const StaticObjectMetadata& data, BASE_NS::string_view name, MetadataType type)
64 {
65 if (auto ret = FindStaticMetadataInClass(data, name, type)) {
66 return ret;
67 }
68 auto base = GetBaseClassMeta(&data);
69 return base ? FindStaticMetadata(*base, name, type) : nullptr;
70 }
71
72 template<typename Interface>
ConstructFromMetadata(const IOwner::Ptr & self,const StaticMetadata & pm)73 auto ConstructFromMetadata(const IOwner::Ptr& self, const StaticMetadata& pm)
74 {
75 auto res = pm.create(self, pm);
76 if (!res) {
77 CORE_LOG_W("Failed to create entity from static metadata [name=%s]", pm.name);
78 }
79 return interface_pointer_cast<Interface>(res);
80 }
81
82 template<typename Interface>
ConstructFromMetadata(const IOwner::Ptr & self,const StaticObjectMetadata & sm,BASE_NS::string_view name,MetadataType type)83 auto ConstructFromMetadata(
84 const IOwner::Ptr& self, const StaticObjectMetadata& sm, BASE_NS::string_view name, MetadataType type)
85 {
86 if (auto pm = FindStaticMetadata(sm, name, type)) {
87 return ConstructFromMetadata<Interface>(self, *pm);
88 }
89 return typename Interface::Ptr {};
90 }
91
92 template<typename Interface>
ConstructFromMetadata(const IOwner::Ptr & self,BASE_NS::string_view name,MetadataType type)93 auto ConstructFromMetadata(const IOwner::Ptr& self, BASE_NS::string_view name, MetadataType type)
94 {
95 if (auto s = interface_cast<IStaticMetadata>(self)) {
96 if (auto pm = s->GetStaticMetadata()) {
97 return ConstructFromMetadata<Interface>(self, *pm, name, type);
98 }
99 }
100 return typename Interface::Ptr {};
101 }
102
ConstructPropertyFromMetadata(const IOwner::Ptr & self,BASE_NS::string_view name)103 inline auto ConstructPropertyFromMetadata(const IOwner::Ptr& self, BASE_NS::string_view name)
104 {
105 auto p = ConstructFromMetadata<IProperty>(self, name, MetadataType::PROPERTY);
106 if (auto pp = interface_cast<IPropertyInternal>(p)) {
107 if (auto s = interface_pointer_cast<IObjectInstance>(self)) {
108 pp->SetOwner(s);
109 }
110 }
111 return p;
112 }
113
GetMetaPropertyType(const StaticMetadata & m)114 inline TypeId GetMetaPropertyType(const StaticMetadata& m)
115 {
116 if (m.type == MetadataType::PROPERTY && m.runtimeValue) {
117 if (auto def = m.runtimeValue()) {
118 return def->GetTypeId();
119 }
120 }
121 return {};
122 }
GetAllStaticMetadataInClass(const StaticObjectMetadata & data,MetadataType type)123 inline BASE_NS::vector<MetadataInfo> GetAllStaticMetadataInClass(const StaticObjectMetadata& data, MetadataType type)
124 {
125 BASE_NS::vector<MetadataInfo> result;
126 for (size_t i = 0; i != data.size; ++i) {
127 auto& p = data.metadata[i];
128 if (uint8_t(p.type) & uint8_t(type)) {
129 MetadataInfo info { p.type, p.name };
130 info.propertyType = GetMetaPropertyType(p);
131 result.push_back(info);
132 }
133 }
134 if (data.baseclass) {
135 auto r = GetAllStaticMetadataInClass(*data.baseclass, type);
136 result.insert(result.end(), r.begin(), r.end());
137 }
138 return result;
139 }
GetAllStaticMetadata(const StaticObjectMetadata & data,MetadataType type)140 inline BASE_NS::vector<MetadataInfo> GetAllStaticMetadata(const StaticObjectMetadata& data, MetadataType type)
141 {
142 auto result = GetAllStaticMetadataInClass(data, type);
143 if (auto base = GetBaseClassMeta(&data)) {
144 auto r = GetAllStaticMetadata(*base, type);
145 result.insert(result.end(), r.begin(), r.end());
146 }
147 return result;
148 }
149 META_END_NAMESPACE()
150
151 #endif
152