• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/base/ids.h>
21 #include <meta/interface/animation/intf_interpolator.h>
22 #include <meta/interface/intf_any.h>
23 #include <meta/interface/intf_object_registry.h>
24 #include <meta/interface/intf_value.h>
25 #include <meta/interface/property/array_property.h>
26 #include <meta/interface/property/intf_modifier.h>
27 #include <meta/interface/property/property.h>
28 
META_BEGIN_NAMESPACE()29 META_BEGIN_NAMESPACE()
30 
31 /// Get shared_ptr of IInterface from an any, or nullptr if not compatible
32 inline BASE_NS::shared_ptr<CORE_NS::IInterface> GetPointer(const IAny& any)
33 {
34     BASE_NS::shared_ptr<CORE_NS::IInterface> ret;
35     any.GetValue(ret);
36     return ret;
37 }
38 
39 /// Get shared_ptr of IInterface from an any ptr, or nullptr if not compatible
GetPointer(const IAny::Ptr & any)40 inline BASE_NS::shared_ptr<CORE_NS::IInterface> GetPointer(const IAny::Ptr& any)
41 {
42     return any ? GetPointer(*any) : nullptr;
43 }
44 
45 /// Get shared_ptr of IInterface from an any, or nullptr if not compatible
GetConstPointer(const IAny & any)46 inline BASE_NS::shared_ptr<const CORE_NS::IInterface> GetConstPointer(const IAny& any)
47 {
48     BASE_NS::shared_ptr<const CORE_NS::IInterface> ret;
49     any.GetValue(ret);
50     return ret;
51 }
52 
53 /// Get shared_ptr of IInterface from an any, or nullptr if not compatible
GetConstPointer(const IAny::ConstPtr & any)54 inline BASE_NS::shared_ptr<const CORE_NS::IInterface> GetConstPointer(const IAny::ConstPtr& any)
55 {
56     return any ? GetConstPointer(*any) : nullptr;
57 }
58 
59 /// Get shared_ptr of IInterface from an any ptr, or nullptr if not compatible
GetPointer(const IAny::ConstPtr & any)60 inline BASE_NS::shared_ptr<const CORE_NS::IInterface> GetPointer(const IAny::ConstPtr& any)
61 {
62     return any ? GetConstPointer(*any) : nullptr;
63 }
64 
65 /// Get interface pointer from an any, or nullptr if not compatible
66 template<typename Interface>
GetPointer(const IAny & any)67 inline BASE_NS::shared_ptr<Interface> GetPointer(const IAny& any)
68 {
69     return interface_pointer_cast<Interface>(GetPointer(any));
70 }
71 
72 /// Returns IIinterface pointer if property contains a pointer that can be converted to it.
GetPointer(const IProperty::ConstPtr & p)73 inline BASE_NS::shared_ptr<CORE_NS::IInterface> GetPointer(const IProperty::ConstPtr& p)
74 {
75     InterfaceSharedLock lock { p };
76     return lock ? GetPointer(p->GetValue()) : nullptr;
77 }
78 
79 /// Returns IIinterface pointer if property contains a pointer that can be converted to it.
GetConstPointer(const IProperty::ConstPtr & p)80 inline BASE_NS::shared_ptr<const CORE_NS::IInterface> GetConstPointer(const IProperty::ConstPtr& p)
81 {
82     InterfaceSharedLock lock { p };
83     return lock ? GetConstPointer(p->GetValue()) : nullptr;
84 }
85 
86 /// Returns interface pointer if property contains a pointer that can be converted to it.
87 template<typename Interface>
GetPointer(const IProperty::ConstPtr & p)88 inline BASE_NS::shared_ptr<Interface> GetPointer(const IProperty::ConstPtr& p)
89 {
90     return interface_pointer_cast<Interface>(GetPointer(p));
91 }
92 
93 /// Returns interface pointer if property contains a pointer that can be converted to it.
94 template<typename Interface>
GetConstPointer(const IProperty::ConstPtr & p)95 inline BASE_NS::shared_ptr<const Interface> GetConstPointer(const IProperty::ConstPtr& p)
96 {
97     return interface_pointer_cast<Interface>(GetConstPointer(p));
98 }
99 
100 /// Returns the internal any from property
GetInternalAny(const IProperty::ConstPtr & p)101 inline IAny::ConstPtr GetInternalAny(const IProperty::ConstPtr& p)
102 {
103     auto i = interface_cast<IPropertyInternalAny>(p);
104     return i ? i->GetInternalAny() : nullptr;
105 }
106 
107 /// Returns the internal any from property
GetInternalAny(const IProperty & p)108 inline IAny::ConstPtr GetInternalAny(const IProperty& p)
109 {
110     auto i = interface_cast<IPropertyInternalAny>(&p);
111     return i ? i->GetInternalAny() : nullptr;
112 }
113 
114 /// Set IIinterface pointer for any if it is compatible
SetPointer(IAny & any,const BASE_NS::shared_ptr<CORE_NS::IInterface> & p)115 inline bool SetPointer(IAny& any, const BASE_NS::shared_ptr<CORE_NS::IInterface>& p)
116 {
117     return any.SetValue(p);
118 }
119 
120 /// Set IIinterface pointer for any if it is compatible
SetPointer(IAny & any,const BASE_NS::shared_ptr<const CORE_NS::IInterface> & p)121 inline bool SetPointer(IAny& any, const BASE_NS::shared_ptr<const CORE_NS::IInterface>& p)
122 {
123     return any.SetValue(p);
124 }
125 
126 /// Set IIinterface pointer for property if it is compatible
SetPointer(const IProperty::Ptr & p,const BASE_NS::shared_ptr<CORE_NS::IInterface> & ptr)127 inline bool SetPointer(const IProperty::Ptr& p, const BASE_NS::shared_ptr<CORE_NS::IInterface>& ptr)
128 {
129     if (InterfaceSharedLock lock { p }) {
130         if (auto inany = GetInternalAny(p)) {
131             if (auto any = inany->Clone(false)) {
132                 if (any->SetValue(ptr)) {
133                     return p->SetValue(*any);
134                 }
135             }
136         }
137     }
138     return false;
139 }
140 
141 /// Set IIinterface pointer for property if it is compatible
SetPointer(const IProperty::Ptr & p,const BASE_NS::shared_ptr<const CORE_NS::IInterface> & ptr)142 inline bool SetPointer(const IProperty::Ptr& p, const BASE_NS::shared_ptr<const CORE_NS::IInterface>& ptr)
143 {
144     if (InterfaceSharedLock lock { p }) {
145         if (auto inany = GetInternalAny(p)) {
146             if (auto any = inany->Clone(false)) {
147                 if (any->SetValue(ptr)) {
148                     return p->SetValue(*any);
149                 }
150             }
151         }
152     }
153     return false;
154 }
155 
156 /// Set IIinterface pointer for property if it is compatible
157 template<typename Interface>
SetPointer(const IProperty::Ptr & p,const BASE_NS::shared_ptr<Interface> & ptr)158 inline bool SetPointer(const IProperty::Ptr& p, const BASE_NS::shared_ptr<Interface>& ptr)
159 {
160     return SetPointer(p, interface_pointer_cast<CORE_NS::IInterface>(ptr));
161 }
162 
163 /**
164  * @brief Duplicate property type without values or modifiers
165  * @param obr Object registry to use
166  * @param p Property to duplicate
167  * @param name Name for the new property, name of p is used if empty
168  * @return New property with same type as p
169  */
170 inline IProperty::Ptr DuplicatePropertyType(IObjectRegistry& obr, IProperty::ConstPtr p, BASE_NS::string_view name = {})
171 {
172     IProperty::Ptr dup;
173     PropertyLock lock { p };
174     if (auto obj = interface_cast<IObject>(p)) {
175         dup = obr.GetPropertyRegister().Create(obj->GetClassId(), name.empty() ? p->GetName() : name);
176         if (auto dupi = interface_cast<IPropertyInternalAny>(dup)) {
177             if (auto any = GetInternalAny(p)) {
178                 dupi->SetInternalAny(any->Clone(false));
179             }
180         }
181     }
182     return dup;
183 }
184 
185 /// Get value of property or given default value if property not set or incompatible
186 template<typename Type>
187 Type GetValue(const Property<Type>& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
188 {
189     return p ? p->GetValue() : BASE_NS::move(defaultValue);
190 }
191 /// Get value of property or given default value if property not set or incompatible
192 template<typename Type>
193 Type GetValue(const IProperty::ConstPtr& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
194 {
195     return GetValue(Property<Type>(p), BASE_NS::move(defaultValue));
196 }
197 /// Get value of property or given default value if property not set or incompatible
198 template<typename Type>
199 Type GetValue(const IProperty::ConstWeakPtr& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
200 {
201     return GetValue<Type>(p.lock(), BASE_NS::move(defaultValue));
202 }
203 // to disambiguate
204 /// Get value of property or given default value if property not set or incompatible
205 template<typename Type>
206 Type GetValue(const IProperty::Ptr& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
207 {
208     return GetValue(Property<Type>(p), BASE_NS::move(defaultValue));
209 }
210 // to disambiguate
211 /// Get value of property or given default value if property not set or incompatible
212 template<typename Type>
213 Type GetValue(const IProperty::WeakPtr& p, NonDeduced_t<BASE_NS::remove_const_t<Type>> defaultValue = {}) noexcept
214 {
215     return GetValue<Type>(p.lock(), BASE_NS::move(defaultValue));
216 }
217 /// Set value for property, true on success
218 template<typename Type>
SetValue(Property<Type> property,const NonDeduced_t<Type> & value)219 bool SetValue(Property<Type> property, const NonDeduced_t<Type>& value) noexcept
220 {
221     return property && property->SetValue(value);
222 }
223 /// Set value for property, true on success
224 template<typename Type>
SetValue(IProperty::Ptr p,const NonDeduced_t<Type> & value)225 bool SetValue(IProperty::Ptr p, const NonDeduced_t<Type>& value) noexcept
226 {
227     return SetValue(Property<Type>(p), value);
228 }
229 /// Set value for property, true on success
230 template<typename Type>
SetValue(IProperty::WeakPtr p,const NonDeduced_t<Type> & value)231 bool SetValue(IProperty::WeakPtr p, const NonDeduced_t<Type>& value) noexcept
232 {
233     return SetValue<Type>(p.lock(), value);
234 }
235 /// Copy value from src to dst property
Copy(const IProperty::ConstPtr & src,const IProperty::Ptr & dst)236 inline bool Copy(const IProperty::ConstPtr& src, const IProperty::Ptr& dst)
237 {
238     PropertyLock source(src);
239     PropertyLock dest(dst);
240     return dest->SetValueAny(source->GetValueAny());
241 }
242 /// Check if property is compatible with given type id and direction
243 inline bool IsCompatible(
244     const IProperty& prop, const TypeId& id, CompatibilityDirection dir = CompatibilityDirection::BOTH)
245 {
246     bool res = false;
247     if (auto iany = GetInternalAny(prop)) {
248         res = IsCompatible(*iany, id, dir);
249     }
250     return res;
251 }
252 /// Check if property is compatible with given type id and direction
253 inline bool IsCompatible(
254     const IProperty::ConstPtr& prop, const TypeId& id, CompatibilityDirection dir = CompatibilityDirection::BOTH)
255 {
256     return prop && IsCompatible(*prop, id, dir);
257 }
258 /// Check if property is compatible with type and direction
259 template<typename T>
260 inline bool IsCompatibleWith(const IProperty::ConstPtr& prop, CompatibilityDirection dir = CompatibilityDirection::BOTH)
261 {
262     return IsCompatible(prop, GetTypeId<BASE_NS::remove_const_t<BASE_NS::remove_reference_t<T>>>(), dir);
263 }
264 /// Check if property is compatible to set value with given type id
IsSetCompatible(const IProperty::ConstPtr & prop,const TypeId & id)265 inline bool IsSetCompatible(const IProperty::ConstPtr& prop, const TypeId& id)
266 {
267     return IsCompatible(prop, id, CompatibilityDirection::SET);
268 }
269 /// Check if property is compatible to get value with given type id
IsGetCompatible(const IProperty::ConstPtr & prop,const TypeId & id)270 inline bool IsGetCompatible(const IProperty::ConstPtr& prop, const TypeId& id)
271 {
272     return IsCompatible(prop, id, CompatibilityDirection::GET);
273 }
274 /// Check if property is compatible to set value with type
275 template<typename T>
IsSetCompatibleWith(const IProperty::ConstPtr & prop)276 inline bool IsSetCompatibleWith(const IProperty::ConstPtr& prop)
277 {
278     return IsCompatibleWith<T>(prop, CompatibilityDirection::SET);
279 }
280 /// Check if property is compatible to get value with type
281 template<typename T>
IsGetCompatibleWith(const IProperty::ConstPtr & prop)282 inline bool IsGetCompatibleWith(const IProperty::ConstPtr& prop)
283 {
284     return IsCompatibleWith<T>(prop, CompatibilityDirection::GET);
285 }
286 /**
287  * @brief Typeless interpolate between two anys using property as result
288  * @param inter Interpolator to use
289  * @param output PRoperty to use as result
290  * @param from Start of the range
291  * @param to End of the range
292  * @param t The interpolation position in range [0,1]
293  */
Interpolate(IInterpolator::ConstPtr inter,const IProperty::Ptr & output,const IAny::ConstPtr & from,const IAny::ConstPtr & to,float t)294 inline AnyReturnValue Interpolate(IInterpolator::ConstPtr inter, const IProperty::Ptr& output,
295     const IAny::ConstPtr& from, const IAny::ConstPtr& to, float t)
296 {
297     if (from && to) {
298         if (auto i = interface_cast<IPropertyInternalAny>(output)) {
299             PropertyLock lock { output };
300             if (auto iany = i->GetInternalAny()) {
301                 auto ret = inter->Interpolate(*iany, *from, *to, t);
302                 lock.SetValueAny(*iany);
303                 return ret;
304             }
305         }
306     }
307     return AnyReturn::FAIL;
308 }
309 /// Check if any is get-compatible with the given IValue
IsValueGetCompatible(const IAny & any,const IValue & value)310 inline bool IsValueGetCompatible(const IAny& any, const IValue& value)
311 {
312     for (auto&& t : any.GetCompatibleTypes(CompatibilityDirection::GET)) {
313         if (value.IsCompatible(t)) {
314             return true;
315         }
316     }
317     return false;
318 }
319 /// Check if any is get-compatible with the given IModifier
IsModifierGetCompatible(const IAny & any,const IModifier & value)320 inline bool IsModifierGetCompatible(const IAny& any, const IModifier& value)
321 {
322     for (auto&& t : any.GetCompatibleTypes(CompatibilityDirection::GET)) {
323         if (value.IsCompatible(t)) {
324             return true;
325         }
326     }
327     return false;
328 }
329 /// Returns the top most value interface from property that implements Interface or nullptr if no such
330 template<typename Interface>
GetFirstValueFromProperty(const IProperty::ConstPtr & p)331 typename Interface::Ptr GetFirstValueFromProperty(const IProperty::ConstPtr& p)
332 {
333     if (auto i = interface_cast<IStackProperty>(p)) {
334         PropertyLock lock { p };
335         TypeId ids[] = { Interface::UID };
336         auto values = i->GetValues(ids, false);
337         if (!values.empty()) {
338             return interface_pointer_cast<Interface>(values.back());
339         }
340     }
341     return nullptr;
342 }
343 
344 /// Check if property contains pointer that can be extracted as constant IInterface
IsGetPointer(const IProperty::ConstPtr & p)345 inline bool IsGetPointer(const IProperty::ConstPtr& p)
346 {
347     return IsGetCompatibleWith<SharedPtrConstIInterface>(p);
348 }
349 
350 /// Check if property contains pointer that can be set as IInterface
IsSetPointer(const IProperty::ConstPtr & p)351 inline bool IsSetPointer(const IProperty::ConstPtr& p)
352 {
353     return IsSetCompatibleWith<SharedPtrIInterface>(p);
354 }
355 
356 META_END_NAMESPACE()
357 
358 #endif
359