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