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 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 // interesting why constexpr uint32_t operator|(PropertyFlags a, PropertyFlags b) not valid?
51 constexpr uint32_t operator|(uint32_t a, PropertyFlags b)
52 {
53 return ((uint32_t)a) | ((uint32_t)b);
54 }
55
56 /** Property type declaration */
57 struct PropertyTypeDecl {
58 /** Is this a c-style array. (size unknown) */
59 bool isArray;
60 /** Type hash */
61 uint64_t typeHash;
62 /** Compare hash */
63 uint64_t compareHash;
64 /** Type name */
65 BASE_NS::string_view name;
66 /** Return compare hash of this property type declaration */
uint64_tPropertyTypeDecl67 constexpr operator uint64_t() const
68 {
69 return compareHash;
70 }
71 };
72
73 /** Equality operator, returns true if types are the same */
74 constexpr inline bool operator==(const PropertyTypeDecl& aA, const PropertyTypeDecl& aB)
75 {
76 return aA.compareHash == aB.compareHash;
77 }
78
79 /** Inequality operator, returns true if types are not the same */
80 constexpr inline bool operator!=(const PropertyTypeDecl& aA, const PropertyTypeDecl& aB)
81 {
82 return aA.compareHash != aB.compareHash;
83 }
84
85 /** @} */
86 struct EnumMetaData {
87 BASE_NS::string_view name;
88 BASE_NS::string_view displayName;
89 int64_t value;
90 };
91
92 struct Property; // Forward declare the struct.
93
94 struct MetaData {
95 BASE_NS::array_view<const Property> memberProperties; // properties of the actual "type"
96 const struct ContainerApi* containerMethods;
97 BASE_NS::array_view<const EnumMetaData> enumMetaData;
98 };
99
100 struct Property {
101 BASE_NS::string_view name;
102 uint64_t hash;
103 PropertyTypeDecl type;
104 size_t count; // Count of elements in array, 1 if not an array
105 size_t size; // Size of property in bytes.
106 uintptr_t offset; // Offset to data blob
107 BASE_NS::string_view displayName;
108 uint32_t flags; // PropertyFlags combination. (unused)
109 MetaData metaData;
110 };
111
112 struct ContainerApi {
113 size_t (*size)(uintptr_t container); // return the size of container
114 void (*resize)(uintptr_t container, size_t newSize); // resize the container.
115 void (*erase)(uintptr_t container, size_t index); // remove element from container
116 uintptr_t (*insert)(uintptr_t container, size_t index); // insert element at location to container
117 uintptr_t (*get)(uintptr_t container,
118 size_t index); // get value by indexed property from container (returns uintptr_t type pointer to the element)
119 Property property; // property type for the elements in array or container
120 };
121
122 #define PROPERTYTYPE_DEFINE(a, b) \
123 CORE_NS::PropertyTypeDecl \
124 { \
125 BASE_NS::is_array_v<a>, BASE_NS::CompileTime::FNV1aHash(#b), \
126 BASE_NS::CompileTime::FNV1aHash(BASE_NS::is_array_v<a> ? #b "_ARRAY" : #b), #b \
127 }
128 #define PROPERTYTYPE(b) PROPERTYTYPE_DEFINE(b, b)
129 #define PROPERTYTYPE_ARRAY(b) PROPERTYTYPE_DEFINE(b[], b)
130 CORE_END_NAMESPACE()
131
132 BASE_BEGIN_NAMESPACE()
133 template<typename T>
134 uint64_t hash(const T& b);
135
136 template<>
hash(const CORE_NS::PropertyTypeDecl & value)137 inline uint64_t hash(const CORE_NS::PropertyTypeDecl& value)
138 {
139 return value.compareHash;
140 }
141 BASE_END_NAMESPACE()
142 #endif // API_CORE_PROPERTY_PROPERTY_H
143