1 /*
2 * Copyright (c) 2022 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 API_CORE_PROPERTY_PROPERTY_H
17 #define API_CORE_PROPERTY_PROPERTY_H
18
19 #include <cstddef>
20 #include <cstdint>
21
22 #include <base/containers/array_view.h>
23 #include <base/containers/string_view.h>
24 #include <base/namespace.h>
25 #include <base/util/compile_time_hashes.h>
26 #include <core/namespace.h>
27
28 CORE_BEGIN_NAMESPACE()
29 /** \addtogroup group_property_propertytypes
30 * @{
31 */
32 /** Property flags */
33 enum class PropertyFlags : uint32_t {
34 /** Min */
35 HAS_MIN = 1,
36 /** Max */
37 HAS_MAX = 2,
38 /** slider */
39 IS_SLIDER = 4,
40 /** Hide From UI */
41 IS_HIDDEN = 8,
42 /** Readonly */
43 IS_READONLY = 16,
44 /** NO_SERIALIZE */
45 NO_SERIALIZE = 32,
46 /** Property is a bit flag container */
47 IS_BITFIELD = 64,
48 };
49
50 constexpr uint32_t operator|(PropertyFlags a, PropertyFlags b)
51 {
52 return ((uint32_t)a) | ((uint32_t)b);
53 }
54
55 constexpr uint32_t operator|(uint32_t a, PropertyFlags b)
56 {
57 return ((uint32_t)a) | ((uint32_t)b);
58 }
59
60 /** Property type declaration */
61 struct PropertyTypeDecl {
62 /** Is this a c-style array. (size unknown) */
63 bool isArray;
64 /** Size of the type in bytes. For arrays this is the size of a single element. */
65 uint32_t byteSize;
66 /** Type hash */
67 uint64_t typeHash;
68 /** Compare hash */
69 uint64_t compareHash;
70 /** Type name */
71 BASE_NS::string_view name;
72 /** Return compare hash of this property type declaration */
uint64_tPropertyTypeDecl73 constexpr operator uint64_t() const
74 {
75 return compareHash;
76 }
77 };
78
79 /** Equality operator, returns true if types are the same */
80 constexpr inline bool operator==(const PropertyTypeDecl& aA, const PropertyTypeDecl& aB)
81 {
82 return aA.compareHash == aB.compareHash;
83 }
84
85 /** Inequality operator, returns true if types are not the same */
86 constexpr inline bool operator!=(const PropertyTypeDecl& aA, const PropertyTypeDecl& aB)
87 {
88 return aA.compareHash != aB.compareHash;
89 }
90
91 /** @} */
92 /** Metadata of an enumeratio value (enumerator). */
93 struct EnumMetaData {
94 BASE_NS::string_view name;
95 BASE_NS::string_view displayName;
96 int64_t value;
97 };
98
99 struct Property; // Forward declare the struct.
100
101 /** Metadata of a type. */
102 struct MetaData {
103 BASE_NS::array_view<const Property> memberProperties; // properties of the actual "type"
104 const struct ContainerApi* containerMethods;
105 BASE_NS::array_view<const EnumMetaData> enumMetaData;
106 };
107
108 /** Metadata of a variable. */
109 struct Property {
110 BASE_NS::string_view name;
111 uint64_t hash;
112 PropertyTypeDecl type;
113 size_t count; // Count of elements in array, 1 if not an array
114 size_t size; // Size of property in bytes.
115 uintptr_t offset; // Offset to data blob
116 BASE_NS::string_view displayName;
117 uint32_t flags; // PropertyFlags combination.
118 MetaData metaData;
119 };
120
121 /** Functions for accessing a container and metadata of the containers element type. */
122 struct ContainerApi {
123 // return the size of container
124 size_t (*size)(uintptr_t container);
125 // resize the container.
126 void (*resize)(uintptr_t container, size_t newSize);
127 // remove element from container
128 void (*erase)(uintptr_t container, size_t index);
129 // insert element at location to container
130 uintptr_t (*insert)(uintptr_t container, size_t index);
131 // get value by indexed property from container (returns uintptr_t type pointer to the element)
132 uintptr_t (*get)(uintptr_t container, size_t index);
133 // property type for the elements in array or container
134 Property property;
135 };
136
137 /** Fills a PropertyTypeDecl for the given type.
138 * @param baseName String used as the type's name. typeHash and compareHash are based on this string.
139 * @return PropertyTypeDecl for the given type.
140 */
141 template<typename T, typename = BASE_NS::enable_if_t<!BASE_NS::is_array_v<T>>>
MakePropertyTypeDecl(const char * baseName)142 constexpr CORE_NS::PropertyTypeDecl MakePropertyTypeDecl(const char* baseName)
143 {
144 return CORE_NS::PropertyTypeDecl { false, static_cast<uint32_t>(sizeof(T)),
145 BASE_NS::CompileTime::FNV1aHash(baseName), BASE_NS::CompileTime::FNV1aHash(baseName), baseName };
146 }
147
148 /** Fills a PropertyTypeDecl for the given array type.
149 * @param baseName String used as the type's name. typeHash is based on this string.
150 * @param arrayTypeName compareHash is based on this string.
151 * @return PropertyTypeDecl for the given type.
152 */
153 template<typename T, typename = BASE_NS::enable_if_t<BASE_NS::is_array_v<T>>>
MakePropertyTypeDecl(const char * baseName,const char * arrayTypeName)154 constexpr CORE_NS::PropertyTypeDecl MakePropertyTypeDecl(const char* baseName, const char* arrayTypeName)
155 {
156 return CORE_NS::PropertyTypeDecl { true, static_cast<uint32_t>(sizeof(BASE_NS::remove_extent_t<T>)),
157 BASE_NS::CompileTime::FNV1aHash(baseName), BASE_NS::CompileTime::FNV1aHash(arrayTypeName), baseName };
158 }
159
160 #define PROPERTYNAME(b) #b
161 #define ARRAY_PROPERTYNAME(b) (#b "_ARRAY")
162
163 /** Helper for filling a PropertyTypeDecl for the given type. */
164 #define PROPERTYTYPE(b) CORE_NS::MakePropertyTypeDecl<b>(PROPERTYNAME(b))
165
166 /** Helper for filling a PropertyTypeDecl for an array of the given type. */
167 #define PROPERTYTYPE_ARRAY(b) CORE_NS::MakePropertyTypeDecl<b[]>(PROPERTYNAME(b), ARRAY_PROPERTYNAME(b))
168 CORE_END_NAMESPACE()
169
170 BASE_BEGIN_NAMESPACE()
171 template<typename T>
172 uint64_t hash(const T&);
173
174 template<>
hash(const CORE_NS::PropertyTypeDecl & value)175 inline uint64_t hash(const CORE_NS::PropertyTypeDecl& value)
176 {
177 return value.compareHash;
178 }
179 BASE_END_NAMESPACE()
180 #endif // API_CORE_PROPERTY_PROPERTY_H
181