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/ext/engine/core_any.h>
22 #include <meta/ext/engine/core_enum_any.h>
23 #include <meta/interface/engine/intf_engine_value.h>
24 #include <meta/interface/interface_helpers.h>
25
META_BEGIN_NAMESPACE()26 META_BEGIN_NAMESPACE()
27
28 namespace Internal {
29 template<typename T>
30 struct IsArray {
31 static constexpr const bool VALUE = false;
32 using ItemType = T;
33 };
34 template<typename T>
35 struct IsArray<BASE_NS::vector<T>> {
36 static constexpr const bool VALUE = true;
37 using ItemType = T;
38 };
39 template<typename Type, typename... CompatType>
40 IAny::Ptr ConstructCoreAny(const CORE_NS::Property& p)
41 {
42 if constexpr (Internal::IsArray<Type>::VALUE) {
43 using ItemType = typename Internal::IsArray<Type>::ItemType;
44 if constexpr ((is_enum_v<Type> || ... || is_enum_v<CompatType>)) {
45 return IAny::Ptr(new ArrayCoreEnumAny<ItemType, StaticCastConv, CompatType...>(p));
46 }
47 return IAny::Ptr(new ArrayCoreAny<ItemType, StaticCastConv, CompatType...>(p));
48 } else {
49 if constexpr ((is_enum_v<Type> || ... || is_enum_v<CompatType>)) {
50 return IAny::Ptr(new CoreEnumAny<Type, StaticCastConv, CompatType...>(p));
51 }
52 return IAny::Ptr(new CoreAny<Type, StaticCastConv, CompatType...>(p));
53 }
54 }
55 } // namespace Internal
56 template<typename Type, typename AccessType = Type>
57 class EngineInternalValueAccess : public IntroduceInterfaces<IEngineInternalValueAccess> {
58 public:
59 IAny::Ptr CreateAny(const CORE_NS::Property& p) const override
60 {
61 if constexpr (BASE_NS::is_same_v<Type, AccessType>) {
62 return Internal::ConstructCoreAny<AccessType>(p);
63 } else {
64 return Internal::ConstructCoreAny<AccessType, Type>(p);
65 }
66 }
67 bool IsCompatible(const CORE_NS::PropertyTypeDecl& type) const override
68 {
69 return MetaType<Type>::coreType == type;
70 }
71 AnyReturnValue SyncToEngine(const IAny& value, const EnginePropertyParams& params) const override
72 {
73 CORE_NS::ScopedHandle<Type> guard { params.handle.Handle() };
74 return guard ? value.GetData(UidFromType<Type>(), (void*)((uintptr_t) & *guard + params.Offset()),
75 sizeof(Type)) /*NOLINT(bugprone-sizeof-expression)*/
76 : AnyReturn::FAIL;
77 }
78 AnyReturnValue SyncFromEngine(const EnginePropertyParams& params, IAny& out) const override
79 {
80 CORE_NS::ScopedHandle<const Type> guard { params.handle.Handle() };
81 return guard ? out.SetData(UidFromType<Type>(), (const void*)((uintptr_t) & *guard + params.Offset()),
82 sizeof(Type)) /*NOLINT(bugprone-sizeof-expression)*/
83 : AnyReturn::FAIL;
84 }
85 };
86
87 /// Class that encapsulates the reading and writing to the core array property and the any type used
88 template<typename Type>
89
90 class EngineInternalArrayValueAccess : public IntroduceInterfaces<IEngineInternalValueAccess> {
91 public:
92 using InternalType = BASE_NS::vector<Type>;
93
94 IAny::Ptr CreateAny(const CORE_NS::Property& p) const override
95 {
96 return Internal::ConstructCoreAny<InternalType>(p);
97 }
98 bool IsCompatible(const CORE_NS::PropertyTypeDecl& type) const override
99 {
100 return MetaType<Type[]>::coreType == type;
101 }
102 AnyReturnValue SyncToEngine(const IAny& value, const EnginePropertyParams& params) const override
103 {
104 AnyReturnValue res = AnyReturn::FAIL;
105 CORE_NS::ScopedHandle<Type[]> guard { params.handle.Handle() };
106 if (guard && params.property.metaData.containerMethods) {
107 BASE_NS::vector<Type> vec;
108 res = value.GetData(UidFromType<InternalType>(), &vec, sizeof(InternalType));
109 if (res) {
110 if (params.property.type.isArray) {
111 size_t size = params.property.count < vec.size() ? params.property.count : vec.size();
112 for (size_t i = 0; i != size; ++i) {
113 ((Type*)((uintptr_t) & *guard + params.Offset()))[i] = vec[i];
114 }
115 } else {
116 auto cont = params.property.metaData.containerMethods;
117 cont->resize(params.Offset(), vec.size());
118 for (size_t i = 0; i != vec.size(); ++i) {
119 *((Type*)cont->get(params.Offset(), i)) = vec[i];
120 }
121 }
122 }
123 }
124 return res;
125 }
126 AnyReturnValue SyncFromEngine(const EnginePropertyParams& params, IAny& out) const override
127 {
128 AnyReturnValue res = AnyReturn::FAIL;
129 CORE_NS::ScopedHandle<const Type[]> guard { params.handle.Handle() };
130 if (guard && params.property.metaData.containerMethods) {
131 BASE_NS::vector<Type> vec;
132 if (params.property.type.isArray) {
133 vec.resize(params.property.count);
134 for (size_t i = 0; i != vec.size(); ++i) {
135 vec[i] = ((const Type*)((uintptr_t) & *guard + params.Offset()))[i];
136 }
137 } else {
138 auto cont = params.property.metaData.containerMethods;
139 vec.resize(cont->size(params.Offset()));
140 for (size_t i = 0; i != vec.size(); ++i) {
141 vec[i] = *((const Type*)cont->get(params.Offset(), i));
142 }
143 }
144 res = out.SetData(UidFromType<InternalType>(), &vec, sizeof(InternalType));
145 }
146 return res;
147 }
148 };
149
150 META_END_NAMESPACE()
151
152 #endif