监听器重做

This commit is contained in:
Nomango 2018-04-24 13:28:21 +08:00
parent f5185f5630
commit da08f33a02
17 changed files with 263 additions and 462 deletions

View File

@ -1,17 +1,27 @@
#include "..\e2dbase.h"
// 上一帧与当前帧的时间间隔
static int s_nInterval = 0;
static unsigned int s_nInterval = 0;
// 游戏开始时长
static double s_fTotalTime = 0;
static unsigned int s_nTotalTime = 0;
double e2d::Time::getTotalTime()
{
return s_fTotalTime;
return s_nTotalTime / 1000.0;
}
int e2d::Time::getDeltaTime()
unsigned int e2d::Time::getTotalTimeMilliseconds()
{
return s_nTotalTime;
}
double e2d::Time::getDeltaTime()
{
return s_nInterval / 1000.0;
}
unsigned int e2d::Time::getDeltaTimeMilliseconds()
{
return s_nInterval;
}
@ -64,8 +74,8 @@ void e2d::Time::__updateLast()
s_tLastUpdate = s_tNow;
s_tNow = steady_clock::now();
s_nInterval = static_cast<int>(duration_cast<milliseconds>(s_tNow - s_tLastUpdate).count());
s_fTotalTime = static_cast<double>(duration_cast<milliseconds>(s_tNow - s_tStart).count()) / 1000.0;
s_nInterval = static_cast<unsigned int>(duration_cast<milliseconds>(s_tNow - s_tLastUpdate).count());
s_nTotalTime = static_cast<unsigned int>(duration_cast<milliseconds>(s_tNow - s_tStart).count());
}
void e2d::Time::__sleep()
@ -132,8 +142,8 @@ void e2d::Time::__updateLast()
s_tLastUpdate = s_tNow;
::QueryPerformanceCounter(&s_tNow);
s_nInterval = static_cast<int>((s_tNow.QuadPart - s_tLastUpdate.QuadPart) * 1000LL / s_tFreq.QuadPart);
s_fTotalTime = static_cast<double>(s_tNow.QuadPart - s_tStart.QuadPart) / s_tFreq.QuadPart;
s_nInterval = static_cast<unsigned int>((s_tNow.QuadPart - s_tLastUpdate.QuadPart) * 1000LL / s_tFreq.QuadPart);
s_nTotalTime = static_cast<unsigned int>(s_tNow.QuadPart - s_tStart.QuadPart) * 1000LL / s_tFreq.QuadPart;
}
void e2d::Time::__sleep()

View File

@ -67,6 +67,21 @@ bool e2d::Scene::remove(Node * child)
return m_pRoot->removeChild(child);
}
std::vector<e2d::Node*> e2d::Scene::get(String name) const
{
return m_pRoot->getChildren(name);
}
e2d::Node * e2d::Scene::getOne(String name) const
{
return m_pRoot->getChild(name);
}
std::vector<e2d::Node*> e2d::Scene::getAll() const
{
return m_pRoot->getAllChildren();
}
e2d::Node * e2d::Scene::getRoot() const
{
return m_pRoot;

View File

@ -179,7 +179,7 @@ void e2d::ActionManager::__uninit()
void e2d::ActionManager::resumeAll()
{
FOR_LOOP(child, SceneManager::getCurrentScene()->getRoot()->getChildren())
FOR_LOOP(child, SceneManager::getCurrentScene()->getRoot()->getAllChildren())
{
ActionManager::__resumeAllBindedWith(child);
}
@ -187,7 +187,7 @@ void e2d::ActionManager::resumeAll()
void e2d::ActionManager::pauseAll()
{
FOR_LOOP(child, SceneManager::getCurrentScene()->getRoot()->getChildren())
FOR_LOOP(child, SceneManager::getCurrentScene()->getRoot()->getAllChildren())
{
ActionManager::__pauseAllBindedWith(child);
}
@ -195,7 +195,7 @@ void e2d::ActionManager::pauseAll()
void e2d::ActionManager::stopAll()
{
FOR_LOOP(child, SceneManager::getCurrentScene()->getRoot()->getChildren())
FOR_LOOP(child, SceneManager::getCurrentScene()->getRoot()->getAllChildren())
{
ActionManager::__stopAllBindedWith(child);
}

View File

@ -3,10 +3,43 @@
#include "..\e2dcollider.h"
#include "..\e2dtool.h"
// 监听器
class Listener
{
public:
Listener(
e2d::Function func,
e2d::String name,
bool paused
)
: name(name)
, callback(func)
, running(!paused)
, stopped(false)
{
}
// 更新监听器状态
virtual void update()
{
if (callback)
{
callback();
}
}
public:
bool running;
bool stopped;
e2d::String name;
e2d::Function callback;
};
// 碰撞体集合
static std::vector<e2d::Collider*> s_vColliders;
// 监听器容器
static std::vector<e2d::CollisionListener*> s_vListeners;
static std::vector<Listener*> s_vListeners;
// 碰撞触发状态
static bool s_bCollisionEnable = false;
// 发生碰撞的节点
@ -21,21 +54,23 @@ void e2d::ColliderManager::setEnable(bool bEnable)
void e2d::ColliderManager::__update()
{
if (s_vListeners.size() == 0)
if (s_vListeners.empty() || Game::isPaused())
return;
for (size_t i = 0; i < s_vListeners.size(); i++)
{
auto pListener = s_vListeners[i];
// ¸üмàÌýÆ÷
if (pListener->m_bClear)
// 清除已停止的监听器
if (pListener->stopped)
{
pListener->release();
delete pListener;
s_vListeners.erase(s_vListeners.begin() + i);
}
else if (pListener->isRunning())
else
{
pListener->_update();
// 更新监听器
pListener->update();
++i;
}
}
}
@ -67,15 +102,16 @@ void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider)
pPassiveNode->getParentScene() == pCurrentScene)
{
// 判断两物体是否是相互冲突的物体
auto IsCollideWith = [](Node * active, unsigned int hash) -> bool
auto IsCollideWith = [](Node * active, Node * passive) -> bool
{
unsigned int hash = passive->getHashName();
FOR_LOOP(collider, active->m_vColliders)
if (collider == hash)
return true;
return false;
};
if (IsCollideWith(pActiveNode, pPassiveNode->getHashName()))
if (IsCollideWith(pActiveNode, pPassiveNode))
{
// 判断两碰撞体交集情况
int relation = pActiveCollider->getRelationWith(pPassiveCollider);
@ -97,47 +133,30 @@ void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider)
s_pPassiveNode = nullptr;
}
void e2d::ColliderManager::__add(CollisionListener * pListener)
void e2d::ColliderManager::add(Function func, String name, bool paused)
{
WARN_IF(pListener == nullptr, "CollisionListener NULL pointer exception!");
auto listener = new Listener(func, name, paused);
s_vListeners.push_back(listener);
}
if (pListener)
void e2d::ColliderManager::pause(String name)
{
FOR_LOOP(pListener, s_vListeners)
{
auto findListener = [](CollisionListener * pListener) -> bool
if (pListener->name == name)
{
FOR_LOOP(l, s_vListeners)
{
if (pListener == l)
{
return true;
}
}
return false;
};
bool bHasListener = findListener(pListener);
WARN_IF(bHasListener, "The CollisionListener is already added, cannot be added again!");
if (!bHasListener)
{
pListener->retain();
s_vListeners.push_back(pListener);
pListener->running = false;
}
}
}
void e2d::ColliderManager::add(Function func, String name)
{
(new CollisionListener(func, name))->start();
}
void e2d::ColliderManager::start(String name)
void e2d::ColliderManager::resume(String name)
{
FOR_LOOP(pListener, s_vListeners)
{
if (pListener->getName() == name)
if (pListener->name == name)
{
pListener->start();
pListener->running = true;
}
}
}
@ -146,29 +165,26 @@ void e2d::ColliderManager::stop(String name)
{
FOR_LOOP(pListener, s_vListeners)
{
if (pListener->getName() == name)
if (pListener->name == name)
{
pListener->stop();
pListener->stopped = true;
}
}
}
void e2d::ColliderManager::clear(String name)
void e2d::ColliderManager::pauseAll()
{
FOR_LOOP(pListener, s_vListeners)
{
if (pListener->getName() == name)
{
pListener->stopAndClear();
}
pListener->running = false;
}
}
void e2d::ColliderManager::startAll()
void e2d::ColliderManager::resumeAll()
{
FOR_LOOP(pListener, s_vListeners)
{
pListener->start();
pListener->running = true;
}
}
@ -176,36 +192,10 @@ void e2d::ColliderManager::stopAll()
{
FOR_LOOP(pListener, s_vListeners)
{
pListener->stop();
pListener->stopped = true;
}
}
void e2d::ColliderManager::clearAll()
{
FOR_LOOP(pListener, s_vListeners)
{
pListener->stopAndClear();
}
}
std::vector<e2d::CollisionListener*> e2d::ColliderManager::get(String name)
{
std::vector<CollisionListener*> vListeners;
FOR_LOOP(pListener, s_vListeners)
{
if (pListener->getName() == name)
{
vListeners.push_back(pListener);
}
}
return std::move(vListeners);
}
std::vector<e2d::CollisionListener*> e2d::ColliderManager::getAll()
{
return s_vListeners;
}
e2d::Node * e2d::ColliderManager::getActiveNode()
{
return s_pActiveNode;
@ -268,7 +258,7 @@ void e2d::ColliderManager::__uninit()
{
FOR_LOOP(listener, s_vListeners)
{
SafeRelease(&listener);
delete listener;
}
s_vListeners.clear();
}

View File

@ -1,78 +1,66 @@
#include "..\e2dmanager.h"
#include "..\e2dtool.h"
// 监听器
class Listener
{
public:
Listener(
e2d::Function func,
e2d::String name,
bool paused
)
: name(name)
, callback(func)
, running(!paused)
, stopped(false)
{
}
// 更新监听器状态
virtual void update()
{
if (callback)
{
callback();
}
}
public:
bool running;
bool stopped;
e2d::String name;
e2d::Function callback;
};
// ¼àÌýÆ÷ÈÝÆ÷
static std::vector<e2d::InputListener*> s_vListeners;
static std::vector<Listener*> s_vListeners;
void e2d::InputManager::__update()
void e2d::InputManager::add(Function func, String name, bool paused)
{
for (size_t i = 0; i < s_vListeners.size(); i++)
{
auto pListener = s_vListeners[i];
// ¸üмàÌýÆ÷
if (pListener->m_bClear)
{
pListener->release();
s_vListeners.erase(s_vListeners.begin() + i);
}
else if (pListener->isRunning())
{
pListener->_update();
}
}
auto listener = new Listener(func, name, paused);
s_vListeners.push_back(listener);
}
void e2d::InputManager::__uninit()
{
FOR_LOOP(listener, s_vListeners)
{
SafeRelease(&listener);
}
s_vListeners.clear();
}
void e2d::InputManager::__add(InputListener * pListener)
{
WARN_IF(pListener == nullptr, "InputListener NULL pointer exception!");
if (pListener)
{
auto findListener = [](InputListener * pListener) -> bool
{
FOR_LOOP(l, s_vListeners)
{
if (pListener == l)
{
return true;
}
}
return false;
};
bool bHasListener = findListener(pListener);
WARN_IF(bHasListener, "The InputListener is already added, cannot be added again!");
if (!bHasListener)
{
pListener->retain();
s_vListeners.push_back(pListener);
}
}
}
void e2d::InputManager::add(Function func, String name)
{
(new InputListener(func, name))->start();
}
void e2d::InputManager::start(String name)
void e2d::InputManager::pause(String name)
{
FOR_LOOP(pListener, s_vListeners)
{
if (pListener->getName() == name)
if (pListener->name == name)
{
pListener->start();
pListener->running = false;
}
}
}
void e2d::InputManager::resume(String name)
{
FOR_LOOP(pListener, s_vListeners)
{
if (pListener->name == name)
{
pListener->running = true;
}
}
}
@ -81,29 +69,26 @@ void e2d::InputManager::stop(String name)
{
FOR_LOOP(pListener, s_vListeners)
{
if (pListener->getName() == name)
if (pListener->name == name)
{
pListener->stop();
pListener->stopped = true;
}
}
}
void e2d::InputManager::clear(String name)
void e2d::InputManager::pauseAll()
{
FOR_LOOP(pListener, s_vListeners)
{
if (pListener->getName() == name)
{
pListener->stopAndClear();
}
pListener->running = false;
}
}
void e2d::InputManager::startAll()
void e2d::InputManager::resumeAll()
{
FOR_LOOP(pListener, s_vListeners)
{
pListener->start();
pListener->running = true;
}
}
@ -111,32 +96,38 @@ void e2d::InputManager::stopAll()
{
FOR_LOOP(pListener, s_vListeners)
{
pListener->stop();
pListener->stopped = true;
}
}
void e2d::InputManager::clearAll()
void e2d::InputManager::__update()
{
FOR_LOOP(pListener, s_vListeners)
{
pListener->stopAndClear();
}
}
if (s_vListeners.empty() || Game::isPaused())
return;
std::vector<e2d::InputListener*> e2d::InputManager::get(String name)
{
std::vector<InputListener*> vListeners;
FOR_LOOP(pListener, s_vListeners)
for (size_t i = 0; i < s_vListeners.size(); i++)
{
if (pListener->getName() == name)
auto pListener = s_vListeners[i];
// 清除已停止的监听器
if (pListener->stopped)
{
vListeners.push_back(pListener);
delete pListener;
s_vListeners.erase(s_vListeners.begin() + i);
}
else
{
// 更新监听器
pListener->update();
++i;
}
}
return std::move(vListeners);
}
std::vector<e2d::InputListener*> e2d::InputManager::getAll()
void e2d::InputManager::__uninit()
{
return s_vListeners;
FOR_LOOP(listener, s_vListeners)
{
delete listener;
}
s_vListeners.clear();
}

View File

@ -692,7 +692,7 @@ e2d::Scene * e2d::Node::getParentScene() const
return m_pParentScene;
}
std::vector<e2d::Node*> e2d::Node::getChildren(String name)
std::vector<e2d::Node*> e2d::Node::getChildren(String name) const
{
std::vector<Node*> vChildren;
unsigned int hash = name.getHashCode();
@ -708,7 +708,22 @@ std::vector<e2d::Node*> e2d::Node::getChildren(String name)
return std::move(vChildren);
}
std::vector<e2d::Node*> e2d::Node::getChildren()
e2d::Node * e2d::Node::getChild(String name) const
{
unsigned int hash = name.getHashCode();
FOR_LOOP(child, m_vChildren)
{
// 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度
if (child->m_nHashName == hash && child->m_sName == name)
{
return child;
}
}
return nullptr;
}
std::vector<e2d::Node*> e2d::Node::getAllChildren() const
{
return m_vChildren;
}

View File

@ -1,30 +0,0 @@
#include "..\..\e2dtool.h"
#include "..\..\e2dmanager.h"
e2d::CollisionListener::CollisionListener()
: Listener()
{
ColliderManager::__add(this);
}
e2d::CollisionListener::CollisionListener(Function func)
: Listener()
, m_callback(func)
{
ColliderManager::__add(this);
}
e2d::CollisionListener::CollisionListener(Function func, String name)
: Listener(name)
, m_callback(func)
{
ColliderManager::__add(this);
}
void e2d::CollisionListener::_update()
{
if (m_callback)
{
m_callback();
}
}

View File

@ -1,36 +0,0 @@
#include "..\..\e2dtool.h"
#include "..\..\e2dmanager.h"
e2d::InputListener::InputListener()
: Listener()
, m_callback(nullptr)
{
InputManager::__add(this);
}
e2d::InputListener::InputListener(Function func)
: Listener()
, m_callback(func)
{
InputManager::__add(this);
}
e2d::InputListener::InputListener(Function func, String name)
: Listener(name)
, m_callback(func)
{
InputManager::__add(this);
}
void e2d::InputListener::setFunc(Function func)
{
m_callback = func;
}
void e2d::InputListener::_update()
{
if (m_callback)
{
m_callback();
}
}

View File

@ -1,45 +0,0 @@
#include "..\..\e2dtool.h"
e2d::Listener::Listener()
: m_bRunning(false)
, m_bClear(false)
{
}
e2d::Listener::Listener(String name)
: m_bRunning(false)
, m_sName(name)
, m_bClear(false)
{
}
void e2d::Listener::start()
{
m_bRunning = true;
}
void e2d::Listener::stop()
{
m_bRunning = false;
}
void e2d::Listener::stopAndClear()
{
m_bRunning = false;
m_bClear = true;
}
bool e2d::Listener::isRunning()
{
return m_bRunning;
}
e2d::String e2d::Listener::getName()
{
return m_sName;
}
void e2d::Listener::setName(String name)
{
m_sName = name;
}

View File

@ -176,5 +176,9 @@ void e2d::Timer::__resetAll()
void e2d::Timer::__uninit()
{
FOR_LOOP(timer, s_vTimers)
{
delete timer;
}
s_vTimers.clear();
}

View File

@ -116,12 +116,18 @@ class Time
friend Game;
public:
// 获取上一帧与当前帧的时间间隔(秒)
static int getDeltaTime();
// 获取上一帧与当前帧的时间间隔(秒)
static double getDeltaTime();
// 获取游戏开始时长(秒)
// 获取上一帧与当前帧的时间间隔(毫秒)
static unsigned int getDeltaTimeMilliseconds();
// 获取游戏总时长(秒)
static double getTotalTime();
// 获取游戏总时长(毫秒)
static unsigned int getTotalTimeMilliseconds();
private:
// 初始化计时操作
static bool __init();

View File

@ -740,6 +740,19 @@ public:
Node * child
);
// 获取所有名称相同的子节点
std::vector<Node*> get(
String name
) const;
// 获取名称相同的子节点
Node* getOne(
String name
) const;
// 获取所有子节点
std::vector<Node*> getAll() const;
// 获取根节点
Node * getRoot() const;
@ -768,6 +781,13 @@ protected:
template<typename Object>
inline void SafeRelease(Object** p) { if (*p) { (*p)->release(); *p = nullptr; } }
inline void SafeRelease(Object** p)
{
if (*p)
{
(*p)->release();
(*p) = nullptr;
}
}
}

View File

@ -14,8 +14,6 @@ class Action;
class Music;
class Collider;
class Transition;
class InputListener;
class CollisionListener;
// 对象管理器
class ObjectManager
@ -232,17 +230,22 @@ class InputManager
{
friend Game;
friend Input;
friend InputListener;
public:
// 添加输入监听
static void add(
Function func, /* 监听到用户输入时的执行函数 */
String name = L"" /* 监听器名称 */
String name = L"", /* 监听器名称 */
bool paused = false /* 是否暂停 */
);
// 启动输入监听
static void start(
// 暂停输入监听
static void pause(
String name
);
// 暂停输入监听
static void resume(
String name
);
@ -251,34 +254,16 @@ public:
String name
);
// 清除输入监听
static void clear(
String name
);
// 暂停所有监听器
static void pauseAll();
// 启动所有监听器
static void startAll();
// 继续所有监听器
static void resumeAll();
// 停止所有监听器
static void stopAll();
// 清除所有监听器
static void clearAll();
// 获取监听器
static std::vector<InputListener*> get(
String name
);
// 获取全部监听器
static std::vector<InputListener*> getAll();
private:
// 添加输入监听
static void __add(
InputListener * pListener
);
// 更新监听器
static void __update();
@ -293,7 +278,6 @@ class ColliderManager
friend Game;
friend Node;
friend Collider;
friend CollisionListener;
public:
// 开启或关闭碰撞监听功能(默认关闭)
@ -304,11 +288,17 @@ public:
// 添加碰撞监听
static void add(
Function func, /* 监听到碰撞时的执行函数 */
String name = L"" /* 监听器名称 */
String name = L"", /* 监听器名称 */
bool paused = false /* 是否暂停 */
);
// 启动碰撞监听
static void start(
// 暂停碰撞监听
static void pause(
String name
);
// 暂停碰撞监听
static void resume(
String name
);
@ -317,28 +307,15 @@ public:
String name
);
// 清除碰撞监听
static void clear(
String name
);
// 暂停所有监听器
static void pauseAll();
// 启动所有监听器
static void startAll();
// 继续所有监听器
static void resumeAll();
// 停止所有监听器
static void stopAll();
// 清除所有监听器
static void clearAll();
// 获取监听器
static std::vector<CollisionListener*> get(
String name
);
// 获取全部监听器
static std::vector<CollisionListener*> getAll();
// 获取碰撞发生时的主动体
static Node * getActiveNode();
@ -356,11 +333,6 @@ public:
);
private:
// 添加碰撞监听
static void __add(
CollisionListener * pListener
);
// 更新监听器
static void __update();

View File

@ -131,10 +131,15 @@ public:
// 获取所有名称相同的子节点
virtual std::vector<Node*> getChildren(
String name
);
) const;
// 获取名称相同的子节点
virtual Node* getChild(
String name
) const;
// 获取所有子节点
virtual std::vector<Node*> getChildren();
virtual std::vector<Node*> getAllChildren() const;
// 获取子节点数量
virtual int getChildrenCount() const;

View File

@ -234,107 +234,6 @@ private:
};
// 监听器
class Listener
: public Object
{
public:
Listener();
Listener(
String name /* 监听器名称 */
);
// 启动
virtual void start();
// 停止
virtual void stop();
// 停止并清除
virtual void stopAndClear();
// 获取运行状态
virtual bool isRunning();
// 获取名称
virtual String getName();
// 修改名称
virtual void setName(
String name
);
protected:
// 更新监听器状态
virtual void _update() = 0;
protected:
String m_sName;
bool m_bRunning;
bool m_bClear;
};
// 输入监听器
class InputListener
: public Listener
{
friend InputManager;
public:
InputListener();
InputListener(
Function func /* 监听到用户输入时的执行函数 */
);
InputListener(
Function func, /* 监听到用户输入时的执行函数 */
String name /* 监听器名称 */
);
// 设置监听到用户输入时的执行函数
virtual void setFunc(
Function func
);
protected:
// 更新监听器状态
virtual void _update();
protected:
Function m_callback;
};
// 碰撞监听器
class CollisionListener
: public Listener
{
friend ColliderManager;
public:
CollisionListener();
CollisionListener(
Function func /* 监听到用户输入时的执行函数 */
);
CollisionListener(
Function func, /* 监听到用户输入时的执行函数 */
String name /* 监听器名称 */
);
protected:
// 更新监听器状态
virtual void _update();
protected:
Function m_callback;
};
// 数据管理工具
class Data
{

View File

@ -249,9 +249,6 @@
<ClCompile Include="..\..\core\Node\Sprite.cpp" />
<ClCompile Include="..\..\core\Node\Text.cpp" />
<ClCompile Include="..\..\core\Tool\Data.cpp" />
<ClCompile Include="..\..\core\Tool\Listener\CollisionListener.cpp" />
<ClCompile Include="..\..\core\Tool\Listener\InputListener.cpp" />
<ClCompile Include="..\..\core\Tool\Listener\Listener.cpp" />
<ClCompile Include="..\..\core\Tool\Path.cpp" />
<ClCompile Include="..\..\core\Tool\Music.cpp" />
<ClCompile Include="..\..\core\Tool\Random.cpp" />

View File

@ -28,9 +28,6 @@
<Filter Include="Node\Shape">
<UniqueIdentifier>{eb72b49a-5b2f-4fc0-9ad2-8f5e02efac6f}</UniqueIdentifier>
</Filter>
<Filter Include="Tool\Listener">
<UniqueIdentifier>{d3968182-2399-40d4-8e39-accb4711018c}</UniqueIdentifier>
</Filter>
<Filter Include="Custom">
<UniqueIdentifier>{3475b59d-d50c-43b1-8334-bcb9e1703ed2}</UniqueIdentifier>
</Filter>
@ -207,15 +204,6 @@
<ClCompile Include="..\..\core\Node\Shape\Ellipse.cpp">
<Filter>Node\Shape</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Tool\Listener\CollisionListener.cpp">
<Filter>Tool\Listener</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Tool\Listener\InputListener.cpp">
<Filter>Tool\Listener</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Tool\Listener\Listener.cpp">
<Filter>Tool\Listener</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Custom\CustomTextRenderer.cpp">
<Filter>Custom</Filter>
</ClCompile>