aboutsummaryrefslogtreecommitdiff
path: root/CruUI/ui/animations
diff options
context:
space:
mode:
Diffstat (limited to 'CruUI/ui/animations')
-rw-r--r--CruUI/ui/animations/animation.cpp227
-rw-r--r--CruUI/ui/animations/animation.h176
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_;
};
}