Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/anim
diff options
context:
space:
mode:
authorrachytski <siarhei.rachytski@gmail.com>2012-10-05 18:44:42 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:44:41 +0300
commit13b42462f946cd0912b25c91264975d8285a667b (patch)
treef9fec8ee8c596634f9002d69364ed5ea6d260ad7 /anim
parent63b732f8f92aaeb98a525bfdf2f8d7eef0331938 (diff)
bug fixes for release.
Diffstat (limited to 'anim')
-rw-r--r--anim/angle_interpolation.cpp10
-rw-r--r--anim/anyrect_interpolation.cpp69
-rw-r--r--anim/anyrect_interpolation.hpp1
-rw-r--r--anim/controller.cpp33
-rw-r--r--anim/controller.hpp3
-rw-r--r--anim/task.cpp51
-rw-r--r--anim/task.hpp19
7 files changed, 145 insertions, 41 deletions
diff --git a/anim/angle_interpolation.cpp b/anim/angle_interpolation.cpp
index 0d8ba70dfa..acb588cae6 100644
--- a/anim/angle_interpolation.cpp
+++ b/anim/angle_interpolation.cpp
@@ -1,6 +1,8 @@
#include "angle_interpolation.hpp"
+#include "controller.hpp"
#include "../geometry/angles.hpp"
+#include "../base/logging.hpp"
namespace anim
{
@@ -22,20 +24,21 @@ namespace anim
void AngleInterpolation::OnStart(double ts)
{
m_startTime = ts;
+ m_outAngle = m_startAngle;
Task::OnStart(ts);
}
void AngleInterpolation::OnStep(double ts)
{
+ if (!IsRunning())
+ return;
+
if (ts - m_startTime >= m_interval)
{
End();
return;
}
- if (!IsRunning())
- return;
-
double elapsedSec = ts - m_startTime;
m_curAngle = m_outAngle = m_startAngle + m_dist * elapsedSec / m_interval;
@@ -56,6 +59,7 @@ namespace anim
void AngleInterpolation::SetEndAngle(double val)
{
+ m_startTime = GetController()->GetCurrentTime();
m_startAngle = m_curAngle;
m_dist = ang::GetShortestDistance(m_startAngle, val);
m_endAngle = m_startAngle + m_dist;
diff --git a/anim/anyrect_interpolation.cpp b/anim/anyrect_interpolation.cpp
index 74ca20eace..51565f1561 100644
--- a/anim/anyrect_interpolation.cpp
+++ b/anim/anyrect_interpolation.cpp
@@ -1,13 +1,15 @@
#include "anyrect_interpolation.hpp"
+#include "../base/logging.hpp"
+
namespace anim
{
AnyRectInterpolation::AnyRectInterpolation(m2::AnyRectD const & startRect,
m2::AnyRectD const & endRect,
double rotationSpeed,
m2::AnyRectD & outRect)
- : m_interval(rotationSpeed * fabs(ang::GetShortestDistance(startRect.Angle().val(),
- endRect.Angle().val())) / (2 * math::pi)),
+ : m_interval(max(0.5, rotationSpeed * fabs(ang::GetShortestDistance(startRect.Angle().val(),
+ endRect.Angle().val())) / (2 * math::pi))),
m_angleInt(startRect.Angle().val(),
endRect.Angle().val(),
rotationSpeed,
@@ -35,9 +37,16 @@ namespace anim
m_startTime = ts;
m_angleInt.OnStart(ts);
+ m_angleInt.Start();
+
m_segmentInt.OnStart(ts);
+ m_segmentInt.Start();
+
m_sizeXInt.OnStart(ts);
+ m_sizeXInt.Start();
+
m_sizeYInt.OnStart(ts);
+ m_sizeYInt.Start();
m_outRect = m_startRect;
@@ -46,34 +55,68 @@ namespace anim
void AnyRectInterpolation::OnStep(double ts)
{
+ if (!IsRunning())
+ return;
+
if (ts - m_startTime >= m_interval)
{
End();
return;
}
- if (!IsRunning())
- return;
+ if (m_angleInt.IsRunning())
+ m_angleInt.OnStep(ts);
+
+ if (m_segmentInt.IsRunning())
+ m_segmentInt.OnStep(ts);
+
+ if (m_sizeXInt.IsRunning())
+ m_sizeXInt.OnStep(ts);
- m_angleInt.OnStep(ts);
- m_segmentInt.OnStep(ts);
- m_sizeXInt.OnStep(ts);
- m_sizeYInt.OnStep(ts);
+ if (m_sizeYInt.IsRunning())
+ m_sizeYInt.OnStep(ts);
- m_outRect = m2::AnyRectD(m_curCenter, m_curAngle, m2::RectD(-m_curSizeX / 2, -m_curSizeY / 2, m_curSizeX / 2, m_curSizeY / 2));
+ m_outRect = m2::AnyRectD(m_curCenter,
+ m_curAngle,
+ m2::RectD(-m_curSizeX / 2, -m_curSizeY / 2,
+ m_curSizeX / 2, m_curSizeY / 2));
anim::Task::OnStep(ts);
}
void AnyRectInterpolation::OnEnd(double ts)
{
- m_angleInt.OnEnd(ts);
- m_segmentInt.OnEnd(ts);
- m_sizeXInt.OnEnd(ts);
- m_sizeYInt.OnEnd(ts);
+ if (m_angleInt.IsRunning())
+ m_angleInt.OnEnd(ts);
+
+ if (m_segmentInt.IsRunning())
+ m_segmentInt.OnEnd(ts);
+
+ if (m_sizeXInt.IsRunning())
+ m_sizeXInt.OnEnd(ts);
+
+ if (m_sizeYInt.IsRunning())
+ m_sizeYInt.OnEnd(ts);
m_outRect = m_endRect;
anim::Task::OnEnd(ts);
}
+
+ void AnyRectInterpolation::OnCancel(double ts)
+ {
+ if (m_angleInt.IsRunning())
+ m_angleInt.Cancel();
+
+ if (m_segmentInt.IsRunning())
+ m_segmentInt.Cancel();
+
+ if (m_sizeXInt.IsRunning())
+ m_sizeXInt.Cancel();
+
+ if (m_sizeYInt.IsRunning())
+ m_sizeYInt.Cancel();
+
+ anim::Task::OnCancel(ts);
+ }
}
diff --git a/anim/anyrect_interpolation.hpp b/anim/anyrect_interpolation.hpp
index 13df48c8db..9ba9272b0a 100644
--- a/anim/anyrect_interpolation.hpp
+++ b/anim/anyrect_interpolation.hpp
@@ -41,5 +41,6 @@ namespace anim
void OnStart(double ts);
void OnStep(double ts);
void OnEnd(double ts);
+ void OnCancel(double ts);
};
}
diff --git a/anim/controller.cpp b/anim/controller.cpp
index 3f217cf48c..2482a21370 100644
--- a/anim/controller.cpp
+++ b/anim/controller.cpp
@@ -20,6 +20,7 @@ namespace anim
void Controller::AddTask(shared_ptr<Task> const & task)
{
+ task->SetController(this);
m_tasks.PushBack(task);
m_IdleFrames = m_IdleThreshold;
}
@@ -30,6 +31,11 @@ namespace anim
swap(from, to);
}
+ void Controller::MergeTasks(TTasks & from, TTasks & to)
+ {
+ copy(from.begin(), from.end(), back_inserter(to));
+ }
+
bool Controller::HasTasks()
{
return !m_tasks.Empty();
@@ -55,7 +61,7 @@ namespace anim
{
m_tasks.ProcessList(bind(&Controller::CopyAndClearTasks, _1, ref(m_tasksList)));
- double ts = my::Timer::LocalTime();
+ double ts = GetCurrentTime();
TTasks l;
@@ -66,30 +72,43 @@ namespace anim
m_IdleFrames = m_IdleThreshold;
shared_ptr<Task> const & task = *it;
- if (task->State() == Task::EStarted)
+
+ task->Lock();
+
+ if (task->IsReady())
+ {
+ task->Start();
task->OnStart(ts);
- if (task->State() == Task::EInProgress)
+ }
+ if (task->IsRunning())
task->OnStep(ts);
- if (task->State() == Task::EInProgress)
+ if (task->IsRunning())
l.push_back(task);
else
{
- if (task->State() == Task::ECancelled)
+ if (task->IsCancelled())
task->OnCancel(ts);
- if (task->State() == Task::EEnded)
+ if (task->IsEnded())
task->OnEnd(ts);
}
+
+ task->Unlock();
}
if (!hasTasks && m_IdleFrames > 0)
m_IdleFrames -= 1;
- m_tasks.ProcessList(bind(&Controller::CopyAndClearTasks, ref(l), _1));
+ m_tasks.ProcessList(bind(&Controller::MergeTasks, ref(l), _1));
}
bool Controller::IsPreWarmed() const
{
return m_IdleFrames > 0;
}
+
+ double Controller::GetCurrentTime() const
+ {
+ return my::Timer::LocalTime();
+ }
}
diff --git a/anim/controller.hpp b/anim/controller.hpp
index ff8a66e863..398f191a4d 100644
--- a/anim/controller.hpp
+++ b/anim/controller.hpp
@@ -26,6 +26,7 @@ namespace anim
int m_IdleFrames;
static void CopyAndClearTasks(list<shared_ptr<Task> > & from, list<shared_ptr<Task> > & to);
+ static void MergeTasks(list<shared_ptr<Task> > & from, list<shared_ptr<Task> > & to);
public:
// Constructor
@@ -53,5 +54,7 @@ namespace anim
// interrupting rendering process, which might had happened in these
// "frames-in-the-middle".
bool IsPreWarmed() const;
+ // Getting current simulation time
+ double GetCurrentTime() const;
};
}
diff --git a/anim/task.cpp b/anim/task.cpp
index b012ce2fc7..92a5c4b04e 100644
--- a/anim/task.cpp
+++ b/anim/task.cpp
@@ -1,9 +1,13 @@
#include "task.hpp"
+#include "../std/bind.hpp"
+
+#include "../base/assert.hpp"
+
namespace anim
{
Task::Task()
- : m_State(EStarted)
+ : m_State(EReady)
{}
Task::~Task()
@@ -26,46 +30,50 @@ namespace anim
void Task::SetState(EState State)
{
- Lock();
m_State = State;
- Unlock();
}
- void Task::PerformCallback(EState state)
+ void Task::PerformCallbacks(EState state)
{
- TCallback const & cb = m_Callbacks[state];
- if (cb)
- cb();
+ list<TCallback> const & cb = m_Callbacks[state];
+ for_each(cb.begin(), cb.end(), bind(&TCallback::operator(), _1));
}
void Task::OnStart(double ts)
{
- PerformCallback(EStarted);
- SetState(EInProgress);
+ PerformCallbacks(EReady);
}
void Task::OnStep(double ts)
{
- PerformCallback(EInProgress);
+ PerformCallbacks(EInProgress);
}
void Task::OnCancel(double ts)
{
- PerformCallback(ECancelled);
+ PerformCallbacks(ECancelled);
}
void Task::OnEnd(double ts)
{
- PerformCallback(EEnded);
+ PerformCallbacks(EEnded);
+ }
+
+ void Task::Start()
+ {
+ ASSERT(IsReady(), ());
+ SetState(EInProgress);
}
void Task::Cancel()
{
+ ASSERT(IsRunning() || IsReady(), ());
SetState(ECancelled);
}
void Task::End()
{
+ ASSERT(IsRunning() || IsReady(), ());
SetState(EEnded);
}
@@ -84,8 +92,23 @@ namespace anim
return State() == EInProgress;
}
- void Task::SetCallback(EState state, TCallback const & cb)
+ bool Task::IsReady() const
+ {
+ return State() == EReady;
+ }
+
+ void Task::AddCallback(EState state, TCallback const & cb)
+ {
+ m_Callbacks[state].push_back(cb);
+ }
+
+ void Task::SetController(Controller * controller)
+ {
+ m_controller = controller;
+ }
+
+ Controller * Task::GetController() const
{
- m_Callbacks[state] = cb;
+ return m_controller;
}
}
diff --git a/anim/task.hpp b/anim/task.hpp
index d55c61d129..8cea0054dd 100644
--- a/anim/task.hpp
+++ b/anim/task.hpp
@@ -1,12 +1,15 @@
#pragma once
#include "../std/map.hpp"
+#include "../std/list.hpp"
#include "../std/function.hpp"
#include "../base/mutex.hpp"
namespace anim
{
+ class Controller;
+
// Interface for single animation task
class Task
{
@@ -16,7 +19,7 @@ namespace anim
enum EState
{
- EStarted,
+ EReady,
EInProgress,
ECancelled,
EEnded
@@ -26,21 +29,27 @@ namespace anim
EState m_State;
- map<EState, TCallback> m_Callbacks;
+ map<EState, list<TCallback> > m_Callbacks;
- void PerformCallback(EState state);
+ void PerformCallbacks(EState state);
threads::Mutex m_mutex;
+ Controller * m_controller;
+
protected:
void SetState(EState state);
+ friend class Controller;
+ void SetController(Controller * controller);
public:
Task();
virtual ~Task();
+ Controller * GetController() const;
+
EState State() const;
virtual void OnStart(double ts);
@@ -48,16 +57,18 @@ namespace anim
virtual void OnEnd(double ts);
virtual void OnCancel(double ts);
+ void Start();
void Cancel();
void End();
bool IsCancelled() const;
bool IsEnded() const;
bool IsRunning() const;
+ bool IsReady() const;
void Lock();
void Unlock();
- void SetCallback(EState state, TCallback const & cb);
+ void AddCallback(EState state, TCallback const & cb);
};
}