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 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 65 IAny::Ptr CreateAny() const override 66 { 67 return IAny::Ptr(new ArrayAny<Type>); 68 } 69 bool IsCompatible(const CORE_NS::PropertyTypeDecl& type) const override 70 { 71 return MetaType<Type[]>::coreType == type; 72 } 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 } 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