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_API_UTIL_H
17 #define META_API_UTIL_H
18 
19 #include <meta/api/locking.h>
20 #include <meta/interface/animation/intf_interpolator.h>
21 #include <meta/interface/intf_any.h>
22 #include <meta/interface/intf_object_registry.h>
23 #include <meta/interface/intf_value.h>
24 #include <meta/interface/property/intf_modifier.h>
25 #include <meta/interface/property/property.h>
26 
META_BEGIN_NAMESPACE()27 META_BEGIN_NAMESPACE()
28 
29 inline BASE_NS::shared_ptr<CORE_NS::IInterface> GetPointer(const IAny& any)
30 {
31     BASE_NS::shared_ptr<CORE_NS::IInterface> ret;
32     any.GetValue(ret);
33     return ret;
34 }
35 
GetConstPointer(const IAny & any)36 inline BASE_NS::shared_ptr<const CORE_NS::IInterface> GetConstPointer(const IAny& any)
37 {
38     BASE_NS::shared_ptr<const CORE_NS::IInterface> ret;
39     any.GetValue(ret);
40     return ret;
41 }
42 
43 template<typename Interface>
GetPointer(const IAny & any)44 inline BASE_NS::shared_ptr<Interface> GetPointer(const IAny& any)
45 {
46     return interface_pointer_cast<Interface>(GetPointer(any));
47 }
48 
49 /// Returns IIinterface pointer if property contains a pointer that can be converted to it.
GetPointer(const IProperty::ConstPtr & p)50 inline BASE_NS::shared_ptr<CORE_NS::IInterface> GetPointer(const IProperty::ConstPtr& p)
51 {
52     InterfaceSharedLock lock { p };
53     return GetPointer(p->GetValue());
54 }
55 
56 template<typename Interface>
GetPointer(const IProperty::ConstPtr & p)57 inline BASE_NS::shared_ptr<Interface> GetPointer(const IProperty::ConstPtr& p)
58 {
59     return interface_pointer_cast<Interface>(GetPointer(p));
60 }
61 
62 inline IProperty::Ptr DuplicatePropertyType(IObjectRegistry& obr, IProperty::ConstPtr p, BASE_NS::string_view name = {})
63 {
64     IProperty::Ptr dup;
65     PropertyLock lock { p };
66     if (auto obj = interface_cast<IObject>(p)) {
67         dup = obr.GetPropertyRegister().Create(obj->GetClassId(), name.empty() ? p->GetName() : name);
68         if (auto dupi = interface_cast<IPropertyInternalAny>(dup)) {
69             if (auto i = interface_cast<IPropertyInternalAny>(p)) {
70                 if (auto&& any = i->GetInternalAny()) {
71                     dupi->SetInternalAny(any->Clone(false));
72                 }
73             }
74         }
75     }
76     return dup;
77 }
78 
79 template<typename Type>
80 Type GetValue(const Property<Type>& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
81 {
82     return p ? p->GetValue() : BASE_NS::move(defaultValue);
83 }
84 template<typename Type>
85 Type GetValue(const IProperty::ConstPtr& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
86 {
87     return GetValue(Property<Type>(p), BASE_NS::move(defaultValue));
88 }
89 template<typename Type>
90 Type GetValue(const IProperty::ConstWeakPtr& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
91 {
92     return GetValue<Type>(p.lock(), BASE_NS::move(defaultValue));
93 }
94 // to disambiguate
95 template<typename Type>
96 Type GetValue(const IProperty::Ptr& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
97 {
98     return GetValue(Property<Type>(p), BASE_NS::move(defaultValue));
99 }
100 // to disambiguate
101 template<typename Type>
102 Type GetValue(const IProperty::WeakPtr& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
103 {
104     return GetValue<Type>(p.lock(), BASE_NS::move(defaultValue));
105 }
106 
107 template<typename Type>
SetValue(Property<Type> property,const NonDeduced_t<Type> & value)108 bool SetValue(Property<Type> property, const NonDeduced_t<Type>& value) noexcept
109 {
110     return property && property->SetValue(value);
111 }
112 template<typename Type>
SetValue(IProperty::Ptr p,const NonDeduced_t<Type> & value)113 bool SetValue(IProperty::Ptr p, const NonDeduced_t<Type>& value) noexcept
114 {
115     return SetValue(Property<Type>(p), value);
116 }
117 template<typename Type>
SetValue(IProperty::WeakPtr p,const NonDeduced_t<Type> & value)118 bool SetValue(IProperty::WeakPtr p, const NonDeduced_t<Type>& value) noexcept
119 {
120     return SetValue<Type>(p.lock(), value);
121 }
122 
Copy(const IProperty::ConstPtr & src,const IProperty::Ptr & dst)123 inline bool Copy(const IProperty::ConstPtr& src, const IProperty::Ptr& dst)
124 {
125     PropertyLock source(src);
126     PropertyLock dest(dst);
127     return dest->SetValueAny(source->GetValueAny());
128 }
129 
130 inline bool IsCompatible(
131     const IProperty::ConstPtr& prop, const TypeId& id, CompatibilityDirection dir = CompatibilityDirection::BOTH)
132 {
133     bool res = false;
134     if (auto i = interface_cast<IPropertyInternalAny>(prop)) {
135         if (auto iany = i->GetInternalAny()) {
136             res = IsCompatible(*iany, id, dir);
137         }
138     }
139     return res;
140 }
141 
142 template<typename T>
143 inline bool IsCompatibleWith(const IProperty::ConstPtr& prop, CompatibilityDirection dir = CompatibilityDirection::BOTH)
144 {
145     return IsCompatible(prop, UidFromType<BASE_NS::remove_const_t<BASE_NS::remove_reference_t<T>>>(), dir);
146 }
147 
IsSetCompatible(const IProperty::ConstPtr & prop,const TypeId & id)148 inline bool IsSetCompatible(const IProperty::ConstPtr& prop, const TypeId& id)
149 {
150     return IsCompatible(prop, id, CompatibilityDirection::SET);
151 }
152 
IsGetCompatible(const IProperty::ConstPtr & prop,const TypeId & id)153 inline bool IsGetCompatible(const IProperty::ConstPtr& prop, const TypeId& id)
154 {
155     return IsCompatible(prop, id, CompatibilityDirection::GET);
156 }
157 
158 template<typename T>
IsSetCompatibleWith(const IProperty::ConstPtr & prop)159 inline bool IsSetCompatibleWith(const IProperty::ConstPtr& prop)
160 {
161     return IsCompatibleWith<T>(prop, CompatibilityDirection::SET);
162 }
163 
164 template<typename T>
IsGetCompatibleWith(const IProperty::ConstPtr & prop)165 inline bool IsGetCompatibleWith(const IProperty::ConstPtr& prop)
166 {
167     return IsCompatibleWith<T>(prop, CompatibilityDirection::GET);
168 }
169 
Interpolate(IInterpolator::ConstPtr inter,const IProperty::Ptr & output,const IAny::ConstPtr & from,const IAny::ConstPtr & to,float t)170 inline AnyReturnValue Interpolate(IInterpolator::ConstPtr inter, const IProperty::Ptr& output,
171     const IAny::ConstPtr& from, const IAny::ConstPtr& to, float t)
172 {
173     if (from && to) {
174         if (auto i = interface_cast<IPropertyInternalAny>(output)) {
175             PropertyLock lock { output };
176             if (auto iany = i->GetInternalAny()) {
177                 auto ret = inter->Interpolate(*iany, *from, *to, t);
178                 lock.SetValueAny(*iany);
179                 return ret;
180             }
181         }
182     }
183     return AnyReturn::FAIL;
184 }
185 
IsValueGetCompatible(const IAny & any,const IValue & value)186 inline bool IsValueGetCompatible(const IAny& any, const IValue& value)
187 {
188     for (auto&& t : any.GetCompatibleTypes(CompatibilityDirection::GET)) {
189         if (value.IsCompatible(t)) {
190             return true;
191         }
192     }
193     return false;
194 }
195 
IsModifierGetCompatible(const IAny & any,const IModifier & value)196 inline bool IsModifierGetCompatible(const IAny& any, const IModifier& value)
197 {
198     for (auto&& t : any.GetCompatibleTypes(CompatibilityDirection::GET)) {
199         if (value.IsCompatible(t)) {
200             return true;
201         }
202     }
203     return false;
204 }
205 
206 META_END_NAMESPACE()
207 
208 #endif
209