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