• 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_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/static_object_metadata.h>
23 
META_BEGIN_NAMESPACE()24 META_BEGIN_NAMESPACE()
25 
26 /// Get the aggregate baseclass' metadata
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 
35 /// Get the aggregate baseclass' metadata
GetBaseClassMeta(const IObject::ConstPtr & obj)36 inline const StaticObjectMetadata* GetBaseClassMeta(const IObject::ConstPtr& obj)
37 {
38     auto m = interface_cast<IStaticMetadata>(obj);
39     return m ? GetBaseClassMeta(m->GetStaticMetadata()) : nullptr;
40 }
41 
42 /// Get the aggregate baseclass' object id
GetBaseClass(const IObject::ConstPtr & obj)43 inline ObjectId GetBaseClass(const IObject::ConstPtr& obj)
44 {
45     if (auto m = GetBaseClassMeta(obj)) {
46         if (m->classInfo) {
47             return m->classInfo->Id();
48         }
49     }
50     return {};
51 }
52 
53 /// Search static metadata in class metadata, not considering aggregate bases
FindStaticMetadataInClass(const StaticObjectMetadata & data,BASE_NS::string_view name,MetadataType type)54 inline const StaticMetadata* FindStaticMetadataInClass(
55     const StaticObjectMetadata& data, BASE_NS::string_view name, MetadataType type)
56 {
57     for (size_t i = 0; i != data.size; ++i) {
58         auto& p = data.metadata[i];
59         if (p.name == name && ((uint8_t(p.type) & uint8_t(type)) || type == MetadataType::UNKNOWN)) {
60             return &p;
61         }
62     }
63     return data.baseclass ? FindStaticMetadataInClass(*data.baseclass, name, type) : nullptr;
64 }
65 
66 /**
67  * @brief Find static metadata for given name and type
68  * @param data Metadata to search from
69  * @param name Name of the entity to search metadata for
70  * @param type Type of the entity to search, this contains bit field of the possible types
71  * @notice Returns the first matching metadata
72  * @return Static metadata for matching entity.
73  */
FindStaticMetadata(const StaticObjectMetadata & data,BASE_NS::string_view name,MetadataType type)74 inline const StaticMetadata* FindStaticMetadata(
75     const StaticObjectMetadata& data, BASE_NS::string_view name, MetadataType type)
76 {
77     if (auto ret = FindStaticMetadataInClass(data, name, type)) {
78         return ret;
79     }
80     auto base = GetBaseClassMeta(&data);
81     return base ? FindStaticMetadata(*base, name, type) : nullptr;
82 }
83 
84 template<typename Interface>
85 struct MetadataObject {
86     typename Interface::Ptr object {};
87     bool isForward {};
88 };
89 
90 /// Construct entity from given metadata
91 template<typename Interface>
ConstructFromMetadata(const IOwner::Ptr & self,const StaticMetadata & pm)92 MetadataObject<Interface> ConstructFromMetadata(const IOwner::Ptr& self, const StaticMetadata& pm)
93 {
94     auto res = pm.create(self, pm);
95     if (!res) {
96         CORE_LOG_W("Failed to create entity from static metadata [name=%s]", pm.name);
97     }
98     return MetadataObject<Interface> { interface_pointer_cast<Interface>(res),
99         bool(pm.flags & uint8_t(Internal::StaticMetaFlag::FORWARD)) };
100 }
101 
102 /// Find and construct entity with given criteria starting search from static metadata
103 template<typename Interface>
ConstructFromMetadata(const IOwner::Ptr & self,const StaticObjectMetadata & sm,BASE_NS::string_view name,MetadataType type)104 MetadataObject<Interface> ConstructFromMetadata(
105     const IOwner::Ptr& self, const StaticObjectMetadata& sm, BASE_NS::string_view name, MetadataType type)
106 {
107     if (auto pm = FindStaticMetadata(sm, name, type)) {
108         return ConstructFromMetadata<Interface>(self, *pm);
109     }
110     return {};
111 }
112 
113 /// Find and construct entity with given criteria for object
114 template<typename Interface>
ConstructFromMetadata(const IOwner::Ptr & self,BASE_NS::string_view name,MetadataType type)115 MetadataObject<Interface> ConstructFromMetadata(const IOwner::Ptr& self, BASE_NS::string_view name, MetadataType type)
116 {
117     if (auto s = interface_cast<IStaticMetadata>(self)) {
118         if (auto pm = s->GetStaticMetadata()) {
119             return ConstructFromMetadata<Interface>(self, *pm, name, type);
120         }
121     }
122     return {};
123 }
124 
GetMetaPropertyType(const StaticMetadata & m)125 inline TypeId GetMetaPropertyType(const StaticMetadata& m)
126 {
127     if (m.type == MetadataType::PROPERTY && m.runtimeValue) {
128         if (auto def = m.runtimeValue()) {
129             return def->GetTypeId();
130         }
131     }
132     return {};
133 }
134 
135 /// Get all static metadata recursively without considering aggregate bases
GetAllStaticMetadataInClass(const StaticObjectMetadata & data,MetadataType type)136 inline BASE_NS::vector<MetadataInfo> GetAllStaticMetadataInClass(const StaticObjectMetadata& data, MetadataType type)
137 {
138     BASE_NS::vector<MetadataInfo> result;
139     for (size_t i = 0; i != data.size; ++i) {
140         auto& p = data.metadata[i];
141         if (uint8_t(p.type) & uint8_t(type)) {
142             MetadataInfo info { p.type, p.name, p.interfaceInfo };
143             if (p.type == MetadataType::PROPERTY) {
144                 info.propertyType = GetMetaPropertyType(p);
145                 info.readOnly = p.flags & static_cast<uint8_t>(Internal::PropertyFlag::READONLY);
146             }
147             info.data = &p;
148             result.push_back(info);
149         }
150     }
151     if (data.baseclass) {
152         auto r = GetAllStaticMetadataInClass(*data.baseclass, type);
153         result.insert(result.end(), r.begin(), r.end());
154     }
155     return result;
156 }
157 
158 /// Get all static metadata recursively
GetAllStaticMetadata(const StaticObjectMetadata & data,MetadataType type)159 inline BASE_NS::vector<MetadataInfo> GetAllStaticMetadata(const StaticObjectMetadata& data, MetadataType type)
160 {
161     auto result = GetAllStaticMetadataInClass(data, type);
162     if (auto base = GetBaseClassMeta(&data)) {
163         auto r = GetAllStaticMetadata(*base, type);
164         result.insert(result.end(), r.begin(), r.end());
165     }
166     return result;
167 }
168 
169 META_END_NAMESPACE()
170 
171 #endif
172