• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 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 <new>
17
18#include <base/containers/array_view.h>
19#include <base/containers/iterator.h>
20#include <base/namespace.h>
21#include <core/log.h>
22#include <core/namespace.h>
23#include <core/property/intf_property_api.h>
24#include <core/property/intf_property_handle.h>
25#include <core/property/property.h>
26#include <core/property_tools/property_api_impl.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#ifndef NDEBUG
154    CORE_ASSERT(!wLocked_);
155    rLocked_++;
156#endif
157    return data_;
158}
159
160template<typename BlockType>
161void PropertyApiImpl<BlockType>::RUnlock() const
162{
163#ifndef NDEBUG
164    CORE_ASSERT(rLocked_ > 0);
165    rLocked_--;
166#endif
167}
168
169template<typename BlockType>
170void* PropertyApiImpl<BlockType>::WLock()
171{
172#ifndef NDEBUG
173    CORE_ASSERT(rLocked_ <= 1 && !wLocked_);
174    wLocked_ = true;
175#endif
176    return data_;
177}
178
179template<typename BlockType>
180void PropertyApiImpl<BlockType>::WUnlock()
181{
182#ifndef NDEBUG
183    CORE_ASSERT(wLocked_);
184    wLocked_ = false;
185#endif
186    generationCount_++;
187}
188
189template<typename BlockType>
190uint64_t PropertyApiImpl<BlockType>::Type() const
191{
192    return typeHash_;
193}
194
195template<>
196inline size_t PropertyApiImpl<void>::Size() const
197{
198    return 0;
199}
200
201template<>
202inline IPropertyHandle* PropertyApiImpl<void>::Create() const
203{
204    auto ret = new PropertyApiImpl<void>();
205    ret->owner_ = owner_;
206    ret->data_ = nullptr;
207    return ret;
208}
209
210template<>
211inline IPropertyHandle* PropertyApiImpl<void>::Clone(const IPropertyHandle* src) const
212{
213    if (src->Owner() == this) {
214        auto* ret = new PropertyApiImpl<void>();
215        ret->owner_ = owner_;
216        return ret;
217    }
218    return nullptr;
219}
220
221template<>
222inline void PropertyApiImpl<void>::Release(IPropertyHandle* dst) const
223{
224    if (dst) {
225        if (dst->Owner() == this) {
226            // we can only destroy things we "own" (know)
227            auto* handle = static_cast<PropertyApiImpl<void>*>(dst);
228            delete handle;
229        }
230    }
231}
232
233CORE_END_NAMESPACE()
234