forked from organicmaps/organicmaps
refactored anim::Controller and moved it into RenderPolicy.
This commit is contained in:
parent
4ba8227713
commit
b79d29f3f3
11 changed files with 126 additions and 116 deletions
|
@ -15,5 +15,7 @@ HEADERS += \
|
|||
|
||||
SOURCES += \
|
||||
controller.cpp \
|
||||
task.cpp
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -8,20 +8,16 @@ namespace anim
|
|||
{
|
||||
Controller::Controller()
|
||||
{
|
||||
m_animStep = 10;
|
||||
m_thread.Create(this);
|
||||
m_LockCount = 0;
|
||||
}
|
||||
|
||||
Controller::~Controller()
|
||||
{
|
||||
m_tasks.Cancel();
|
||||
m_newTasks.Cancel();
|
||||
m_thread.Cancel();
|
||||
}
|
||||
|
||||
void Controller::AddTask(shared_ptr<Task> const & task)
|
||||
{
|
||||
m_newTasks.PushBack(task);
|
||||
m_tasks.PushBack(task);
|
||||
}
|
||||
|
||||
void Controller::CopyTasks(TTasks & from, TTasks & to)
|
||||
|
@ -30,54 +26,50 @@ namespace anim
|
|||
swap(from, to);
|
||||
}
|
||||
|
||||
void Controller::Do()
|
||||
bool Controller::HasTasks()
|
||||
{
|
||||
while (true)
|
||||
return !m_tasks.Empty();
|
||||
}
|
||||
|
||||
void Controller::Lock()
|
||||
{
|
||||
++m_LockCount;
|
||||
}
|
||||
|
||||
void Controller::Unlock()
|
||||
{
|
||||
--m_LockCount;
|
||||
}
|
||||
|
||||
int Controller::LockCount()
|
||||
{
|
||||
if (m_LockCount < 0)
|
||||
LOG(LWARNING, ("Lock/Unlock is unbalanced! LockCount < 0!"));
|
||||
|
||||
return m_LockCount;
|
||||
}
|
||||
|
||||
void Controller::PerformStep()
|
||||
{
|
||||
m_tasks.ProcessList(bind(&Controller::CopyTasks, this, _1, ref(m_tasksList)));
|
||||
|
||||
double ts = my::Timer::LocalTime();
|
||||
|
||||
TTasks l;
|
||||
|
||||
for (TTasks::const_iterator it = m_tasksList.begin(); it != m_tasksList.end(); ++it)
|
||||
{
|
||||
// making synchronized copy of tasks to process
|
||||
// them without intervention from other threads.
|
||||
m_newTasks.ProcessList(bind(&Controller::CopyTasks, this, _1, ref(m_newTasksList)));
|
||||
m_tasks.ProcessList(bind(&Controller::CopyTasks, this, _1, ref(m_tasksList)));
|
||||
|
||||
// checking for thread cancellation
|
||||
if (m_newTasks.IsCancelled()
|
||||
|| m_tasks.IsCancelled()
|
||||
|| IsCancelled())
|
||||
break;
|
||||
|
||||
// current animation step timestamp
|
||||
double timeStamp = my::Timer::LocalTime();
|
||||
|
||||
// starting new tasks and adding them to the pool.
|
||||
// they we'll be processed in the next animation step
|
||||
for (TTasks::const_iterator it = m_newTasksList.begin();
|
||||
it != m_newTasksList.end();
|
||||
++it)
|
||||
{
|
||||
shared_ptr<Task> task = *it;
|
||||
task->OnStart(timeStamp);
|
||||
m_tasks.PushBack(task);
|
||||
}
|
||||
|
||||
m_newTasksList.clear();
|
||||
|
||||
// processing current tasks
|
||||
for (TTasks::const_iterator it = m_tasksList.begin();
|
||||
it != m_tasksList.end();
|
||||
++it)
|
||||
{
|
||||
shared_ptr<Task> task = *it;
|
||||
task->OnStep(timeStamp);
|
||||
if (!task->IsFinished())
|
||||
m_tasks.PushBack(task);
|
||||
else
|
||||
task->OnEnd(timeStamp);
|
||||
}
|
||||
|
||||
m_tasksList.clear();
|
||||
|
||||
// sleeping till the next animation step.
|
||||
threads::Sleep(m_animStep);
|
||||
shared_ptr<Task> const & task = *it;
|
||||
if (task->State() == Task::EWaitStart)
|
||||
task->OnStart(ts);
|
||||
if (task->State() == Task::EInProgress)
|
||||
task->OnStep(ts);
|
||||
if (task->State() == Task::EWaitEnd)
|
||||
task->OnEnd(ts);
|
||||
else
|
||||
l.push_back(task);
|
||||
}
|
||||
|
||||
m_tasks.ProcessList(bind(&Controller::CopyTasks, this, ref(l), _1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,7 @@ namespace anim
|
|||
class Task;
|
||||
|
||||
// Animation controller class.
|
||||
// - Creates and manages the separate thread.
|
||||
// - Using ThreadedList to manage the list of active commands.
|
||||
// - CPU efficient, which means that when there are no commands
|
||||
// the thread is sleeping and doesn't consume CPU
|
||||
class Controller : public threads::IRoutine
|
||||
class Controller
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -25,17 +21,7 @@ namespace anim
|
|||
// Task for the current step.
|
||||
TTasks m_tasksList;
|
||||
|
||||
ThreadedList<shared_ptr<Task> > m_newTasks;
|
||||
// Added, but not started tasks.
|
||||
// They'll be started in the next animation step.
|
||||
TTasks m_newTasksList;
|
||||
|
||||
// Animation thread.
|
||||
threads::Thread m_thread;
|
||||
// Animation step in miliseconds.
|
||||
unsigned m_animStep;
|
||||
// MainLoop method
|
||||
void Do();
|
||||
int m_LockCount;
|
||||
|
||||
void CopyTasks(list<shared_ptr<Task> > & from, list<shared_ptr<Task> > & to);
|
||||
|
||||
|
@ -46,5 +32,17 @@ namespace anim
|
|||
~Controller();
|
||||
// Adding animation task to the controller
|
||||
void AddTask(shared_ptr<Task> const & task);
|
||||
// Do we have animation tasks, which are currently running?
|
||||
bool HasTasks();
|
||||
// Lock/Unlock controller. Locked controller
|
||||
// is considered to be in "transition" mode from one task to another
|
||||
// and this situation is taken into account into RenderPolicy when
|
||||
// checking for "need redraw" status.
|
||||
void Lock();
|
||||
void Unlock();
|
||||
// Getting current lock count
|
||||
int LockCount();
|
||||
// Perform single animation step
|
||||
void PerformStep();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,12 +6,34 @@ namespace anim
|
|||
class Task
|
||||
{
|
||||
public:
|
||||
virtual void OnStart(double ts) = 0;
|
||||
virtual void OnStep(double ts) = 0;
|
||||
virtual void OnEnd(double ts) = 0;
|
||||
virtual bool IsFinished() = 0;
|
||||
virtual void Finish() = 0;
|
||||
|
||||
virtual ~Task() {};
|
||||
enum EState
|
||||
{
|
||||
EWaitStart,
|
||||
EInProgress,
|
||||
EWaitEnd
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
EState m_State;
|
||||
|
||||
protected:
|
||||
|
||||
void SetState(EState state);
|
||||
|
||||
public:
|
||||
|
||||
Task();
|
||||
virtual ~Task();
|
||||
|
||||
EState State() const;
|
||||
|
||||
virtual void OnStart(double ts);
|
||||
virtual void OnStep(double ts);
|
||||
virtual void OnEnd(double ts);
|
||||
|
||||
void Finish();
|
||||
bool IsFinished() const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ m2::RectI const BasicRenderPolicy::OnSize(int w, int h)
|
|||
void BasicRenderPolicy::BeginFrame(shared_ptr<PaintEvent> const & e,
|
||||
ScreenBase const & s)
|
||||
{
|
||||
RenderPolicy::BeginFrame(e, s);
|
||||
|
||||
if (m_QueuedRenderer)
|
||||
m_QueuedRenderer->BeginFrame();
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ BasicTilingRenderPolicy::BasicTilingRenderPolicy(Params const & p,
|
|||
|
||||
void BasicTilingRenderPolicy::BeginFrame(shared_ptr<PaintEvent> const & e, ScreenBase const & s)
|
||||
{
|
||||
RenderPolicy::BeginFrame(e, s);
|
||||
|
||||
if (m_QueuedRenderer)
|
||||
m_QueuedRenderer->BeginFrame();
|
||||
}
|
||||
|
|
|
@ -215,6 +215,8 @@ namespace location
|
|||
if (!m_fw->GetNavigator().DoSupportRotation())
|
||||
return;
|
||||
|
||||
m_fw->GetRenderPolicy()->GetAnimController()->Lock();
|
||||
|
||||
StopAnimation();
|
||||
|
||||
double startAngle = m_fw->GetNavigator().Screen().GetAngle();
|
||||
|
@ -235,8 +237,10 @@ namespace location
|
|||
endAngle,
|
||||
1));
|
||||
|
||||
m_fw->GetAnimController()->AddTask(m_rotateScreenTask);
|
||||
m_fw->GetRenderPolicy()->GetAnimController()->AddTask(m_rotateScreenTask);
|
||||
}
|
||||
|
||||
m_fw->GetRenderPolicy()->GetAnimController()->Unlock();
|
||||
}
|
||||
|
||||
void State::StopAnimation()
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#include "../base/SRC_FIRST.hpp"
|
||||
|
||||
#include "render_policy.hpp"
|
||||
|
||||
#include "../indexer/drawing_rules.hpp"
|
||||
|
||||
#include "window_handle.hpp"
|
||||
#include "test_render_policy.hpp"
|
||||
#include "basic_render_policy.hpp"
|
||||
|
@ -13,9 +10,13 @@
|
|||
#include "tiling_render_policy_st.hpp"
|
||||
#include "tiling_render_policy_mt.hpp"
|
||||
|
||||
#include "../anim/controller.hpp"
|
||||
#include "../anim/task.hpp"
|
||||
|
||||
#include "../yg/internal/opengl.hpp"
|
||||
|
||||
#include "../indexer/scales.hpp"
|
||||
#include "../indexer/drawing_rules.hpp"
|
||||
|
||||
#include "../platform/video_timer.hpp"
|
||||
#include "../platform/settings.hpp"
|
||||
|
@ -37,7 +38,7 @@ RenderPolicy::RenderPolicy(Params const & p,
|
|||
m_doForceUpdate(false),
|
||||
m_visualScale(p.m_visualScale),
|
||||
m_skinName(p.m_skinName),
|
||||
m_isAnimating(false)
|
||||
m_controller(new anim::Controller())
|
||||
{
|
||||
LOG(LDEBUG, ("each BaseRule will hold up to", idCacheSize, "cached values"));
|
||||
drule::rules().ResizeCaches(idCacheSize);
|
||||
|
@ -98,7 +99,10 @@ void RenderPolicy::StopRotate(double a, double)
|
|||
}
|
||||
|
||||
void RenderPolicy::BeginFrame(shared_ptr<PaintEvent> const & e, ScreenBase const & s)
|
||||
{}
|
||||
{
|
||||
/// processing animations at the beginning of the frame
|
||||
m_controller->PerformStep();
|
||||
}
|
||||
|
||||
void RenderPolicy::EndFrame(shared_ptr<PaintEvent> const & e, ScreenBase const & s)
|
||||
{}
|
||||
|
@ -110,7 +114,14 @@ bool RenderPolicy::DoSupportRotation() const
|
|||
|
||||
bool RenderPolicy::NeedRedraw() const
|
||||
{
|
||||
return m_windowHandle->needRedraw();
|
||||
return m_windowHandle->needRedraw()
|
||||
|| IsAnimating();
|
||||
}
|
||||
|
||||
bool RenderPolicy::IsAnimating() const
|
||||
{
|
||||
return (m_controller->HasTasks()
|
||||
|| (m_controller->LockCount() > 0));
|
||||
}
|
||||
|
||||
bool RenderPolicy::IsTiling() const
|
||||
|
@ -209,14 +220,9 @@ void RenderPolicy::JoinBenchmarkFence(int fenceID)
|
|||
{
|
||||
}
|
||||
|
||||
void RenderPolicy::SetIsAnimating(bool flag)
|
||||
shared_ptr<anim::Controller> const & RenderPolicy::GetAnimController() const
|
||||
{
|
||||
m_isAnimating = flag;
|
||||
}
|
||||
|
||||
bool RenderPolicy::IsAnimating() const
|
||||
{
|
||||
return m_isAnimating;
|
||||
return m_controller;
|
||||
}
|
||||
|
||||
RenderPolicy * CreateRenderPolicy(RenderPolicy::Params const & params)
|
||||
|
|
|
@ -24,6 +24,12 @@ namespace yg
|
|||
class ResourceManager;
|
||||
}
|
||||
|
||||
namespace anim
|
||||
{
|
||||
class Controller;
|
||||
class Task;
|
||||
}
|
||||
|
||||
class WindowHandle;
|
||||
|
||||
class RenderPolicy
|
||||
|
@ -54,7 +60,7 @@ protected:
|
|||
m2::AnyRectD m_invalidRect;
|
||||
double m_visualScale;
|
||||
string m_skinName;
|
||||
bool m_isAnimating;
|
||||
shared_ptr<anim::Controller> m_controller;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -114,7 +120,7 @@ public:
|
|||
bool DoForceUpdate() const;
|
||||
void SetForceUpdate(bool flag);
|
||||
|
||||
void SetIsAnimating(bool flag);
|
||||
shared_ptr<anim::Controller> const & GetAnimController() const;
|
||||
bool IsAnimating() const;
|
||||
|
||||
void SetInvalidRect(m2::AnyRectD const & glbRect);
|
||||
|
|
|
@ -11,21 +11,20 @@ RotateScreenTask::RotateScreenTask(Framework * framework,
|
|||
m_interval(interval)
|
||||
{
|
||||
m_startTime = 0;
|
||||
m_isFinished = false;
|
||||
}
|
||||
|
||||
void RotateScreenTask::OnStart(double ts)
|
||||
{
|
||||
m_startTime = ts;
|
||||
m_curAngle = m_startAngle;
|
||||
m_framework->GetRenderPolicy()->SetIsAnimating(true);
|
||||
anim::Task::OnStart(ts);
|
||||
}
|
||||
|
||||
void RotateScreenTask::OnStep(double ts)
|
||||
{
|
||||
if (ts - m_startTime > m_interval)
|
||||
{
|
||||
m_isFinished = true;
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -37,21 +36,4 @@ void RotateScreenTask::OnStep(double ts)
|
|||
|
||||
m_framework->GetNavigator().Rotate(angle - m_curAngle);
|
||||
m_curAngle = angle;
|
||||
|
||||
m_framework->GetRenderPolicy()->GetWindowHandle()->invalidate();
|
||||
}
|
||||
|
||||
void RotateScreenTask::OnEnd(double ts)
|
||||
{
|
||||
m_framework->GetRenderPolicy()->SetIsAnimating(false);
|
||||
}
|
||||
|
||||
bool RotateScreenTask::IsFinished()
|
||||
{
|
||||
return m_isFinished;
|
||||
}
|
||||
|
||||
void RotateScreenTask::Finish()
|
||||
{
|
||||
m_isFinished = true;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@ private:
|
|||
double m_interval;
|
||||
double m_curAngle;
|
||||
|
||||
bool m_isFinished;
|
||||
|
||||
public:
|
||||
|
||||
RotateScreenTask(Framework * framework,
|
||||
|
@ -27,8 +25,4 @@ public:
|
|||
|
||||
void OnStart(double ts);
|
||||
void OnStep(double ts);
|
||||
void OnEnd(double ts);
|
||||
|
||||
bool IsFinished();
|
||||
void Finish();
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue