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 #ifndef META_SRC_ANIMATION_H 16 #define META_SRC_ANIMATION_H 17 18 #include <meta/api/make_callback.h> 19 #include <meta/interface/animation/builtin_animations.h> 20 #include <meta/interface/animation/intf_animation.h> 21 #include <meta/interface/intf_containable.h> 22 #include <meta/interface/serialization/intf_serializable.h> 23 24 #include "../object.h" 25 #include "animation_state.h" 26 #include "staggered_animation_state.h" 27 28 META_BEGIN_NAMESPACE() 29 30 namespace Internal { 31 32 /** 33 * @brief A base class which can be used by generic animation implementations. 34 */ 35 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces> 36 class BaseAnimationFwd : public Internal::ObjectFwd<FinalClass, ClassInfo, BaseAnimationInterface, INotifyOnChange, 37 IAttachment, IContainable, IMutableContainable, IAnimationInternal, Interfaces...> { 38 static_assert(BASE_NS::is_convertible_v<BaseAnimationInterface*, IAnimation*>, 39 "BaseAnimationInterface of BaseAnimationFwd must inherit from IAnimation"); 40 using Super = Internal::ObjectFwd<FinalClass, ClassInfo, BaseAnimationInterface, INotifyOnChange, IAttachment, 41 IContainable, IMutableContainable, IAnimationInternal, Interfaces...>; 42 43 protected: 44 BaseAnimationFwd() = default; 45 ~BaseAnimationFwd() override = default; 46 47 protected: // IObject 48 BASE_NS::string GetName() const override 49 { 50 return META_ACCESS_PROPERTY_VALUE(Name); 51 } 52 53 protected: // ILifecycle 54 bool Build(const IMetadata::Ptr& data) override 55 { 56 if (Super::Build(data)) { 57 META_ACCESS_PROPERTY(Name)->SetDefaultValue(Super::GetName()); 58 return GetState().Initialize(BASE_NS::move(GetParams())); 59 } 60 return false; 61 } 62 void Destroy() override 63 { 64 GetState().Uninitialize(); 65 Super::Destroy(); 66 } 67 68 virtual AnimationState::AnimationStateParams GetParams() = 0; 69 70 protected: // IContainable 71 IObject::Ptr GetParent() const override 72 { 73 return parent_.lock(); 74 } 75 76 protected: // IMutableContainable 77 void SetParent(const IObject::Ptr& parent) override 78 { 79 parent_ = parent; 80 } 81 82 protected: // INamed 83 META_IMPLEMENT_INTERFACE_PROPERTY(INamed, BASE_NS::string, Name) 84 85 protected: // IAttach 86 bool Attach(const IObject::Ptr& attachment, const IObject::Ptr& dataContext) override 87 { 88 return GetState().Attach(attachment, dataContext); 89 } 90 bool Detach(const IObject::Ptr& attachment) override 91 { 92 return GetState().Detach(attachment); 93 } 94 95 protected: // IAnimationInternal 96 void ResetClock() override 97 { 98 GetState().ResetClock(); 99 } 100 101 bool Move(const IAnimationInternal::MoveParams& move) override 102 { 103 return GetState().Move(move).changed; 104 } 105 106 void OnAnimationStateChanged(const IAnimationInternal::AnimationStateChangedInfo& info) override 107 { 108 Evaluate(); 109 } 110 void OnEvaluationNeeded() override 111 { 112 Evaluate(); 113 } 114 115 protected: // IAttachment 116 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAttachment, IObject::WeakPtr, DataContext) 117 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAttachment, IAttach::WeakPtr, AttachedTo) 118 bool Attaching(const IAttach::Ptr& target, const IObject::Ptr& dataContext) override 119 { 120 SetValue(META_ACCESS_PROPERTY(AttachedTo), target); 121 SetValue(META_ACCESS_PROPERTY(DataContext), dataContext); 122 return true; 123 } 124 bool Detaching(const IAttach::Ptr& target) override 125 { 126 SetValue(META_ACCESS_PROPERTY(AttachedTo), {}); 127 SetValue(META_ACCESS_PROPERTY(DataContext), {}); 128 return true; 129 } 130 131 protected: // IAnimation 132 META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, bool, Enabled, true) 133 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Valid, {}, DEFAULT_PROPERTY_FLAGS_NO_SER) 134 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, TimeSpan, TotalDuration, {}, DEFAULT_PROPERTY_FLAGS_NO_SER) 135 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Running, {}, DEFAULT_PROPERTY_FLAGS_NO_SER) 136 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, float, Progress, {}, DEFAULT_PROPERTY_FLAGS_NO_SER) 137 META_IMPLEMENT_INTERFACE_PROPERTY( 138 IAnimation, IAnimationController::WeakPtr, Controller, {}, DEFAULT_PROPERTY_FLAGS_NO_SER) 139 META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, ICurve1D::Ptr, Curve) 140 void Step(const IClock::ConstPtr& clock) override 141 { 142 GetState().Step(clock); 143 } 144 META_IMPLEMENT_INTERFACE_EVENT(IAnimation, IOnChanged, OnFinished) 145 META_IMPLEMENT_INTERFACE_EVENT(IAnimation, IOnChanged, OnStarted) 146 147 protected: // INotifyOnChange 148 META_IMPLEMENT_INTERFACE_EVENT(INotifyOnChange, IOnChanged, OnChanged) 149 NotifyChanged()150 void NotifyChanged() 151 { 152 META_ACCESS_EVENT(OnChanged)->Invoke(); 153 } 154 155 protected: 156 virtual void Evaluate() = 0; 157 virtual Internal::AnimationState& GetState() noexcept = 0; 158 159 private: 160 IObject::WeakPtr parent_; 161 }; 162 163 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces> 164 class BaseStartableAnimationFwd 165 : public BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IStartableAnimation, Interfaces...> { 166 using Super = BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IStartableAnimation, Interfaces...>; 167 using Super::GetState; 168 169 protected: // IStartableAnimation 170 void Pause() override 171 { 172 GetState().Pause(); 173 } 174 void Restart() override 175 { 176 GetState().Restart(); 177 } 178 void Seek(float position) override 179 { 180 GetState().Seek(position); 181 } 182 void Start() override 183 { 184 GetState().Start(); 185 } 186 void Stop() override 187 { 188 GetState().Stop(); 189 } 190 void Finish() override 191 { 192 GetState().Finish(); 193 } 194 }; 195 196 /** 197 * @brief A base class which can be used by animation container implementations. 198 */ 199 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces> 200 class BaseAnimationContainerFwd : public BaseStartableAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, 201 IContainer, ILockable, IIterable, IImportFinalize, Interfaces...> { 202 static_assert(BASE_NS::is_convertible_v<BaseAnimationInterface*, IStaggeredAnimation*>, 203 "BaseAnimationInterface of BaseAnimationContainerFwd must inherit from IStaggeredAnimation"); 204 using Super = BaseStartableAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IContainer, ILockable, 205 IIterable, IImportFinalize, Interfaces...>; 206 using IContainer::SizeType; 207 208 public: // ILockable 209 void Lock() const override 210 { 211 if (auto lockable = interface_cast<ILockable>(&GetContainer())) { 212 lockable->Lock(); 213 } 214 } 215 void Unlock() const override 216 { 217 if (auto lockable = interface_cast<ILockable>(&GetContainer())) { 218 lockable->Unlock(); 219 } 220 } 221 void LockShared() const override 222 { 223 if (auto lockable = interface_cast<ILockable>(&GetContainer())) { 224 lockable->LockShared(); 225 } 226 } 227 void UnlockShared() const override 228 { 229 if (auto lockable = interface_cast<ILockable>(&GetContainer())) { 230 lockable->UnlockShared(); 231 } 232 } 233 234 protected: 235 Internal::StaggeredAnimationState& GetState() noexcept override = 0; 236 237 ReturnError Finalize(IImportFunctions&) override 238 { 239 GetState().ChildrenChanged(); 240 return GenericError::SUCCESS; 241 } 242 243 public: // IIterable 244 IterationResult Iterate(const IterationParameters& params) override 245 { 246 auto iterable = interface_cast<IIterable>(&GetContainer()); 247 return iterable ? iterable->Iterate(params) : IterationResult::FAILED; 248 } 249 IterationResult Iterate(const IterationParameters& params) const override 250 { 251 const auto iterable = interface_cast<IIterable>(&GetContainer()); 252 return iterable ? iterable->Iterate(params) : IterationResult::FAILED; 253 } 254 255 public: // IContainer 256 bool Add(const IObject::Ptr& object) override 257 { 258 return GetContainer().Add(object); 259 } 260 bool Insert(SizeType index, const IObject::Ptr& object) override 261 { 262 return GetContainer().Insert(index, object); 263 } 264 bool Remove(SizeType index) override 265 { 266 return GetContainer().Remove(index); 267 } 268 bool Remove(const IObject::Ptr& child) override 269 { 270 return GetContainer().Remove(child); 271 } 272 bool Move(SizeType fromIndex, SizeType toIndex) override 273 { 274 return GetContainer().Move(fromIndex, toIndex); 275 } 276 bool Move(const IObject::Ptr& child, SizeType toIndex) override 277 { 278 return GetContainer().Move(child, toIndex); 279 } 280 bool Replace(const IObject::Ptr& child, const IObject::Ptr& replaceWith, bool addAlways) override 281 { 282 return GetContainer().Replace(child, replaceWith, addAlways); 283 } 284 BASE_NS::vector<IObject::Ptr> GetAll() const override 285 { 286 return GetContainer().GetAll(); 287 } 288 void RemoveAll() override 289 { 290 GetContainer().RemoveAll(); 291 } 292 IObject::Ptr GetAt(SizeType index) const override 293 { 294 return GetContainer().GetAt(index); 295 } 296 SizeType GetSize() const override 297 { 298 return GetContainer().GetSize(); 299 } 300 BASE_NS::vector<IObject::Ptr> FindAll(const IContainer::FindOptions& options) const override 301 { 302 return GetContainer().FindAll(options); 303 } 304 IObject::Ptr FindAny(const IContainer::FindOptions& options) const override 305 { 306 return GetContainer().FindAny(options); 307 } 308 IObject::Ptr FindByName(BASE_NS::string_view name) const override 309 { 310 return GetContainer().FindByName(name); 311 } 312 bool IsAncestorOf(const IObject::ConstPtr& object) const override 313 { 314 return GetContainer().IsAncestorOf(object); 315 } 316 317 META_FORWARD_EVENT(IOnChanged, OnAdded, GetContainer().EventOnAdded()); 318 META_FORWARD_EVENT(IOnChanged, OnRemoved, GetContainer().EventOnRemoved()); 319 META_FORWARD_EVENT(IOnChanged, OnMoved, GetContainer().EventOnMoved()); 320 321 protected: // IStaggeredAnimation 322 void AddAnimation(const IAnimation::Ptr& animation) override 323 { 324 GetContainer().Add(animation); 325 } 326 void RemoveAnimation(const IAnimation::Ptr& animation) override 327 { 328 GetContainer().Remove(animation); 329 } 330 BASE_NS::vector<IAnimation::Ptr> GetAnimations() const override 331 { 332 return GetContainer().template GetAll<IAnimation>(); 333 } 334 335 protected: 336 virtual IContainer& GetContainer() noexcept = 0; 337 virtual const IContainer& GetContainer() const noexcept = 0; 338 }; 339 340 /** 341 * @brief A base class which can be used by property animation implementations. 342 */ 343 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces> 344 class BasePropertyAnimationFwd : public BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, 345 IPropertyAnimation, IModifier, IImportFinalize, Interfaces...> { 346 static_assert(BASE_NS::is_convertible_v<BaseAnimationInterface*, ITimedAnimation*>, 347 "BaseAnimationInterface of BasePropertyAnimationFwd must inherit from ITimedAnimation"); 348 using Super = BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IPropertyAnimation, IModifier, 349 IImportFinalize, Interfaces...>; 350 351 protected: 352 BasePropertyAnimationFwd() = default; 353 ~BasePropertyAnimationFwd() override = default; 354 355 protected: // ILifecycle 356 bool Build(const IMetadata::Ptr& data) override 357 { 358 if (Super::Build(data)) { 359 META_ACCESS_PROPERTY(Property)->OnChanged()->AddHandler( 360 MakeCallback<IOnChanged>(this, &BasePropertyAnimationFwd::PropertyChanged)); 361 return true; 362 } 363 return false; 364 } 365 366 protected: // IPropertyAnimation 367 META_IMPLEMENT_INTERFACE_PROPERTY(IPropertyAnimation, IProperty::WeakPtr, Property); 368 369 protected: // ITimedAnimation 370 META_IMPLEMENT_INTERFACE_PROPERTY(ITimedAnimation, TimeSpan, Duration) 371 372 protected: // IModifier 373 EvaluationResult ProcessOnGet(IAny& value) override 374 { 375 return EvaluationResult::EVAL_CONTINUE; 376 } 377 EvaluationResult ProcessOnSet(IAny& value, const IAny& current) override 378 { 379 return EvaluationResult::EVAL_CONTINUE; 380 } 381 bool IsCompatible(const TypeId& id) const override 382 { 383 if (auto p = GetTargetProperty()) { 384 return META_NS::IsCompatible(p.property->GetValue(), id); 385 } 386 return false; 387 } 388 Internal::PropertyAnimationState& GetState() noexcept override = 0; 389 390 protected: 391 ReturnError Finalize(IImportFunctions&) override 392 { 393 GetState().UpdateTotalDuration(); 394 auto p = GetTargetProperty(); 395 GetState().SetInterpolator(p ? p.property->GetTypeId() : TypeId {}); 396 SetValue(Super::META_ACCESS_PROPERTY(Valid), p); 397 return GenericError::SUCCESS; 398 } 399 400 protected: 401 struct TargetProperty { 402 IProperty::Ptr property; 403 IStackProperty::Ptr stack; 404 /* NOLINTNEXTLINE(google-explicit-constructor) */ 405 operator bool() const noexcept 406 { 407 return property && stack; 408 } 409 }; 410 PropertyChanged()411 void PropertyChanged() 412 { 413 auto p = GetTargetProperty(); 414 this->GetState().SetInterpolator(p ? p.property->GetTypeId() : TypeId {}); 415 SetValue(Super::META_ACCESS_PROPERTY(Valid), p); 416 OnPropertyChanged(p, property_.lock()); 417 property_ = p.stack; 418 } 419 420 virtual void OnPropertyChanged(const TargetProperty& property, const IStackProperty::Ptr& previous) = 0; 421 422 TargetProperty GetTargetProperty() const noexcept 423 { 424 auto p = META_ACCESS_PROPERTY_VALUE(Property).lock(); 425 return { p, interface_pointer_cast<IStackProperty>(p) }; 426 } 427 428 private: 429 IStackProperty::WeakPtr property_; 430 }; 431 432 /** 433 * @brief A base class which can be used by property animation implementations. 434 */ 435 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces> 436 class PropertyAnimationFwd 437 : public BasePropertyAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, Interfaces...> { 438 using Super = BasePropertyAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, Interfaces...>; 439 440 protected: 441 PropertyAnimationFwd() = default; 442 ~PropertyAnimationFwd() override = default; 443 444 protected: 445 // Note covariance 446 Internal::PropertyAnimationState& GetState() noexcept override 447 { 448 return state_; 449 } 450 451 private: 452 Internal::PropertyAnimationState state_; 453 }; 454 455 } // namespace Internal 456 457 META_END_NAMESPACE() 458 459 #endif // META_SRC_ANIMATION_H 460