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#include <PropertyTools/property_api_impl.h> 17#include <new> 18 19#include <base/containers/array_view.h> 20#include <base/containers/iterator.h> 21#include <base/namespace.h> 22#include <core/log.h> 23#include <core/namespace.h> 24#include <core/property/intf_property_api.h> 25#include <core/property/intf_property_handle.h> 26#include <core/property/property.h> 27 28CORE_BEGIN_NAMESPACE() 29template<typename BlockType> 30PropertyApiImpl<BlockType>::PropertyApiImpl() = default; 31 32template<typename BlockType> 33PropertyApiImpl<BlockType>::PropertyApiImpl(BlockType* data, BASE_NS::array_view<const Property> aProps) 34 : data_(data), componentMetadata_(aProps) 35{ 36 // Create a typeid by hashing the metadata information. 37 typeHash_ = 0; 38 for (auto& t : aProps) { 39 BASE_NS::HashCombine(typeHash_, t.offset); 40 BASE_NS::HashCombine(typeHash_, t.count); 41 BASE_NS::HashCombine(typeHash_, t.type.compareHash); 42 BASE_NS::HashCombine(typeHash_, t.type.typeHash); 43 BASE_NS::HashCombine(typeHash_, t.hash); 44 BASE_NS::HashCombine(typeHash_, t.size); 45 } 46} 47 48template<typename BlockType> 49size_t PropertyApiImpl<BlockType>::PropertyCount() const 50{ 51 if (owner_) { 52 return owner_->PropertyCount(); 53 } 54 return componentMetadata_.size(); 55} 56 57// Metadata for property 58template<typename BlockType> 59const Property* PropertyApiImpl<BlockType>::MetaData(size_t aIndex) const 60{ 61 if (owner_) { 62 return owner_->MetaData(aIndex); 63 } 64 return &componentMetadata_[aIndex]; 65} 66 67// Metadata for properties 68template<typename BlockType> 69BASE_NS::array_view<const Property> PropertyApiImpl<BlockType>::MetaData() const 70{ 71 if (owner_) { 72 return owner_->MetaData(); 73 } 74 return componentMetadata_; 75} 76 77template<typename BlockType> 78IPropertyHandle* PropertyApiImpl<BlockType>::Create() const 79{ 80 auto ret = new PropertyApiImpl<BlockType>(); 81 ret->owner_ = Owner(); 82 ret->typeHash_ = Type(); 83 ret->data_ = new BlockType(); 84 return ret; 85} 86 87template<typename BlockType> 88IPropertyHandle* PropertyApiImpl<BlockType>::Clone(const IPropertyHandle* src) const 89{ 90 if (src->Owner() == this) { 91 auto* h = static_cast<const PropertyApiImpl<BlockType>*>(src); 92 auto* ret = new PropertyApiImpl<BlockType>(); 93 ret->owner_ = Owner(); 94 ret->typeHash_ = Type(); 95 ret->data_ = new BlockType(); 96 *ret->data_ = *h->data_; 97 return ret; 98 } 99 return nullptr; 100} 101 102template<typename BlockType> 103void PropertyApiImpl<BlockType>::Release(IPropertyHandle* dst) const 104{ 105 if (dst) { 106 if (dst->Owner() == Owner()) { 107 // we can only destroy things we "own" (know) 108 auto* handle = static_cast<PropertyApiImpl<BlockType>*>(dst); 109 if (handle->owner_) { 110 // and only the ones that own the data.. 111 delete handle; 112 } 113 } 114 } 115} 116 117template<typename BlockType> 118uint32_t PropertyApiImpl<BlockType>::GetGeneration() const 119{ 120 return generationCount_; 121} 122 123template<typename BlockType> 124IPropertyHandle* PropertyApiImpl<BlockType>::GetData() 125{ 126 return this; 127} 128 129template<typename BlockType> 130const IPropertyHandle* PropertyApiImpl<BlockType>::GetData() const 131{ 132 return this; 133} 134 135template<typename BlockType> 136const IPropertyApi* PropertyApiImpl<BlockType>::Owner() const 137{ 138 if (owner_) { 139 return owner_; 140 } 141 return this; 142} 143 144template<typename BlockType> 145size_t PropertyApiImpl<BlockType>::Size() const 146{ 147 return sizeof(BlockType); 148} 149 150template<typename BlockType> 151const void* PropertyApiImpl<BlockType>::RLock() const 152{ 153 CORE_ASSERT(!wLocked_); 154 rLocked_++; 155 return data_; 156} 157 158template<typename BlockType> 159void PropertyApiImpl<BlockType>::RUnlock() const 160{ 161 CORE_ASSERT(rLocked_ > 0); 162 rLocked_--; 163} 164 165template<typename BlockType> 166void* PropertyApiImpl<BlockType>::WLock() 167{ 168 CORE_ASSERT(rLocked_ <= 1 && !wLocked_); 169 wLocked_ = true; 170 return data_; 171} 172 173template<typename BlockType> 174void PropertyApiImpl<BlockType>::WUnlock() 175{ 176 CORE_ASSERT(wLocked_); 177 wLocked_ = false; 178 generationCount_++; 179} 180 181template<typename BlockType> 182uint64_t PropertyApiImpl<BlockType>::Type() const 183{ 184 return typeHash_; 185} 186 187template<> 188inline size_t PropertyApiImpl<void>::Size() const 189{ 190 return 0; 191} 192 193template<> 194inline IPropertyHandle* PropertyApiImpl<void>::Create() const 195{ 196 auto ret = new PropertyApiImpl<void>(); 197 ret->owner_ = owner_; 198 ret->data_ = nullptr; 199 return ret; 200} 201 202template<> 203inline IPropertyHandle* PropertyApiImpl<void>::Clone(const IPropertyHandle* src) const 204{ 205 if (src->Owner() == this) { 206 auto* ret = new PropertyApiImpl<void>(); 207 ret->owner_ = owner_; 208 return ret; 209 } 210 return nullptr; 211} 212 213template<> 214inline void PropertyApiImpl<void>::Release(IPropertyHandle* dst) const 215{ 216 if (dst) { 217 if (dst->Owner() == this) { 218 // we can only destroy things we "own" (know) 219 auto* handle = static_cast<PropertyApiImpl<void>*>(dst); 220 delete handle; 221 } 222 } 223} 224 225CORE_END_NAMESPACE() 226