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