diff options
Diffstat (limited to 'CruUI/ui/animations')
-rw-r--r-- | CruUI/ui/animations/animation.cpp | 227 | ||||
-rw-r--r-- | CruUI/ui/animations/animation.h | 176 |
2 files changed, 233 insertions, 170 deletions
diff --git a/CruUI/ui/animations/animation.cpp b/CruUI/ui/animations/animation.cpp index 26b7d5fc..9d05860a 100644 --- a/CruUI/ui/animations/animation.cpp +++ b/CruUI/ui/animations/animation.cpp @@ -5,99 +5,186 @@ namespace cru::ui::animations { - constexpr int frame_rate = 60; - constexpr double frame_step_time = 1.0 / frame_rate; - - AnimationManager::AnimationManager() - : timer_action_(new Action<>([this]() + namespace details { - for (auto& animation : animations_) + class AnimationDelegateImpl; + constexpr double frame_rate = 60; + constexpr AnimationTimeUnit frame_step_time = AnimationTimeUnit(1) / frame_rate; + + + class AnimationDelegateImpl : public virtual IAnimationDelegate { - if (animation.second->Step(frame_step_time)) - InvokeLater([=] + public: + explicit AnimationDelegateImpl(String tag) + : tag_(std::move(tag)) + { + + } + AnimationDelegateImpl(const AnimationDelegateImpl& other) = delete; + AnimationDelegateImpl(AnimationDelegateImpl&& other) = delete; + AnimationDelegateImpl& operator=(const AnimationDelegateImpl& other) = delete; + AnimationDelegateImpl& operator=(AnimationDelegateImpl&& other) = delete; + ~AnimationDelegateImpl() override = default; + + void Cancel() override + { + AnimationManager::GetInstance()->RemoveAnimation(tag_); + } + + private: + String tag_; + }; + + + class Animation : public Object + { + public: + Animation( + String tag, + AnimationTimeUnit duration, + Vector<AnimationStepHandlerPtr> step_handlers, + Vector<AnimationStartHandlerPtr> start_handlers, + Vector<ActionPtr> finish_handlers, + Vector<ActionPtr> cancel_handlers, + AnimationDelegatePtr delegate + ); + Animation(const Animation& other) = delete; + Animation(Animation&& other) = delete; + Animation& operator=(const Animation& other) = delete; + Animation& operator=(Animation&& other) = delete; + ~Animation() override; + + + // If finish or invalid, return false. + bool Step(AnimationTimeUnit time); + + String GetTag() const { - RemoveAnimation(animation.second); //TODO!!! - }); + return tag_; + } + + private: + const String tag_; + const AnimationTimeUnit duration_; + Vector<AnimationStepHandlerPtr> step_handlers_; + Vector<AnimationStartHandlerPtr> start_handlers_; + Vector<ActionPtr> finish_handlers_; + Vector<ActionPtr> cancel_handlers_; + AnimationDelegatePtr delegate_; + + AnimationTimeUnit current_time_ = AnimationTimeUnit::zero(); + }; + + AnimationManager::AnimationManager() + : timer_action_(CreateActionPtr([this]() + { + auto i = animations_.cbegin(); + while (i != animations_.cend()) + { + auto current_i = i++; + if (current_i->second->Step(frame_step_time)) + animations_.erase(current_i); + } + + if (animations_.empty()) + KillTimer(); + })) + { + } - })) - { - } + AnimationManager::~AnimationManager() + { + KillTimer(); + } - AnimationManager::~AnimationManager() - { - for (auto& animation : animations_) - delete animation.second; + AnimationDelegatePtr AnimationManager::CreateAnimation(String tag, AnimationTimeUnit duration, + Vector<AnimationStepHandlerPtr> step_handlers, Vector<AnimationStartHandlerPtr> start_handlers, + Vector<ActionPtr> finish_handlers, Vector<ActionPtr> cancel_handlers) + { + if (animations_.empty()) + SetTimer(); - if (timer_) - timer_->Cancel(); - } + auto delegate = std::make_shared<AnimationDelegateImpl>(tag); - void AnimationManager::AddAnimation(Animation* animation) - { - if (animations_.empty()) - timer_ = SetInterval(frame_step_time, timer_action_); + animations_[tag] = std::make_unique<Animation>(tag, duration, std::move(step_handlers), std::move(start_handlers), std::move(finish_handlers), std::move(cancel_handlers), delegate); - const auto find_result = animations_.find(animation->GetTag()); - if (find_result != animations_.cend()) - find_result->second->Cancel(); - animations_.insert_or_assign(animation->GetTag(), animation); - } + return delegate; + } - void AnimationManager::RemoveAnimation(Animation* animation) - { - const auto find_result = animations_.find(animation->GetTag()); - if (find_result != animations_.cend()) + void AnimationManager::RemoveAnimation(const String& tag) { - delete find_result->second; - animations_.erase(find_result); + const auto find_result = animations_.find(tag); + if (find_result != animations_.cend()) + animations_.erase(find_result); + + if (animations_.empty()) + KillTimer(); } - if (animations_.empty()) + void AnimationManager::SetTimer() { - assert(timer_); - timer_->Cancel(); - timer_ = nullptr; + if (timer_ == nullptr) + timer_ = SetInterval(std::chrono::duration_cast<std::chrono::milliseconds>(frame_step_time), timer_action_); } - } - Animation::Animation(String tag, const double duration, - const Vector<std::shared_ptr<Action<Animation*, double>>>& step_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& start_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& finish_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& cancel_handlers - ) : tag_(std::move(tag)), duration_(duration), step_handlers_(step_handlers), - start_handlers_(start_handlers), finish_handlers_(finish_handlers), cancel_handlers_(cancel_handlers) - { - AnimationManager::GetInstance()->AddAnimation(this); - } + void AnimationManager::KillTimer() + { + if (timer_ != nullptr) + { + timer_->Cancel(); + timer_ = nullptr; + } + } - bool Animation::Step(const double time) - { - current_time_ += time; - if (current_time_ > duration_) + Animation::Animation( + String tag, + AnimationTimeUnit duration, + Vector<AnimationStepHandlerPtr> step_handlers, + Vector<AnimationStartHandlerPtr> start_handlers, + Vector<ActionPtr> finish_handlers, + Vector<ActionPtr> cancel_handlers, + AnimationDelegatePtr delegate + ) : tag_(std::move(tag)), duration_(duration), + step_handlers_(std::move(step_handlers)), + start_handlers_(std::move(start_handlers)), + finish_handlers_(std::move(finish_handlers)), + cancel_handlers_(std::move(cancel_handlers)), + delegate_(std::move(delegate)) + { + + } + + Animation::~Animation() { - for (auto& handler : step_handlers_) - (*handler)(this, 1); - for (auto& handler : finish_handlers_) - (*handler)(this); - return true; + if (current_time_ < duration_) + for (auto& handler : cancel_handlers_) + (*handler)(); } - else + + bool Animation::Step(const AnimationTimeUnit time) { - for (auto& handler : step_handlers_) - (*handler)(this, current_time_ / duration_); - return false; + current_time_ += time; + if (current_time_ > duration_) + { + for (auto& handler : step_handlers_) + (*handler)(delegate_, 1); + for (auto& handler : finish_handlers_) + (*handler)(); + return true; + } + else + { + for (auto& handler : step_handlers_) + (*handler)(delegate_, current_time_ / duration_); + return false; + } } + } - void Animation::Cancel() + AnimationDelegatePtr AnimationBuilder::Start() const { - for (auto& handler : cancel_handlers_) - (*handler)(this); - InvokeLater([this] - { - AnimationManager::GetInstance()->RemoveAnimation(this); //TODO!!! - }); + return details::AnimationManager::GetInstance()->CreateAnimation(tag, duration, step_handlers_, start_handlers_, finish_handlers_, cancel_handlers_); } } diff --git a/CruUI/ui/animations/animation.h b/CruUI/ui/animations/animation.h index fb6ba93e..69b08b0c 100644 --- a/CruUI/ui/animations/animation.h +++ b/CruUI/ui/animations/animation.h @@ -1,131 +1,107 @@ #pragma once -#include <map> +#include <unordered_map> #include "base.h" #include "application.h" #include "timer.h" -#include "builder.h" namespace cru::ui::animations { - class Animation; + using AnimationTimeUnit = FloatSecond; + + using IAnimationDelegate = ICancelable; + using AnimationDelegatePtr = CancelablePtr; - class AnimationManager : public Object - { - public: - static AnimationManager* GetInstance() - { - return Application::GetInstance()->GetAnimationManager(); - } - - public: - AnimationManager(); - AnimationManager(const AnimationManager& other) = delete; - AnimationManager(AnimationManager&& other) = delete; - AnimationManager& operator=(const AnimationManager& other) = delete; - AnimationManager& operator=(AnimationManager&& other) = delete; - ~AnimationManager() override; + using AnimationStepHandlerPtr = FunctionPtr<void(AnimationDelegatePtr, double)>; + using AnimationStartHandlerPtr = FunctionPtr<void(AnimationDelegatePtr)>; - void AddAnimation(Animation* animation); - void RemoveAnimation(Animation* animation); - private: - std::map<String, Animation*> animations_; - std::shared_ptr<ITimerTask> timer_; - std::shared_ptr<Action<>> timer_action_; - }; - - class Animation : public Object + namespace details { - friend class AnimationManager; - protected: - Animation( - String tag, - double duration, - const Vector<std::shared_ptr<Action<Animation*, double>>>& step_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& start_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& finish_handlers, - const Vector<std::shared_ptr<Action<Animation*>>>& cancel_handlers - ); + class Animation; + using AnimationPtr = std::unique_ptr<Animation>; - public: - Animation(const Animation& other) = delete; - Animation(Animation&& other) = delete; - Animation& operator=(const Animation& other) = delete; - Animation& operator=(Animation&& other) = delete; - ~Animation() override = default; // The animation will never destroy by users. - - bool Step(double time); - void Cancel(); - String GetTag() const + class AnimationManager : public Object { - return tag_; - } + public: + static AnimationManager* GetInstance() + { + return Application::GetInstance()->GetAnimationManager(); + } - private: - const String tag_; - const double duration_; - Vector<std::shared_ptr<Action<Animation*, double>>> step_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> start_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> finish_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> cancel_handlers_; + public: + AnimationManager(); + AnimationManager(const AnimationManager& other) = delete; + AnimationManager(AnimationManager&& other) = delete; + AnimationManager& operator=(const AnimationManager& other) = delete; + AnimationManager& operator=(AnimationManager&& other) = delete; + ~AnimationManager() override; + + AnimationDelegatePtr CreateAnimation( + String tag, + AnimationTimeUnit duration, + Vector<AnimationStepHandlerPtr> step_handlers, + Vector<AnimationStartHandlerPtr> start_handlers, + Vector<ActionPtr> finish_handlers, + Vector<ActionPtr> cancel_handlers + ); + void RemoveAnimation(const String& tag); - double current_time_ = 0; + private: + void SetTimer(); + void KillTimer(); + private: + std::unordered_map<String, AnimationPtr> animations_; + std::shared_ptr<ICancelable> timer_; + ActionPtr timer_action_; + }; + } + + class AnimationBuilder : public Object + { public: - class Builder : public OneTimeBuilder<Animation> + AnimationBuilder(String tag, const AnimationTimeUnit duration) + : tag(std::move(tag)), duration(duration) { - public: - Builder(String tag, const double duration) - : tag(std::move(tag)), duration(duration) - { - } + } - String tag; - double duration; + String tag; + AnimationTimeUnit duration; - Builder& AddStepHandler(Action<Animation*, double>&& handler) - { - if (IsValid()) - step_handlers_.push_back(std::make_shared<Action<Animation*, double>>(std::move(handler))); - return *this; - } + AnimationBuilder& AddStepHandler(AnimationStepHandlerPtr handler) + { + step_handlers_.push_back(std::move(handler)); + return *this; + } - Builder& AddStartHandler(Action<Animation*>&& handler) - { - if (IsValid()) - start_handlers_.push_back(std::make_shared<Action<Animation*>>(std::move(handler))); - return *this; - } + AnimationBuilder& AddStartHandler(AnimationStartHandlerPtr handler) + { + start_handlers_.push_back(std::move(handler)); + return *this; + } - Builder& AddFinishHandler(Action<Animation*>&& handler) - { - if (IsValid()) - finish_handlers_.push_back(std::make_shared<Action<Animation*>>(std::move(handler))); - return *this; - } + AnimationBuilder& AddFinishHandler(ActionPtr handler) + { + finish_handlers_.push_back(std::move(handler)); + return *this; + } - Builder& AddCancelHandler(Action<Animation*>&& handler) - { - if (IsValid()) - cancel_handlers_.push_back(std::make_shared<Action<Animation*>>(std::move(handler))); - return *this; - } + AnimationBuilder& AddCancelHandler(ActionPtr handler) + { + cancel_handlers_.push_back(std::move(handler)); + return *this; + } - protected: - Animation* OnCreate() override - { - return new Animation(std::move(tag), duration, step_handlers_, start_handlers_, finish_handlers_, cancel_handlers_); - } + AnimationDelegatePtr Start() const; - private: - Vector<std::shared_ptr<Action<Animation*, double>>> step_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> start_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> finish_handlers_; - Vector<std::shared_ptr<Action<Animation*>>> cancel_handlers_; - }; + private: + Vector<AnimationStepHandlerPtr> step_handlers_; + Vector<AnimationStartHandlerPtr> start_handlers_; + Vector<ActionPtr> finish_handlers_; + Vector<ActionPtr> cancel_handlers_; }; } |