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 /** 55 * @brief Construct property 56 * @param obr Object registry instance 57 * @param name Name of the property 58 * @param value Default value for the property 59 * @param flags Object flags for the property 60 * @return Typed property 61 */ 62 template<typename T> 63 Property<T> ConstructProperty(IObjectRegistry& obr, BASE_NS::string_view name, const T& value = {}, 64 ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 65 { 66 Property<T> p(NOCHECK, obr.GetPropertyRegister().Create(ClassId::StackProperty, name)); 67 if (auto i = interface_cast<IPropertyInternalAny>(p.GetProperty())) { 68 i->SetInternalAny(ConstructAny<T>(value)); 69 } 70 if (auto f = interface_cast<IObjectFlags>(p.GetProperty())) { 71 f->SetObjectFlags(flags); 72 } 73 return p; 74 } 75 /** 76 * @brief Construct property 77 * @param name Name of the property 78 * @param value Default value for the property 79 * @param flags Object flags for the property 80 * @return Typed property 81 */ 82 template<typename T, typename = BASE_NS::enable_if_t<!BASE_NS::is_convertible_v<T*, ValuePtrBase*>>> 83 Property<T> ConstructProperty( 84 BASE_NS::string_view name, const T& value = {}, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 85 { 86 return ConstructProperty(GetObjectRegistry(), name, value, flags); 87 } 88 89 /** 90 * @brief Construct property for value pointer type 91 * @param name Name of the property 92 * @param value Default value for the property 93 * @param flags Object flags for the property 94 * @return Typed property 95 */ 96 template<typename T, typename Param = typename T::TypePtr> 97 Property<typename T::TypePtr> ConstructProperty( 98 BASE_NS::string_view name, const Param& value = {}, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 99 { 100 auto& obr = GetObjectRegistry(); 101 Property<typename T::TypePtr> p(NOCHECK, obr.GetPropertyRegister().Create(ClassId::StackProperty, name)); 102 if (auto i = interface_cast<IPropertyInternalAny>(p.GetProperty())) { 103 auto obj = obr.Create<IAny>(T::ID); 104 if (!obj) { 105 CORE_LOG_E("invalid class id for ValuePtr"); 106 return nullptr; 107 } 108 i->SetInternalAny(obj); 109 } 110 auto access = p.GetUnlockedAccess(); 111 access.SetDefaultValueAny(Any<Param>(value)); 112 if (auto f = interface_cast<IObjectFlags>(p.GetProperty())) { 113 f->SetObjectFlags(flags); 114 } 115 return p; 116 } 117 118 /** 119 * @brief Construct property with default IAny value 120 * @param name Name of the property 121 * @param value Default value for the property 122 * @param flags Object flags for the property 123 * @return Typed property 124 */ 125 template<typename T> 126 Property<PropertyType_v<T>> ConstructPropertyAny( 127 BASE_NS::string_view name, const IAny& value, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 128 { 129 auto p = ConstructProperty<T>(name, {}, flags); 130 if (p) { 131 p.GetUnlockedAccess().SetDefaultValueAny(value); 132 } 133 return p; 134 } 135 136 /** 137 * @brief Construct property using IAny as type for the property 138 * @param name Name of the property 139 * @param value Default value for the property 140 * @param flags Object flags for the property 141 * @return typeless property 142 */ 143 inline IProperty::Ptr ConstructPropertyAny( 144 BASE_NS::string_view name, const IAny& value, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 145 { 146 auto p = GetObjectRegistry().GetPropertyRegister().Create(ClassId::StackProperty, name); 147 if (auto i = interface_cast<IPropertyInternalAny>(p)) { 148 i->SetInternalAny(value.Clone(true)); 149 } 150 if (auto f = interface_cast<IObjectFlags>(p)) { 151 f->SetObjectFlags(flags); 152 } 153 return p; 154 } 155 156 // helpers to handle default values with Value Ptr stuff 157 template<typename T> 158 IAny::Ptr ConstructAnyHelper(T&& value) 159 { 160 return ConstructAny(BASE_NS::forward<T>(value)); 161 } 162 template<typename T> 163 IAny::Ptr ConstructAnyHelper(PropertyType_v<T> value) 164 { 165 return ConstructAny<PropertyType_v<T>>(BASE_NS::move(value)); 166 } 167 template<typename T, typename Param, typename = typename T::TypePtr> 168 IAny::Ptr ConstructAnyHelper(Param&& value) 169 { 170 return ConstructAny(BASE_NS::forward<Param>(value)); 171 } 172 173 META_END_NAMESPACE() 174 175 #endif 176