• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 CORE__ECS_HELPER__PROPERTY_TOOLS__PROPERTY_VALUE_H
17 #define CORE__ECS_HELPER__PROPERTY_TOOLS__PROPERTY_VALUE_H
18 
19 #include <base/util/log.h>
20 #include <base/containers/type_traits.h>
21 #include <core/property/property_types.h>
22 
CORE_BEGIN_NAMESPACE()23 CORE_BEGIN_NAMESPACE()
24 class PropertyValue {
25 public:
26     PropertyValue() noexcept : count_(0), data_(nullptr), index_(0) {}
27     ~PropertyValue() = default;
28     PropertyValue(const PropertyValue& other) noexcept
29         : type_(other.type_), count_(other.count_), data_(other.data_), index_(other.index_)
30     {}
31 
32     PropertyValue(PropertyValue&& other) noexcept
33         : type_(other.type_), // exchange(other.type_, PropertyType::INVALID)),
34           count_(BASE_NS::exchange(other.count_, 0)), data_(BASE_NS::exchange(other.data_, nullptr)),
35           index_(BASE_NS::exchange(other.index_, 0))
36     {}
37     explicit constexpr PropertyValue(const Property* type, void* rawData, size_t cnt) noexcept
38         : type_(type), count_(cnt), data_(rawData), index_(0)
39     {}
40 
41     constexpr size_t Size() const
42     {
43         return count_;
44     }
45     constexpr PropertyTypeDecl GetType() const
46     {
47         return type_->type;
48     }
49     constexpr operator PropertyTypeDecl() const
50     {
51         return type_->type;
52     }
53     constexpr bool operator==(const PropertyTypeDecl& other) const
54     {
55         return type_->type.compareHash == other.compareHash;
56     }
57 
58     BASE_NS::array_view<const Property> MetaData() const
59     {
60         if (type_) {
61             return type_->metaData.memberProperties;
62         }
63         return {};
64     }
65     const Property* MetaData(size_t index) const
66     {
67         if (type_) {
68             const auto& meta = type_->metaData.memberProperties;
69             if (index < meta.size()) {
70                 return &meta[index];
71             }
72         }
73         return nullptr;
74     }
75 
76     // void* access
77     explicit constexpr operator void*()
78     {
79         return data_;
80     }
81     explicit constexpr operator void const*() const
82     {
83         return data_;
84     }
85 
86     // safe
87     const PropertyValue operator[](const size_t index) const
88     {
89         BASE_ASSERT(type_->type.isArray); // This accessor type is valid only for arrays.
90         BASE_ASSERT(index < type_->count);
91         return PropertyValue(type_, data_, 1, index);
92     }
93     PropertyValue operator[](const size_t index)
94     {
95         BASE_ASSERT(type_->type.isArray); // This accessor type is valid only for arrays.
96         BASE_ASSERT(index < type_->count);
97         return PropertyValue(type_, data_, 1, index);
98     }
99 
100     const PropertyValue operator[](BASE_NS::string_view name) const
101     {
102         uintptr_t offset = (uintptr_t)data_;
103         const auto nameHash = BASE_NS::FNV1aHash(name.data(), name.size());
104         for (const auto& p : type_->metaData.memberProperties) {
105             if ((nameHash == p.hash) && (p.name == name)) {
106                 return PropertyValue(&p, (void*)(offset + p.offset), p.count);
107             }
108         }
109         // no such member property
110         return {};
111     }
112 
113     // unsafe
114     template<typename T>
115     [[deprecated]] constexpr operator T() const
116     {
117         return reinterpret_cast<T*>(data_)[index_];
118     }
119 
120     template<typename T>
121     [[deprecated]] constexpr operator T&()
122     {
123         return reinterpret_cast<T*>(data_)[index_];
124     }
125 
126     template<typename T>
127     [[deprecated]] PropertyValue& operator=(T v)
128     {
129         reinterpret_cast<T*>(data_)[index_] = v;
130         return *this;
131     }
132 
133     PropertyValue& operator=(const PropertyValue& other) noexcept
134     {
135         if (this != &other) {
136             type_ = other.type_;
137             count_ = other.count_;
138             data_ = other.data_;
139             index_ = other.index_;
140         }
141         return *this;
142     }
143     PropertyValue& operator=(PropertyValue&& other) noexcept
144     {
145         if (this != &other) {
146             type_ = BASE_NS::exchange(other.type_, {});
147             count_ = BASE_NS::exchange(other.count_, 0);
148             data_ = BASE_NS::exchange(other.data_, nullptr);
149             index_ = BASE_NS::exchange(other.index_, 0);
150         }
151         return *this;
152     }
153 
154 private:
155     const Property* type_ { nullptr };
156     size_t count_;
157     void* data_;
158     size_t index_;
159     explicit constexpr PropertyValue(const Property* type, void* rawData, size_t cnt, size_t index)
160         : type_(type), count_(cnt), data_(rawData), index_(index)
161     {}
162 };
163 CORE_END_NAMESPACE()
164 
165 #endif // CORE__ECS_HELPER__PROPERTY_TOOLS__PROPERTY_VALUE_H
166