From 4b86554a0354d78efeb40e551eaccaac0fecd1d1 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 25 Sep 2018 13:08:40 +0800 Subject: Change the structure of project. --- src/ui/animations/animation.cpp | 190 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/ui/animations/animation.cpp (limited to 'src/ui/animations/animation.cpp') diff --git a/src/ui/animations/animation.cpp b/src/ui/animations/animation.cpp new file mode 100644 index 00000000..9d05860a --- /dev/null +++ b/src/ui/animations/animation.cpp @@ -0,0 +1,190 @@ +#include "animation.h" + +#include +#include + +namespace cru::ui::animations +{ + namespace details + { + class AnimationDelegateImpl; + constexpr double frame_rate = 60; + constexpr AnimationTimeUnit frame_step_time = AnimationTimeUnit(1) / frame_rate; + + + class AnimationDelegateImpl : public virtual IAnimationDelegate + { + 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 step_handlers, + Vector start_handlers, + Vector finish_handlers, + Vector 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 + { + return tag_; + } + + private: + const String tag_; + const AnimationTimeUnit duration_; + Vector step_handlers_; + Vector start_handlers_; + Vector finish_handlers_; + Vector 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(); + } + + AnimationDelegatePtr AnimationManager::CreateAnimation(String tag, AnimationTimeUnit duration, + Vector step_handlers, Vector start_handlers, + Vector finish_handlers, Vector cancel_handlers) + { + if (animations_.empty()) + SetTimer(); + + auto delegate = std::make_shared(tag); + + animations_[tag] = std::make_unique(tag, duration, std::move(step_handlers), std::move(start_handlers), std::move(finish_handlers), std::move(cancel_handlers), delegate); + + return delegate; + } + + void AnimationManager::RemoveAnimation(const String& tag) + { + const auto find_result = animations_.find(tag); + if (find_result != animations_.cend()) + animations_.erase(find_result); + + if (animations_.empty()) + KillTimer(); + } + + void AnimationManager::SetTimer() + { + if (timer_ == nullptr) + timer_ = SetInterval(std::chrono::duration_cast(frame_step_time), timer_action_); + } + + void AnimationManager::KillTimer() + { + if (timer_ != nullptr) + { + timer_->Cancel(); + timer_ = nullptr; + } + } + + Animation::Animation( + String tag, + AnimationTimeUnit duration, + Vector step_handlers, + Vector start_handlers, + Vector finish_handlers, + Vector 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() + { + if (current_time_ < duration_) + for (auto& handler : cancel_handlers_) + (*handler)(); + } + + bool Animation::Step(const AnimationTimeUnit time) + { + 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; + } + } + + } + + AnimationDelegatePtr AnimationBuilder::Start() const + { + return details::AnimationManager::GetInstance()->CreateAnimation(tag, duration, step_handlers_, start_handlers_, finish_handlers_, cancel_handlers_); + } +} -- cgit v1.2.3