• 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 #ifndef META_BASE_META_TYPES_H
16 #define META_BASE_META_TYPES_H
17 
18 #include <stdint.h>
19 
20 #include <base/namespace.h>
21 #include <base/util/color.h>
22 #include <base/util/compile_time_hashes.h>
23 #include <base/util/uid.h>
24 #include <core/plugin/intf_interface.h>
25 #include <core/property/property_types.h>
26 
27 #include <meta/base/type_traits.h>
28 
29 CORE_BEGIN_NAMESPACE()
30 
31 DECLARE_PROPERTY_TYPE(BASE_NS::vector<BASE_NS::string>);
32 
33 CORE_END_NAMESPACE()
34 
35 META_BEGIN_NAMESPACE()
36 
37 template<typename t>
38 struct MetaType;
39 
40 template<class T, class B>
CorePropertyTypeDeclFromType()41 inline constexpr auto CorePropertyTypeDeclFromType()
42 {
43     if constexpr (CORE_NS::PropertySystem::is_defined<T>().value) {
44         return CORE_NS::PropertySystem::PropertyTypeDeclFromType<T, B>();
45     }
46     return CORE_NS::PropertyTypeDecl {};
47 }
48 
MakeUidImpl(uint64_t hash,const char (& type)[9])49 inline constexpr BASE_NS::Uid MakeUidImpl(uint64_t hash, const char (&type)[9])
50 {
51     uint8_t data[16u] { static_cast<uint8_t>((hash >> 56) & 0xFF), static_cast<uint8_t>((hash >> 48) & 0xFF),
52         static_cast<uint8_t>((hash >> 40) & 0xFF), static_cast<uint8_t>((hash >> 32) & 0xFF),
53         static_cast<uint8_t>((hash >> 24) & 0xFF), static_cast<uint8_t>((hash >> 16) & 0xFF),
54         static_cast<uint8_t>((hash >> 8) & 0xFF), static_cast<uint8_t>(hash & 0xFF), static_cast<uint8_t>(type[0]),
55         static_cast<uint8_t>(type[1]), static_cast<uint8_t>(type[2]), static_cast<uint8_t>(type[3]),
56         static_cast<uint8_t>(type[4]), static_cast<uint8_t>(type[5]), static_cast<uint8_t>(type[6]),
57         static_cast<uint8_t>(type[7]) };
58     return BASE_NS::Uid(data);
59 }
60 
61 /**
62  * @brief Generate UID from name and type string.
63  */
MakeUid(const char * const name,const char (& type)[9])64 inline constexpr BASE_NS::Uid MakeUid(const char* const name, const char (&type)[9])
65 {
66     return MakeUidImpl(BASE_NS::CompileTime::FNV1aHash(name), type);
67 }
68 
69 template<typename Type>
70 using EnableIfDefined = decltype(sizeof(Type));
71 
72 template<typename Type>
73 constexpr bool IsDefined_v = META_NS::IsDetected_v<EnableIfDefined, Type>; // NOLINT(readability-identifier-naming)
74 
75 template<typename Type>
76 constexpr bool HasUid_v = IsDefined_v<MetaType<Type>>; // NOLINT(readability-identifier-naming)
77 
78 /**
79  * @brief Generate UID from registered type and type string.
80  */
81 template<typename Type>
MakeUid(const char (& type)[9])82 inline constexpr BASE_NS::Uid MakeUid(const char (&type)[9])
83 {
84     static_assert(HasUid_v<Type>, "META_TYPE missing for given type");
85     return MakeUidImpl(BASE_NS::CompileTime::FNV1aHash(MetaType<Type>::name), type);
86 }
87 
88 template<typename Type>
CombineHash(uint64_t hash)89 inline constexpr uint64_t CombineHash(uint64_t hash)
90 {
91     static_assert(HasUid_v<Type>, "META_TYPE missing for given type");
92     return hash ^
93             (BASE_NS::CompileTime::FNV1aHash(MetaType<Type>::name) + 0x9e3779b97f4a7c15LLU + (hash << 12) + // 12: bits
94             (hash >> 4));                                                                                   //  4: bits
95 }
96 
97 /**
98  * @brief Generate UID from multiple registered types and type string.
99  */
100 template<typename... Types>
MakeUidFromTypes(const char (& type)[9])101 inline constexpr BASE_NS::Uid MakeUidFromTypes(const char (&type)[9])
102 {
103     uint64_t hash {};
104     if constexpr (sizeof...(Types) != 0) {
105         hash = (CombineHash<Types>(hash), ...);
106     }
107     return MakeUidImpl(hash, type);
108 }
109 
110 /**
111  * @brief Check if UID is valid.
112  */
IsValidUid(const BASE_NS::Uid & uid)113 inline constexpr bool IsValidUid(const BASE_NS::Uid& uid)
114 {
115     return uid.data[0] && uid.data[1];
116 }
117 
118 /**
119  * @brief Generate UID for read-only property type.
120  */
121 template<typename Type>
UidFromReadOnlyType()122 inline constexpr BASE_NS::Uid UidFromReadOnlyType()
123 {
124 // At least visual c++ 2017 has a bug that causes this uid variable to be uninitialised at runtime and so crashing
125 // We know at least visual c++ 2022 works...
126 #if defined(_MSC_VER) && _MSC_VER < 1930
127     return MakeUid<Type>("ReadOnly");
128 #else
129     constexpr auto uid = MakeUid<Type>("ReadOnly");
130     static_assert(IsValidUid(uid));
131     return uid;
132 #endif
133 }
134 /**
135  * @brief Generate UID for property type.
136  */
137 
138 template<typename Type>
UidFromType()139 inline constexpr BASE_NS::Uid UidFromType()
140 {
141 // At least visual c++ 2017 has a bug that causes this uid variable to be uninitialised at runtime and so crashing
142 // We know at least visual c++ 2022 works...
143 #if defined(_MSC_VER) && _MSC_VER < 1930
144     return MakeUid<Type>("Property");
145 #else
146     constexpr auto uid = MakeUid<Type>("Property");
147     static_assert(IsValidUid(uid));
148     return uid;
149 #endif
150 }
151 
152 template<typename Type>
ArrayUidFromType()153 inline constexpr BASE_NS::Uid ArrayUidFromType()
154 {
155     if constexpr (BASE_NS::is_array_v<Type>) {
156         return UidFromType<Type>();
157     }
158     return UidFromType<Type[]>();
159 }
160 
161 template<typename Type>
ItemUidFromType()162 inline constexpr BASE_NS::Uid ItemUidFromType()
163 {
164     return UidFromType<BASE_NS::remove_extent_t<Type>>();
165 }
166 
167 template<>
168 struct MetaType<void> {
169     // NOLINTBEGIN(readability-identifier-naming)
170     static constexpr char name[] = "void";
171     static constexpr CORE_NS::PropertyTypeDecl coreType = CorePropertyTypeDeclFromType<void, BASE_NS::false_type>();
172     // NOLINTEND(readability-identifier-naming)
173 };
174 
175 META_END_NAMESPACE()
176 
177 /**
178  * @brief To introduce new types to the property system, call META_TYPE(<type>) in global namespace.
179  */
180 #define META_TYPE_IMPL(a, n)                                                                    \
181     template<>                                                                                  \
182     struct ::META_NS::MetaType<a> {                                                             \
183         static constexpr char name[] = n;                                                       \
184         static constexpr CORE_NS::PropertyTypeDecl coreType =                                   \
185             ::META_NS::CorePropertyTypeDeclFromType<a, BASE_NS::false_type>();                  \
186     };                                                                                          \
187     template<>                                                                                  \
188     struct ::META_NS::MetaType<a[]> {                                                           \
189         static constexpr char name[] = n "[]";                                                  \
190         static constexpr CORE_NS::PropertyTypeDecl coreType =                                   \
191             ::META_NS::CorePropertyTypeDeclFromType<a, BASE_NS::true_type>();                   \
192     };                                                                                          \
193     template<>                                                                                  \
194     struct ::META_NS::MetaType<BASE_NS::vector<a>> {                                            \
195         static constexpr char name[] = "BASE_NS::vector<" n ">";                                \
196         static constexpr CORE_NS::PropertyTypeDecl coreType =                                   \
197             ::META_NS::CorePropertyTypeDeclFromType<BASE_NS::vector<a>, BASE_NS::false_type>(); \
198     };
199 
200 #define META_TYPE(a) META_TYPE_IMPL(a, #a)
201 #define META_INTERFACE_TYPE(a)                   \
202     META_TYPE_IMPL(a::Ptr, #a "::Ptr")           \
203     META_TYPE_IMPL(a::ConstPtr, #a "::ConstPtr") \
204     META_TYPE_IMPL(a::WeakPtr, #a "::WeakPtr")   \
205     META_TYPE_IMPL(a::ConstWeakPtr, #a "::ConstWeakPtr")
206 
207 META_TYPE(char);
208 META_TYPE(wchar_t);
209 META_TYPE(float);
210 META_TYPE(double);
211 META_TYPE(bool);
212 META_TYPE(uint8_t);
213 META_TYPE(uint16_t);
214 META_TYPE(uint32_t);
215 META_TYPE(uint64_t);
216 META_TYPE(int8_t);
217 META_TYPE(int16_t);
218 META_TYPE(int32_t);
219 META_TYPE(int64_t);
220 #ifdef __APPLE__
221 META_TYPE(size_t);
222 #endif
223 META_TYPE(BASE_NS::Uid);
224 META_TYPE(BASE_NS::string);
225 META_TYPE(BASE_NS::string_view);
226 META_TYPE(BASE_NS::Math::Vec2);
227 META_TYPE(BASE_NS::Math::UVec2);
228 META_TYPE(BASE_NS::Math::IVec2);
229 META_TYPE(BASE_NS::Math::Vec3);
230 META_TYPE(BASE_NS::Math::UVec3);
231 META_TYPE(BASE_NS::Math::IVec3);
232 META_TYPE(BASE_NS::Math::Vec4);
233 META_TYPE(BASE_NS::Math::UVec4);
234 META_TYPE(BASE_NS::Math::IVec4);
235 META_TYPE(BASE_NS::Math::Quat);
236 META_TYPE(BASE_NS::Math::Mat3X3);
237 META_TYPE(BASE_NS::Math::Mat4X4);
238 META_TYPE(BASE_NS::Color);
239 META_TYPE(CORE_NS::Entity);
240 META_TYPE(CORE_NS::EntityReference);
241 
242 META_TYPE(BASE_NS::shared_ptr<const CORE_NS::IInterface>)
243 META_TYPE(BASE_NS::shared_ptr<CORE_NS::IInterface>)
244 META_TYPE(BASE_NS::weak_ptr<const CORE_NS::IInterface>)
245 META_TYPE(BASE_NS::weak_ptr<CORE_NS::IInterface>)
246 
247 CORE_BEGIN_NAMESPACE()
248 class IPropertyHandle;
249 DECLARE_PROPERTY_TYPE(CORE_NS::IPropertyHandle*);
250 CORE_END_NAMESPACE()
251 
252 META_TYPE(CORE_NS::IPropertyHandle*);
253 
254 #endif
255