• 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#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