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