1 /*
2 * Copyright (c) 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 META_EXT_ENGINE_INTERNAL_ACCESS_H
17 #define META_EXT_ENGINE_INTERNAL_ACCESS_H
18
19 #include <core/property/scoped_handle.h>
20
21 #include <meta/interface/detail/any.h>
22 #include <meta/interface/engine/intf_engine_value.h>
23 #include <meta/interface/interface_helpers.h>
24
META_BEGIN_NAMESPACE()25 META_BEGIN_NAMESPACE()
26
27 template<typename Type, typename AnyType, typename AccessType = Type>
28 class EngineInternalValueAccessImpl : public IntroduceInterfaces<IEngineInternalValueAccess> {
29 public:
30 IAny::Ptr CreateAny() const override
31 {
32 return IAny::Ptr(new AnyType);
33 }
34 bool IsCompatible(const CORE_NS::PropertyTypeDecl& type) const override
35 {
36 return MetaType<Type>::coreType == type;
37 }
38 AnyReturnValue SyncToEngine(const IAny& value, const EnginePropertyParams& params) const override
39 {
40 CORE_NS::ScopedHandle<Type> guard { params.handle };
41 return guard ? value.GetData(UidFromType<AccessType>(), (void*)((uintptr_t) & *guard + params.Offset()),
42 sizeof(Type)) /*NOLINT(bugprone-sizeof-expression)*/
43 : AnyReturn::FAIL;
44 }
45 AnyReturnValue SyncFromEngine(const EnginePropertyParams& params, IAny& out) const override
46 {
47 CORE_NS::ScopedHandle<const Type> guard { params.handle };
48 return guard ? out.SetData(UidFromType<AccessType>(), (const void*)((uintptr_t) & *guard + params.Offset()),
49 sizeof(Type)) /*NOLINT(bugprone-sizeof-expression)*/
50 : AnyReturn::FAIL;
51 }
52 };
53
54 template<typename Type>
55 class EngineInternalValueAccess : public EngineInternalValueAccessImpl<Type, Any<Type>> {};
56 template<typename Type>
57 class EngineInternalValueAccess<BASE_NS::vector<Type>>
58 : public EngineInternalValueAccessImpl<BASE_NS::vector<Type>, ArrayAny<Type>> {};
59
60 template<typename Type>
61 class EngineInternalArrayValueAccess : public IntroduceInterfaces<IEngineInternalValueAccess> {
62 public:
63 using InternalType = BASE_NS::vector<Type>;
64
CreateAny()65 IAny::Ptr CreateAny() const override
66 {
67 return IAny::Ptr(new ArrayAny<Type>);
68 }
IsCompatible(const CORE_NS::PropertyTypeDecl & type)69 bool IsCompatible(const CORE_NS::PropertyTypeDecl& type) const override
70 {
71 return MetaType<Type[]>::coreType == type;
72 }
SyncToEngine(const IAny & value,const EnginePropertyParams & params)73 AnyReturnValue SyncToEngine(const IAny& value, const EnginePropertyParams& params) const override
74 {
75 AnyReturnValue res = AnyReturn::FAIL;
76 CORE_NS::ScopedHandle<Type[]> guard { params.handle };
77 if (guard && params.property.metaData.containerMethods) {
78 BASE_NS::vector<Type> vec;
79 res = value.GetData(UidFromType<InternalType>(), &vec, sizeof(InternalType));
80 if (res) {
81 if (params.property.type.isArray) {
82 size_t size = params.property.count < vec.size() ? params.property.count : vec.size();
83 for (size_t i = 0; i != size; ++i) {
84 ((Type*)((uintptr_t) & *guard + params.Offset()))[i] = vec[i];
85 }
86 } else {
87 auto cont = params.property.metaData.containerMethods;
88 cont->resize(params.Offset(), vec.size());
89 for (size_t i = 0; i != vec.size(); ++i) {
90 *((Type*)cont->get(params.Offset(), i)) = vec[i];
91 }
92 }
93 }
94 }
95 return res;
96 }
SyncFromEngine(const EnginePropertyParams & params,IAny & out)97 AnyReturnValue SyncFromEngine(const EnginePropertyParams& params, IAny& out) const override
98 {
99 AnyReturnValue res = AnyReturn::FAIL;
100 CORE_NS::ScopedHandle<const Type[]> guard { params.handle };
101 if (guard && params.property.metaData.containerMethods) {
102 BASE_NS::vector<Type> vec;
103 if (params.property.type.isArray) {
104 vec.resize(params.property.count);
105 for (size_t i = 0; i != vec.size(); ++i) {
106 vec[i] = ((const Type*)((uintptr_t) & *guard + params.Offset()))[i];
107 }
108 } else {
109 auto cont = params.property.metaData.containerMethods;
110 vec.resize(cont->size(params.Offset()));
111 for (size_t i = 0; i != vec.size(); ++i) {
112 vec[i] = *((const Type*)cont->get(params.Offset(), i));
113 }
114 }
115 res = out.SetData(UidFromType<InternalType>(), &vec, sizeof(InternalType));
116 }
117 return res;
118 }
119 };
120
121 META_END_NAMESPACE()
122
123 #endif