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_nTotalTimes(times)
{
ASSERT(m_pAction != nullptr, "ActionLoop NULL pointer exception!");
ASSERT(m_pAction, "ActionLoop NULL pointer exception!");
m_pAction->retain();
}

View File

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

View File

@ -219,7 +219,7 @@ std::vector<e2d::Action*> e2d::ActionManager::getAll()
return s_vActions;
}
void e2d::ActionManager::__resetAllActions()
void e2d::ActionManager::__resetAll()
{
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 */)
{
ASSERT(scene != nullptr, "Next scene NULL pointer exception!");
ASSERT(scene, "Next scene NULL pointer exception!");
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 "..\e2dmanager.h"
#include "..\e2dtool.h"
#include "..\e2daction.h"
#include "..\e2dcollider.h"
#include <algorithm>

View File

@ -1,128 +1,180 @@
#include "..\e2dtool.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 */)
: 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)
class TimerInfo
{
this->setName(name);
this->setFunc(func);
this->setUpdateTimes(updateTimes);
this->setInterval(interval);
m_bAutoRelease = autoRelease;
m_bAtOnce = atOnce;
}
bool e2d::Timer::isRunning() const
{
return m_bRunning;
}
void e2d::Timer::stop()
{
m_bRunning = false;
}
void e2d::Timer::stopAndClear()
{
m_bRunning = false;
m_bClear = true;
}
void e2d::Timer::start()
{
if (!m_bRunning)
public:
TimerInfo(
e2d::Function func,
e2d::String name,
double delay,
int updateTimes,
bool paused
)
: running(!paused)
, stopped(false)
, runTimes(0)
, totalTimes(updateTimes)
, delay(max(delay, 0))
, lastTime(e2d::Time::getTotalTime())
, callback(func)
, name(name)
{
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++;
m_fLast += m_fInterval;
void update()
{
if (this->callback)
{
this->callback();
}
if (m_nRunTimes == m_nUpdateTimes)
{
if (m_bAutoRelease)
{
this->stopAndClear();
}
else
{
this->stop();
}
}
}
this->runTimes++;
this->lastTime += this->delay;
bool e2d::Timer::isReady() const
{
if (m_bRunning && !m_bClear)
if (this->runTimes == this->totalTimes)
{
if (m_bAtOnce && m_nRunTimes == 0)
this->stopped = true;
}
}
bool ready()
{
if (this->running)
{
if (this->delay == 0)
return true;
if (m_fInterval == 0)
return true;
if ((Time::getTotalTime() - m_fLast) >= m_fInterval)
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
{
// 更新定时器
if (timer->ready())
{
timer->update();
}
++i;
}
}
}
void e2d::Timer::__resetAll()
{
FOR_LOOP(timer, s_vTimers)
{
timer->lastTime = Time::getTotalTime();
}
}
void e2d::Timer::__uninit()
{
s_vTimers.clear();
}

View File

@ -45,7 +45,7 @@ void e2d::Transition::_init(Scene * prev, Scene * next)
if (FAILED(hr))
{
ASSERT(false, L"Create layer failed!");
ASSERT(false, "Create layer failed!");
}
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
{
@ -241,7 +168,7 @@ private:
);
// 重置所有动作状态
static void __resetAllActions();
static void __resetAll();
// 回收资源
static void __uninit();

View File

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

View File

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

View File

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