Timer定时器类重做

This commit is contained in:
Nomango 2018-04-24 09:02:06 +08:00
parent 04920b6b06
commit 0614701a30
12 changed files with 212 additions and 432 deletions

View File

@ -6,7 +6,7 @@ e2d::ActionLoop::ActionLoop(Action * action, int times /* = -1 */)
, m_nTimes(0) , m_nTimes(0)
, m_nTotalTimes(times) , m_nTotalTimes(times)
{ {
ASSERT(m_pAction != nullptr, "ActionLoop NULL pointer exception!"); ASSERT(m_pAction, "ActionLoop NULL pointer exception!");
m_pAction->retain(); m_pAction->retain();
} }

View File

@ -1,5 +1,6 @@
#include "..\e2dbase.h" #include "..\e2dbase.h"
#include "..\e2dmanager.h" #include "..\e2dmanager.h"
#include "..\e2dtool.h"
// 控制游戏终止 // 控制游戏终止
@ -98,7 +99,7 @@ int e2d::Game::start(bool bAutoRelease/* true */)
// 判断是否达到了刷新状态 // 判断是否达到了刷新状态
if (Time::__isReady()) if (Time::__isReady())
{ {
TimerManager::__update(); // 定时器管理器执行程序 Timer::__update(); // 定时器管理器执行程序
ActionManager::__update(); // 动作管理器执行程序 ActionManager::__update(); // 动作管理器执行程序
while (Time::__isReady()) while (Time::__isReady())
{ {
@ -136,8 +137,8 @@ void e2d::Game::resume()
// 刷新当前时间 // 刷新当前时间
Time::__updateLast(); Time::__updateLast();
// 重置动画和定时器 // 重置动画和定时器
ActionManager::__resetAllActions(); ActionManager::__resetAll();
TimerManager::__resetAllTimers(); Timer::__resetAll();
} }
} }
@ -157,8 +158,6 @@ void e2d::Game::destroy()
SceneManager::__uninit(); SceneManager::__uninit();
// 关闭播放器 // 关闭播放器
MusicManager::__uninit(); MusicManager::__uninit();
// 清空定时器
TimerManager::__uninit();
// 删除监听器 // 删除监听器
InputManager::__uninit(); InputManager::__uninit();
ColliderManager::__uninit(); ColliderManager::__uninit();
@ -168,6 +167,8 @@ void e2d::Game::destroy()
ObjectManager::__clear(); ObjectManager::__clear();
// 清空图片缓存 // 清空图片缓存
Image::clearCache(); Image::clearCache();
// 清空定时器
Timer::__uninit();
// 关闭输入 // 关闭输入
Input::__uninit(); Input::__uninit();
// 恢复计时操作 // 恢复计时操作

View File

@ -219,7 +219,7 @@ std::vector<e2d::Action*> e2d::ActionManager::getAll()
return s_vActions; return s_vActions;
} }
void e2d::ActionManager::__resetAllActions() void e2d::ActionManager::__resetAll()
{ {
FOR_LOOP(action, s_vRunningActions) FOR_LOOP(action, s_vRunningActions)
{ {

View File

@ -9,7 +9,7 @@ static std::stack<e2d::Scene*> s_SceneStack;
void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullptr */, bool saveCurrentScene /* = true */) void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullptr */, bool saveCurrentScene /* = true */)
{ {
ASSERT(scene != nullptr, "Next scene NULL pointer exception!"); ASSERT(scene, "Next scene NULL pointer exception!");
scene->retain(); scene->retain();
// 保存下一场景的指针 // 保存下一场景的指针

View File

@ -1,176 +0,0 @@
#include "..\e2dmanager.h"
#include "..\e2dtool.h"
#include "..\e2dnode.h"
static std::vector<e2d::Timer*> s_vTimers;
void e2d::TimerManager::__update()
{
if (s_vTimers.empty() || Game::isPaused())
return;
for (size_t i = 0; i < s_vTimers.size(); i++)
{
auto pTimer = s_vTimers[i];
// 更新定时器
if (pTimer->isReady())
{
pTimer->update();
}
// 清除不必要的定时器
if (pTimer->m_bClear)
{
pTimer->release();
s_vTimers.erase(s_vTimers.begin() + i);
i--;
}
}
}
e2d::Timer * e2d::TimerManager::start(String name, Function func, double interval, int times, bool atOnce, bool autoRelease)
{
auto pTimer = new (std::nothrow) Timer(name, func, interval, times, atOnce, autoRelease);
if (pTimer)
{
pTimer->retain();
pTimer->start();
s_vTimers.push_back(pTimer);
}
return pTimer;
}
e2d::Timer* e2d::TimerManager::start(double timeOut, Function func)
{
auto pTimer = new (std::nothrow) Timer(L"", func, timeOut, 1, false, true);
if (pTimer)
{
pTimer->retain();
pTimer->start();
s_vTimers.push_back(pTimer);
}
return pTimer;
}
void e2d::TimerManager::add(Timer * pTimer)
{
WARN_IF(pTimer == nullptr, "Timer NULL pointer exception!");
if (pTimer)
{
auto findTimer = [](Timer * pTimer) -> bool
{
FOR_LOOP(t, s_vTimers)
{
if (pTimer == t)
{
return true;
}
}
return false;
};
bool bHasTimer = findTimer(pTimer);
WARN_IF(bHasTimer, "The timer is already added, cannot be added again!");
if (!bHasTimer)
{
pTimer->retain();
s_vTimers.push_back(pTimer);
}
}
}
void e2d::TimerManager::start(String name)
{
FOR_LOOP(timer, s_vTimers)
{
if (timer->getName() == name)
{
timer->start();
}
}
}
void e2d::TimerManager::stop(String name)
{
FOR_LOOP(timer, s_vTimers)
{
if (timer->getName() == name)
{
timer->stop();
}
}
}
void e2d::TimerManager::clear(String name)
{
FOR_LOOP(timer, s_vTimers)
{
if (timer->getName() == name)
{
timer->stopAndClear();
}
}
}
std::vector<e2d::Timer*> e2d::TimerManager::get(String name)
{
std::vector<Timer*> vTimers;
FOR_LOOP(timer, s_vTimers)
{
if (timer->getName() == name)
{
vTimers.push_back(timer);
}
}
return std::move(vTimers);
}
void e2d::TimerManager::startAll()
{
FOR_LOOP(timer, s_vTimers)
{
timer->start();
}
}
void e2d::TimerManager::stopAll()
{
FOR_LOOP(timer, s_vTimers)
{
timer->stop();
}
}
void e2d::TimerManager::stopAndClearAll()
{
FOR_LOOP(timer, s_vTimers)
{
timer->stop();
timer->release();
}
s_vTimers.clear();
}
std::vector<e2d::Timer*> e2d::TimerManager::getAll()
{
return s_vTimers;
}
void e2d::TimerManager::__resetAllTimers()
{
FOR_LOOP(timer, s_vTimers)
{
timer->m_fLast = Time::getTotalTime();
}
}
void e2d::TimerManager::__uninit()
{
FOR_LOOP(timer, s_vTimers)
{
SafeRelease(&timer);
}
s_vTimers.clear();
}

View File

@ -1,6 +1,5 @@
#include "..\e2dnode.h" #include "..\e2dnode.h"
#include "..\e2dmanager.h" #include "..\e2dmanager.h"
#include "..\e2dtool.h"
#include "..\e2daction.h" #include "..\e2daction.h"
#include "..\e2dcollider.h" #include "..\e2dcollider.h"
#include <algorithm> #include <algorithm>

View File

@ -1,128 +1,180 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
#include "..\e2dnode.h" #include "..\e2dnode.h"
#include "..\e2dmanager.h"
e2d::Timer::Timer(String name, Function func, double interval /* = 0 */, int updateTimes /* = -1 */, bool atOnce /* = false */, bool autoRelease /* = false */) class TimerInfo
: m_bRunning(false)
, m_nRunTimes(0)
, m_Callback(nullptr)
, m_fInterval(0)
, m_fLast(0)
, m_nUpdateTimes(-1)
, m_bAtOnce(false)
, m_bAutoRelease(false)
, m_bClear(false)
{ {
this->setName(name); public:
this->setFunc(func); TimerInfo(
this->setUpdateTimes(updateTimes); e2d::Function func,
this->setInterval(interval); e2d::String name,
m_bAutoRelease = autoRelease; double delay,
m_bAtOnce = atOnce; int updateTimes,
} bool paused
)
bool e2d::Timer::isRunning() const : running(!paused)
{ , stopped(false)
return m_bRunning; , runTimes(0)
} , totalTimes(updateTimes)
, delay(max(delay, 0))
void e2d::Timer::stop() , lastTime(e2d::Time::getTotalTime())
{ , callback(func)
m_bRunning = false; , name(name)
}
void e2d::Timer::stopAndClear()
{
m_bRunning = false;
m_bClear = true;
}
void e2d::Timer::start()
{
if (!m_bRunning)
{ {
m_bRunning = true;
m_fLast = Time::getTotalTime();
m_nRunTimes = 0;
}
}
void e2d::Timer::start(int times)
{
if (!m_bRunning)
{
m_bRunning = true;
m_fLast = Time::getTotalTime();
m_nUpdateTimes = times;
m_nRunTimes = 0;
}
}
e2d::String e2d::Timer::getName() const
{
return m_sName;
}
void e2d::Timer::setName(String name)
{
m_sName = name;
}
void e2d::Timer::setInterval(double interval)
{
m_fInterval = max(interval, 0);
}
void e2d::Timer::setFunc(Function func)
{
m_Callback = func;
}
void e2d::Timer::setUpdateTimes(int updateTimes)
{
m_nUpdateTimes = updateTimes;
}
void e2d::Timer::setRunAtOnce(bool bAtOnce)
{
m_bAtOnce = bAtOnce;
}
void e2d::Timer::update()
{
if (m_Callback)
{
m_Callback();
} }
m_nRunTimes++; void update()
m_fLast += m_fInterval;
if (m_nRunTimes == m_nUpdateTimes)
{ {
if (m_bAutoRelease) if (this->callback)
{ {
this->stopAndClear(); this->callback();
}
this->runTimes++;
this->lastTime += this->delay;
if (this->runTimes == this->totalTimes)
{
this->stopped = true;
}
}
bool ready()
{
if (this->running)
{
if (this->delay == 0)
return true;
if ((e2d::Time::getTotalTime() - this->lastTime) >= this->delay)
return true;
}
return false;
}
public:
bool running;
bool stopped;
int runTimes;
int totalTimes;
double delay;
double lastTime;
e2d::String name;
e2d::Function callback;
};
static std::vector<TimerInfo*> s_vTimers;
void e2d::Timer::start(Function func, double delay, int updateTimes, bool paused, String name)
{
auto timer = new TimerInfo(func, name, delay, updateTimes, paused);
s_vTimers.push_back(timer);
}
void e2d::Timer::start(Function func, String name)
{
Timer::start(func, 0, -1, false, name);
}
void e2d::Timer::startOnce(Function func, double timeOut)
{
auto timer = new TimerInfo(func, L"", timeOut, 1, false);
s_vTimers.push_back(timer);
}
void e2d::Timer::pause(String name)
{
FOR_LOOP(timer, s_vTimers)
{
if (timer->name == name)
{
timer->running = false;
}
}
}
void e2d::Timer::resume(String name)
{
FOR_LOOP(timer, s_vTimers)
{
if (timer->name == name)
{
timer->running = true;
}
}
}
void e2d::Timer::stop(String name)
{
FOR_LOOP(timer, s_vTimers)
{
if (timer->name == name)
{
timer->stopped = true;
}
}
}
void e2d::Timer::pauseAll()
{
FOR_LOOP(timer, s_vTimers)
{
timer->running = false;
}
}
void e2d::Timer::resumeAll()
{
FOR_LOOP(timer, s_vTimers)
{
timer->running = true;
}
}
void e2d::Timer::stopAll()
{
FOR_LOOP(timer, s_vTimers)
{
timer->stopped = true;
}
}
void e2d::Timer::__update()
{
if (s_vTimers.empty() || Game::isPaused())
return;
for (size_t i = 0; i < s_vTimers.size();)
{
auto timer = s_vTimers[i];
// 清除已停止的定时器
if (timer->stopped)
{
delete timer;
s_vTimers.erase(s_vTimers.begin() + i);
} }
else else
{ {
this->stop(); // 更新定时器
if (timer->ready())
{
timer->update();
}
++i;
} }
} }
} }
bool e2d::Timer::isReady() const void e2d::Timer::__resetAll()
{ {
if (m_bRunning && !m_bClear) FOR_LOOP(timer, s_vTimers)
{ {
if (m_bAtOnce && m_nRunTimes == 0) timer->lastTime = Time::getTotalTime();
return true;
if (m_fInterval == 0)
return true;
if ((Time::getTotalTime() - m_fLast) >= m_fInterval)
return true;
} }
return false;
} }
void e2d::Timer::__uninit()
{
s_vTimers.clear();
}

View File

@ -45,7 +45,7 @@ void e2d::Transition::_init(Scene * prev, Scene * next)
if (FAILED(hr)) if (FAILED(hr))
{ {
ASSERT(false, L"Create layer failed!"); ASSERT(false, "Create layer failed!");
} }
m_fLast = Time::getTotalTime(); m_fLast = Time::getTotalTime();

View File

@ -87,79 +87,6 @@ private:
}; };
// 定时器管理器
class TimerManager
{
friend Game;
friend Node;
friend Timer;
public:
// 启动一个新任务
static Timer* start(
String name, /* 任务名称 */
Function func, /* 执行函数 */
double interval = 0, /* 时间间隔(秒) */
int times = -1, /* 执行次数(设 -1 为永久执行) */
bool atOnce = false, /* 是否立即执行 */
bool autoRelease = false /* 自动清除 */
);
// 启动一个新任务:等待一段时间后执行指定函数
static Timer* start(
double timeOut, /* 等待的时长(秒) */
Function func /* 执行的函数 */
);
// 启动具有相同名称的定时器
static void start(
String name
);
// 停止具有相同名称的定时器
static void stop(
String name
);
// 删除具有相同名称的定时器
static void clear(
String name
);
// 添加定时器
static void add(
Timer * pTimer
);
// 获取名称相同的定时器
static std::vector<Timer*> get(
String name
);
// 启动所有定时器
static void startAll();
// 停止所有定时器
static void stopAll();
// 停止并清除所有定时器
static void stopAndClearAll();
// 获取所有定时器
static std::vector<Timer*> getAll();
private:
// 更新定时器
static void __update();
// 重置定时器状态
static void __resetAllTimers();
// 清空定时器
static void __uninit();
};
// 动作管理器 // 动作管理器
class ActionManager class ActionManager
{ {
@ -241,7 +168,7 @@ private:
); );
// 重置所有动作状态 // 重置所有动作状态
static void __resetAllActions(); static void __resetAll();
// 回收资源 // 回收资源
static void __uninit(); static void __uninit();

View File

@ -5,7 +5,6 @@
namespace e2d namespace e2d
{ {
class TimerManager;
class MusicManager; class MusicManager;
class InputManager; class InputManager;
class ColliderManager; class ColliderManager;
@ -161,83 +160,65 @@ protected:
// 定时器 // 定时器
class Timer : class Timer
public Object
{ {
friend TimerManager; friend Game;
public: public:
Timer( // 启动定时器
String name = L"", /* 任务名称 */ static void start(
Function func = nullptr, /* 执行函数 */ Function func, /* 执行函数 */
double interval = 0, /* 时间间隔(秒) */ String name /* 定时器名称 */
int times = -1, /* 执行次数(设 -1 为永久执行) */
bool atOnce = false, /* 是否立即执行 */
bool autoRelease = false /* 执行结束时自动清除 */
); );
// 启动定时器 // 启动定时器
void start(); static void start(
Function func, /* 执行函数 */
// 启动定时器,并执行指定次数 double delay = 0, /* 时间间隔(秒) */
void start( int times = -1, /* 执行次数(设 -1 为永久执行) */
int times /* 执行次数(设 -1 为永久执行) */ bool paused = false, /* 是否暂停 */
String name = L"" /* 定时器名称 */
); );
// 停止定时器 // 启动仅执行一次的定时器
void stop(); static void startOnce(
Function func, /* 执行的函数 */
double timeOut /* 等待的时长(秒) */
);
// 停止并清除该定时器 // 暂停具有相同名称的定时器
void stopAndClear(); static void pause(
// 更新定时器
void update();
// 获取定时器状态
bool isRunning() const;
// 判断是否达到执行状态
bool isReady() const;
// 获取定时器名称
String getName() const;
// 设置定时器名称
void setName(
String name String name
); );
// 设置定时器执行间隔 // 继续具有相同名称的定时器
void setInterval( static void resume(
double fInterval /* 时间间隔(秒) */ String name
); );
// 设置定时器的执行函数 // 停止具有相同名称的定时器
void setFunc( static void stop(
Function func String name
); );
// 设置定时器执行次数 // 暂停所有定时器
void setUpdateTimes( static void pauseAll();
int nUpdateTimes /* 执行次数(设 -1 为永久执行) */
);
// 设置定时器在绑定后立即执行一次 // 继续所有定时器
virtual void setRunAtOnce( static void resumeAll();
bool bAtOnce
);
protected: // 停止所有定时器
String m_sName; static void stopAll();
bool m_bRunning;
bool m_bAtOnce; private:
bool m_bAutoRelease; // 更新定时器
bool m_bClear; static void __update();
int m_nRunTimes;
int m_nUpdateTimes; // 重置定时器状态
double m_fInterval; static void __resetAll();
double m_fLast;
Function m_Callback; // 清空定时器
static void __uninit();
}; };

View File

@ -237,7 +237,6 @@
<ClCompile Include="..\..\core\Manager\ObjectManager.cpp" /> <ClCompile Include="..\..\core\Manager\ObjectManager.cpp" />
<ClCompile Include="..\..\core\Manager\ColliderManager.cpp" /> <ClCompile Include="..\..\core\Manager\ColliderManager.cpp" />
<ClCompile Include="..\..\core\Manager\SceneManager.cpp" /> <ClCompile Include="..\..\core\Manager\SceneManager.cpp" />
<ClCompile Include="..\..\core\Manager\TimerManager.cpp" />
<ClCompile Include="..\..\core\Node\Button.cpp" /> <ClCompile Include="..\..\core\Node\Button.cpp" />
<ClCompile Include="..\..\core\Node\ButtonToggle.cpp" /> <ClCompile Include="..\..\core\Node\ButtonToggle.cpp" />
<ClCompile Include="..\..\core\Node\Menu.cpp" /> <ClCompile Include="..\..\core\Node\Menu.cpp" />

View File

@ -102,9 +102,6 @@
<ClCompile Include="..\..\core\Manager\ObjectManager.cpp"> <ClCompile Include="..\..\core\Manager\ObjectManager.cpp">
<Filter>Manager</Filter> <Filter>Manager</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Manager\TimerManager.cpp">
<Filter>Manager</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Node\Button.cpp"> <ClCompile Include="..\..\core\Node\Button.cpp">
<Filter>Node</Filter> <Filter>Node</Filter>
</ClCompile> </ClCompile>