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_INTERFACE_PROPERTY_CONSTRUCT_PROPERTY_H 17 #define META_INTERFACE_PROPERTY_CONSTRUCT_PROPERTY_H 18 19 #include <meta/interface/intf_any.h> 20 #include <meta/interface/intf_object_flags.h> 21 #include <meta/interface/intf_object_registry.h> 22 #include <meta/interface/property/property.h> 23 24 META_BEGIN_NAMESPACE() 25 26 struct ValuePtrBase {}; 27 28 template<typename Type, const META_NS::ClassInfo& ClassInfo> 29 struct ValuePtrInstance : ValuePtrBase { 30 static constexpr ObjectId ID = ClassInfo.Id(); 31 using TypePtr = typename Type::Ptr; 32 static_assert(IsInterfacePtr_v<TypePtr>, "Invalid type for ValuePtr"); 33 }; 34 35 template<typename Type> 36 struct ValuePtrImpl { 37 template<const META_NS::ClassInfo& ClassInfo> 38 using Instance = ValuePtrInstance<Type, ClassInfo>; 39 }; 40 template<typename Type, const META_NS::ClassInfo& ClassInfo> 41 using ValuePtr = ValuePtrInstance<Type, ClassInfo>; 42 43 template<typename T> 44 struct PropertyType { 45 using Type = T; 46 }; 47 template<typename T, const META_NS::ClassInfo& ClassInfo> 48 struct PropertyType<ValuePtr<T, ClassInfo>> { 49 using Type = typename ValuePtr<T, ClassInfo>::TypePtr; 50 }; 51 template<typename T> 52 using PropertyType_v = typename PropertyType<T>::Type; // NOLINT(readability-identifier-naming) 53 54 template<typename T> 55 Property<T> ConstructProperty(IObjectRegistry& obr, BASE_NS::string_view name, const T& value = {}, 56 ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 57 { 58 Property<T> p(NOCHECK, obr.GetPropertyRegister().Create(ClassId::StackProperty, name)); 59 if (auto i = interface_cast<IPropertyInternalAny>(p.GetProperty())) { 60 i->SetInternalAny(ConstructAny<T>(value)); 61 } 62 if (auto f = interface_cast<IObjectFlags>(p.GetProperty())) { 63 f->SetObjectFlags(flags); 64 } 65 return p; 66 } 67 68 template<typename T, typename = BASE_NS::enable_if_t<!BASE_NS::is_convertible_v<T*, ValuePtrBase*>>> 69 Property<T> ConstructProperty( 70 BASE_NS::string_view name, const T& value = {}, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 71 { 72 return ConstructProperty(GetObjectRegistry(), name, value, flags); 73 } 74 75 template<typename T, typename Param = typename T::TypePtr> 76 Property<typename T::TypePtr> ConstructProperty( 77 BASE_NS::string_view name, const Param& value = {}, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 78 { 79 auto& obr = GetObjectRegistry(); 80 Property<typename T::TypePtr> p(NOCHECK, obr.GetPropertyRegister().Create(ClassId::StackProperty, name)); 81 if (auto i = interface_cast<IPropertyInternalAny>(p.GetProperty())) { 82 auto obj = obr.Create<IAny>(T::ID); 83 if (!obj) { 84 CORE_LOG_E("invalid class id for ValuePtr"); 85 return nullptr; 86 } 87 i->SetInternalAny(obj); 88 } 89 auto access = p.GetUnlockedAccess(); 90 access.SetDefaultValueAny(Any<Param>(value)); 91 if (auto f = interface_cast<IObjectFlags>(p.GetProperty())) { 92 f->SetObjectFlags(flags); 93 } 94 return p; 95 } 96 97 template<typename T> 98 Property<PropertyType_v<T>> ConstructPropertyAny( 99 BASE_NS::string_view name, const IAny& value, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 100 { 101 auto p = ConstructProperty<T>(name, {}, flags); 102 if (p) { 103 p.GetUnlockedAccess().SetDefaultValueAny(value); 104 } 105 return p; 106 } 107 108 inline IProperty::Ptr ConstructPropertyAny( 109 BASE_NS::string_view name, const IAny& value, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 110 { 111 auto p = GetObjectRegistry().GetPropertyRegister().Create(ClassId::StackProperty, name); 112 if (auto i = interface_cast<IPropertyInternalAny>(p)) { 113 i->SetInternalAny(value.Clone(true)); 114 } 115 if (auto f = interface_cast<IObjectFlags>(p)) { 116 f->SetObjectFlags(flags); 117 } 118 return p; 119 } 120 121 // helpers to handle default values with Value Ptr stuff 122 template<typename T> 123 IAny::Ptr ConstructAnyHelper(T&& value) 124 { 125 return ConstructAny(BASE_NS::forward<T>(value)); 126 } 127 template<typename T> 128 IAny::Ptr ConstructAnyHelper(PropertyType_v<T> value) 129 { 130 return ConstructAny<PropertyType_v<T>>(BASE_NS::move(value)); 131 } 132 template<typename T, typename Param, typename = typename T::TypePtr> 133 IAny::Ptr ConstructAnyHelper(Param&& value) 134 { 135 return ConstructAny(BASE_NS::forward<Param>(value)); 136 } 137 138 META_END_NAMESPACE() 139 140 #endif 141