From 38d9671411a4f84a0a89f5690772cbf97009dec4 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sun, 8 Jul 2018 19:13:39 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BE=93=E5=85=A5=E7=9B=91=E5=90=AC=E5=88=86?= =?UTF-8?q?=E7=A6=BB=E5=88=B0InputManager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Base/Game.cpp | 6 +- core/Base/Input.cpp | 139 ---------------------- core/Manager/InputManager.cpp | 162 ++++++++++++++++++++++++++ core/e2dbase.h | 52 --------- core/e2dmanager.h | 73 ++++++++++++ core/e2dtool.h | 3 +- project/vs2012/Easy2D.vcxproj | 4 +- project/vs2012/Easy2D.vcxproj.filters | 12 +- project/vs2013/Easy2D.vcxproj | 4 +- project/vs2013/Easy2D.vcxproj.filters | 12 +- project/vs2017/Easy2D.vcxproj | 1 + project/vs2017/Easy2D.vcxproj.filters | 3 + 12 files changed, 261 insertions(+), 210 deletions(-) create mode 100644 core/Manager/InputManager.cpp diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 187fb3c6..0c18d324 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -44,6 +44,7 @@ void e2d::Game::start(bool cleanup) auto timer = Timer::getInstance(); auto sceneManager = SceneManager::getInstance(); auto actionManager = ActionManager::getInstance(); + auto inputManager = InputManager::getInstance(); auto collisionManager = CollisionManager::getInstance(); // 显示窗口 @@ -76,7 +77,8 @@ void e2d::Game::start(bool cleanup) timer->update(); // 更新定时器 actionManager->update(); // 更新动作管理器 sceneManager->update(); // 更新场景内容 - collisionManager->update(); // 更新碰撞体 + inputManager->update(); // 更新输入监听器 + collisionManager->update(); // 更新碰撞监听器 renderer->render(); // 渲染游戏画面 GC::flush(); // 刷新内存池 @@ -149,7 +151,7 @@ void e2d::Game::cleanup() // 删除碰撞监听器 CollisionManager::getInstance()->clearAllListeners(); // 删除输入监听器 - Input::clearAllListeners(); + InputManager::getInstance()->clearAllListeners(); // 清空图片缓存 Image::clearCache(); // 清空音乐缓存 diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index 54ae286e..435c9482 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -7,7 +7,6 @@ static char s_KeyBuffer[BUFFER_SIZE] = { 0 }; // 用于保存键盘按键信息缓冲区 static char s_KeyRecordBuffer[BUFFER_SIZE] = { 0 }; // 键盘消息二级缓冲区 -static std::vector s_vListeners; // 监听器容器 e2d::Input * e2d::Input::_instance = nullptr; @@ -113,12 +112,6 @@ void e2d::Input::destroyInstance() } void e2d::Input::update() -{ - Input::__updateDeviceState(); - Input::__updateListeners(); -} - -void e2d::Input::__updateDeviceState() { if (_keyboardDevice) { @@ -233,135 +226,3 @@ double e2d::Input::getMouseDeltaZ() { return (double)_mouseState.lZ; } - -e2d::Listener * e2d::Input::addListener(const Function& func, const String& name, bool paused) -{ - auto listener = new (e2d::autorelease) Listener(func, name, paused); - GC::retain(listener); - s_vListeners.push_back(listener); - return listener; -} - -void e2d::Input::addListener(Listener * listener) -{ - if (listener) - { - auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); - if (iter == s_vListeners.end()) - { - GC::retain(listener); - s_vListeners.push_back(listener); - } - } -} - -void e2d::Input::removeListener(Listener * listener) -{ - if (listener) - { - auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); - if (iter != s_vListeners.end()) - { - GC::safeRelease(listener); - s_vListeners.erase(iter); - } - } -} - -void e2d::Input::stopListener(const String& name) -{ - if (s_vListeners.empty() || name.isEmpty()) - return; - - for (auto listener : s_vListeners) - { - if (listener->_name == name) - { - listener->stop(); - } - } -} - -void e2d::Input::startListener(const String& name) -{ - if (s_vListeners.empty() || name.isEmpty()) - return; - - for (auto listener : s_vListeners) - { - if (listener->_name == name) - { - listener->start(); - } - } -} - -void e2d::Input::removeListener(const String& name) -{ - if (s_vListeners.empty() || name.isEmpty()) - return; - - for (auto listener : s_vListeners) - { - if (listener->_name == name) - { - listener->_stopped = true; - } - } -} - -void e2d::Input::stopAllListeners() -{ - for (auto listener : s_vListeners) - { - listener->stop(); - } -} - -void e2d::Input::startAllListeners() -{ - for (auto listener : s_vListeners) - { - listener->start(); - } -} - -void e2d::Input::removeAllListeners() -{ - for (auto listener : s_vListeners) - { - listener->_stopped = true; - } -} - -void e2d::Input::clearAllListeners() -{ - for (auto listener : s_vListeners) - { - GC::release(listener); - } - s_vListeners.clear(); -} - -void e2d::Input::__updateListeners() -{ - if (s_vListeners.empty() || Game::getInstance()->isPaused()) - return; - - for (size_t i = 0; i < s_vListeners.size(); ++i) - { - auto listener = s_vListeners[i]; - // 清除已停止的监听器 - if (listener->_stopped) - { - GC::safeRelease(listener); - s_vListeners.erase(s_vListeners.begin() + i); - } - else - { - // 更新监听器 - listener->_update(); - ++i; - } - } -} diff --git a/core/Manager/InputManager.cpp b/core/Manager/InputManager.cpp new file mode 100644 index 00000000..496fa77b --- /dev/null +++ b/core/Manager/InputManager.cpp @@ -0,0 +1,162 @@ +#include "..\e2dbase.h" +#include "..\e2dmanager.h" +#include "..\e2dtool.h" + + +e2d::InputManager * e2d::InputManager::_instance = nullptr; + +e2d::InputManager * e2d::InputManager::getInstance() +{ + if (!_instance) + _instance = new (std::nothrow) InputManager; + return _instance; +} + +void e2d::InputManager::destroyInstance() +{ + if (_instance) + { + delete _instance; + _instance = nullptr; + } +} + +e2d::InputManager::InputManager() +{ +} + +e2d::InputManager::~InputManager() +{ +} + +e2d::Listener * e2d::InputManager::addListener(const Function& func, const String& name, bool paused) +{ + auto listener = new (e2d::autorelease) Listener(func, name, paused); + GC::retain(listener); + _listeners.push_back(listener); + return listener; +} + +void e2d::InputManager::addListener(Listener * listener) +{ + if (listener) + { + auto iter = std::find(_listeners.begin(), _listeners.end(), listener); + if (iter == _listeners.end()) + { + GC::retain(listener); + _listeners.push_back(listener); + } + } +} + +void e2d::InputManager::removeListener(Listener * listener) +{ + if (listener) + { + auto iter = std::find(_listeners.begin(), _listeners.end(), listener); + if (iter != _listeners.end()) + { + GC::safeRelease(listener); + _listeners.erase(iter); + } + } +} + +void e2d::InputManager::stopListener(const String& name) +{ + if (_listeners.empty() || name.isEmpty()) + return; + + for (auto listener : _listeners) + { + if (listener->_name == name) + { + listener->stop(); + } + } +} + +void e2d::InputManager::startListener(const String& name) +{ + if (_listeners.empty() || name.isEmpty()) + return; + + for (auto listener : _listeners) + { + if (listener->_name == name) + { + listener->start(); + } + } +} + +void e2d::InputManager::removeListener(const String& name) +{ + if (_listeners.empty() || name.isEmpty()) + return; + + for (auto listener : _listeners) + { + if (listener->_name == name) + { + listener->_stopped = true; + } + } +} + +void e2d::InputManager::stopAllListeners() +{ + for (auto listener : _listeners) + { + listener->stop(); + } +} + +void e2d::InputManager::startAllListeners() +{ + for (auto listener : _listeners) + { + listener->start(); + } +} + +void e2d::InputManager::removeAllListeners() +{ + for (auto listener : _listeners) + { + listener->_stopped = true; + } +} + +void e2d::InputManager::clearAllListeners() +{ + for (auto listener : _listeners) + { + GC::release(listener); + } + _listeners.clear(); +} + +void e2d::InputManager::update() +{ + if (_listeners.empty() || Game::getInstance()->isPaused()) + return; + + for (size_t i = 0; i < _listeners.size(); ++i) + { + auto listener = _listeners[i]; + // 清除已停止的监听器 + if (listener->_stopped) + { + GC::safeRelease(listener); + _listeners.erase(_listeners.begin() + i); + } + else + { + // 更新监听器 + listener->_update(); + ++i; + } + } +} diff --git a/core/e2dbase.h b/core/e2dbase.h index ffe95c88..31a25d12 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -226,8 +226,6 @@ private: }; -class Listener; - // 输入设备 class Input { @@ -356,50 +354,6 @@ public: // 刷新输入设备状态 void update(); - // 添加输入监听 - static Listener * addListener( - const Function& func, /* 监听到用户输入时的执行函数 */ - const String& name = L"", /* 监听器名称 */ - bool paused = false /* 是否暂停 */ - ); - - // 添加碰撞监听 - static void addListener( - Listener * listener /* 监听器 */ - ); - - // 移除监听器 - static void removeListener( - Listener * listener /* 监听器 */ - ); - - // 启动输入监听 - static void startListener( - const String& name - ); - - // 停止输入监听 - static void stopListener( - const String& name - ); - - // 移除输入监听 - static void removeListener( - const String& name - ); - - // 启动所有监听器 - static void startAllListeners(); - - // 停止所有监听器 - static void stopAllListeners(); - - // 移除所有监听器 - static void removeAllListeners(); - - // 强制清空所有监听器 - static void clearAllListeners(); - private: Input(); @@ -407,12 +361,6 @@ private: E2D_DISABLE_COPY(Input); - // 刷新设备状态 - void __updateDeviceState(); - - // 更新监听器 - static void __updateListeners(); - private: IDirectInput8* _directInput; IDirectInputDevice8* _keyboardDevice; diff --git a/core/e2dmanager.h b/core/e2dmanager.h index cfa832a1..218324e5 100644 --- a/core/e2dmanager.h +++ b/core/e2dmanager.h @@ -172,6 +172,79 @@ private: class Listener; +// 用户输入管理器 +class InputManager +{ + friend class Node; + +public: + // 获取碰撞体管理器实例 + static InputManager * getInstance(); + + // 销毁实例 + static void destroyInstance(); + + // 添加输入监听 + Listener * addListener( + const Function& func, /* 监听到用户输入时的执行函数 */ + const String& name = L"", /* 监听器名称 */ + bool paused = false /* 是否暂停 */ + ); + + // 添加碰撞监听 + void addListener( + Listener * listener /* 监听器 */ + ); + + // 移除监听器 + void removeListener( + Listener * listener /* 监听器 */ + ); + + // 启动输入监听 + void startListener( + const String& name + ); + + // 停止输入监听 + void stopListener( + const String& name + ); + + // 移除输入监听 + void removeListener( + const String& name + ); + + // 启动所有监听器 + void startAllListeners(); + + // 停止所有监听器 + void stopAllListeners(); + + // 移除所有监听器 + void removeAllListeners(); + + // 强制清空所有监听器 + void clearAllListeners(); + + // 更新监听器 + void update(); + +private: + InputManager(); + + ~InputManager(); + + E2D_DISABLE_COPY(InputManager); + +private: + std::vector _listeners; + + static InputManager * _instance; +}; + + // 碰撞体管理器 class CollisionManager { diff --git a/core/e2dtool.h b/core/e2dtool.h index 29d21703..4ba4a6ed 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -377,13 +377,14 @@ private: }; +class InputManager; class CollisionManager; // 监听器 class Listener : public Ref { - friend class Input; + friend class InputManager; friend class CollisionManager; public: diff --git a/project/vs2012/Easy2D.vcxproj b/project/vs2012/Easy2D.vcxproj index cd22f0a4..cb487ee4 100644 --- a/project/vs2012/Easy2D.vcxproj +++ b/project/vs2012/Easy2D.vcxproj @@ -58,7 +58,6 @@ - @@ -77,7 +76,8 @@ - + + diff --git a/project/vs2012/Easy2D.vcxproj.filters b/project/vs2012/Easy2D.vcxproj.filters index 4a47d83b..03303913 100644 --- a/project/vs2012/Easy2D.vcxproj.filters +++ b/project/vs2012/Easy2D.vcxproj.filters @@ -122,9 +122,6 @@ Base - - Collider - Common @@ -176,9 +173,6 @@ Manager - - Manager - Manager @@ -260,5 +254,11 @@ Common + + Manager + + + Manager + \ No newline at end of file diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index 1237453c..a531da63 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -202,7 +202,6 @@ - @@ -221,7 +220,8 @@ - + + diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 891045fd..c279e3d1 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -122,9 +122,6 @@ Base - - Collider - Common @@ -176,9 +173,6 @@ Manager - - Manager - Manager @@ -260,5 +254,11 @@ Common + + Manager + + + Manager + \ No newline at end of file diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index a8b36903..2836fe63 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -240,6 +240,7 @@ + diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 691c6aec..64bb623a 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -240,6 +240,9 @@ Manager + + Manager +