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