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(IAny::Ptr(new Any<T>)); 61 } 62 auto access = p.GetUnlockedAccess(); 63 access.SetDefaultValue(value); 64 if (auto f = interface_cast<IObjectFlags>(p.GetProperty())) { 65 f->SetObjectFlags(flags); 66 } 67 return p; 68 } 69 70 template<typename T, typename = BASE_NS::enable_if_t<!BASE_NS::is_convertible_v<T*, ValuePtrBase*>>> 71 Property<T> ConstructProperty( 72 BASE_NS::string_view name, const T& value = {}, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 73 { 74 return ConstructProperty(GetObjectRegistry(), name, value, flags); 75 } 76 77 template<typename T, typename Param = typename T::TypePtr> 78 Property<typename T::TypePtr> ConstructProperty( 79 BASE_NS::string_view name, const Param& value = {}, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 80 { 81 auto& obr = GetObjectRegistry(); 82 Property<typename T::TypePtr> p(NOCHECK, obr.GetPropertyRegister().Create(ClassId::StackProperty, name)); 83 if (auto i = interface_cast<IPropertyInternalAny>(p.GetProperty())) { 84 auto obj = obr.Create<IAny>(T::ID); 85 if (!obj) { 86 CORE_LOG_E("invalid class id for ValuePtr"); 87 return nullptr; 88 } 89 i->SetInternalAny(obj); 90 } 91 auto access = p.GetUnlockedAccess(); 92 access.SetDefaultValueAny(Any<Param>(value)); 93 if (auto f = interface_cast<IObjectFlags>(p.GetProperty())) { 94 f->SetObjectFlags(flags); 95 } 96 return p; 97 } 98 99 inline IProperty::Ptr ConstructPropertyAny( 100 BASE_NS::string_view name, const IAny& value, ObjectFlagBitsValue flags = ObjectFlagBits::SERIALIZE) 101 { 102 auto p = GetObjectRegistry().GetPropertyRegister().Create(ClassId::StackProperty, name); 103 if (auto i = interface_cast<IPropertyInternalAny>(p)) { 104 i->SetInternalAny(value.Clone(true)); 105 } 106 if (auto f = interface_cast<IObjectFlags>(p)) { 107 f->SetObjectFlags(flags); 108 } 109 return p; 110 } 111 112 META_END_NAMESPACE() 113 114 #endif 115