Input类单例模式重做

This commit is contained in:
Nomango 2018-07-04 15:33:09 +08:00
parent 17d73916ba
commit 2eaa3814c5
6 changed files with 152 additions and 156 deletions

View File

@ -11,10 +11,12 @@ e2d::Game::Game()
, _paused(false) , _paused(false)
, _initialized(false) , _initialized(false)
{ {
CoInitialize(nullptr);
} }
e2d::Game::~Game() e2d::Game::~Game()
{ {
CoUninitialize();
} }
e2d::Game * e2d::Game::getInstance() e2d::Game * e2d::Game::getInstance()
@ -33,41 +35,6 @@ void e2d::Game::destroyInstance()
} }
} }
bool e2d::Game::init()
{
if (_initialized)
{
WARN("The game has been initialized!");
return false;
}
// 初始化 COM 组件
CoInitialize(nullptr);
bool bInputInit = false;
auto DestroyResources = [&]()
{
if (bInputInit) Input::__uninit();
};
// 初始化 DirectInput
if (Input::__init())
{
bInputInit = true;
}
else
{
DestroyResources();
throw SystemException(L"初始化 DirectInput 组件失败");
}
// 初始化成功
_initialized = true;
return _initialized;
}
void e2d::Game::start(bool cleanup) void e2d::Game::start(bool cleanup)
{ {
if (!_initialized) if (!_initialized)
@ -75,8 +42,11 @@ void e2d::Game::start(bool cleanup)
throw Exception(L"开始游戏前未进行初始化"); throw Exception(L"开始游戏前未进行初始化");
} }
auto gc = GC::getInstance();
auto input = Input::getInstance();
auto window = Window::getInstance(); auto window = Window::getInstance();
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
// 初始化场景管理器 // 初始化场景管理器
SceneManager::__init(); SceneManager::__init();
@ -101,7 +71,7 @@ void e2d::Game::start(bool cleanup)
// 判断是否达到了刷新状态 // 判断是否达到了刷新状态
if (Time::__isReady()) if (Time::__isReady())
{ {
Input::__update(); // 获取用户输入 input->__update(); // 获取用户输入
Timer::__update(); // 更新定时器 Timer::__update(); // 更新定时器
ActionManager::__update(); // 更新动作管理器 ActionManager::__update(); // 更新动作管理器
SceneManager::__update(); // 更新场景内容 SceneManager::__update(); // 更新场景内容
@ -111,8 +81,8 @@ void e2d::Game::start(bool cleanup)
} }
else else
{ {
Time::__sleep(); // 挂起线程 Time::__sleep(); // 挂起线程
GC::getInstance()->__update(); // 刷新内存池 gc->__update(); // 刷新内存池
} }
} }
@ -160,9 +130,6 @@ void e2d::Game::quit()
void e2d::Game::cleanup() void e2d::Game::cleanup()
{ {
if (!_initialized)
return;
// 删除所有场景 // 删除所有场景
SceneManager::__uninit(); SceneManager::__uninit();
// 删除输入监听器 // 删除输入监听器
@ -175,12 +142,6 @@ void e2d::Game::cleanup()
Image::clearCache(); Image::clearCache();
// 清空定时器 // 清空定时器
Timer::__uninit(); Timer::__uninit();
// 关闭输入
Input::__uninit();
// 删除所有对象 // 删除所有对象
GC::getInstance()->clear(); GC::getInstance()->clear();
CoUninitialize();
_initialized = false;
} }

View File

@ -1,39 +1,37 @@
#include "..\e2dbase.h" #include "..\e2dbase.h"
#include "..\e2dtool.h" #include "..\e2dtool.h"
#include "..\e2dmanager.h" #include "..\e2dmanager.h"
#pragma comment(lib, "dinput8.lib") #pragma comment(lib, "dinput8.lib")
using namespace e2d;
#define BUFFER_SIZE 256 #define BUFFER_SIZE 256
static IDirectInput8* s_pDirectInput = nullptr; // DirectInput 接口对象
static IDirectInputDevice8* s_KeyboardDevice = nullptr; // 键盘设备接口
static char s_KeyBuffer[BUFFER_SIZE] = { 0 }; // 用于保存键盘按键信息缓冲区 static char s_KeyBuffer[BUFFER_SIZE] = { 0 }; // 用于保存键盘按键信息缓冲区
static char s_KeyRecordBuffer[BUFFER_SIZE] = { 0 }; // 键盘消息二级缓冲区 static char s_KeyRecordBuffer[BUFFER_SIZE] = { 0 }; // 键盘消息二级缓冲区
static IDirectInputDevice8* s_MouseDevice = nullptr; // 鼠标设备接口
static DIMOUSESTATE s_MouseState; // 鼠标信息存储结构体
static DIMOUSESTATE s_MouseRecordState; // 鼠标信息二级缓冲
static POINT s_MousePosition; // 鼠标位置存储结构体
static std::vector<e2d::Listener*> s_vListeners; // 监听器容器 static std::vector<e2d::Listener*> s_vListeners; // 监听器容器
e2d::Input * e2d::Input::_instance = nullptr;
bool Input::__init() e2d::Input::Input()
: _directInput(false)
, _keyboardDevice(false)
, _mouseDevice(false)
, _mouseState()
, _mouseStateRecord()
, _mousePos()
{ {
CoInitialize(nullptr);
ZeroMemory(s_KeyBuffer, sizeof(s_KeyBuffer)); ZeroMemory(s_KeyBuffer, sizeof(s_KeyBuffer));
ZeroMemory(s_KeyRecordBuffer, sizeof(s_KeyRecordBuffer)); ZeroMemory(s_KeyRecordBuffer, sizeof(s_KeyRecordBuffer));
ZeroMemory(&s_MouseState, sizeof(s_MouseState)); ZeroMemory(&_mouseState, sizeof(_mouseState));
ZeroMemory(&s_MouseRecordState, sizeof(s_MouseRecordState)); ZeroMemory(&_mouseStateRecord, sizeof(_mouseStateRecord));
// 初始化接口对象 // 初始化接口对象
HRESULT hr = DirectInput8Create( HRESULT hr = DirectInput8Create(
HINST_THISCOMPONENT, HINST_THISCOMPONENT,
DIRECTINPUT_VERSION, DIRECTINPUT_VERSION,
IID_IDirectInput8, IID_IDirectInput8,
(void**)&s_pDirectInput, (void**)&_directInput,
nullptr nullptr
); );
@ -42,62 +40,76 @@ bool Input::__init()
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
// 初始化键盘设备 // 初始化键盘设备
hr = s_pDirectInput->CreateDevice( hr = _directInput->CreateDevice(
GUID_SysKeyboard, GUID_SysKeyboard,
&s_KeyboardDevice, &_keyboardDevice,
nullptr nullptr
); );
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
s_KeyboardDevice->SetCooperativeLevel( _keyboardDevice->SetCooperativeLevel(
window->getHWnd(), window->getHWnd(),
DISCL_FOREGROUND | DISCL_NONEXCLUSIVE DISCL_FOREGROUND | DISCL_NONEXCLUSIVE
); );
s_KeyboardDevice->SetDataFormat( _keyboardDevice->SetDataFormat(
&c_dfDIKeyboard); &c_dfDIKeyboard);
s_KeyboardDevice->Acquire(); _keyboardDevice->Acquire();
s_KeyboardDevice->Poll(); _keyboardDevice->Poll();
} }
else else
{ {
window->error(L"Keyboard not found!"); throw SystemException(L"Keyboard not found!");
return false;
} }
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
// 初始化鼠标设备 // 初始化鼠标设备
hr = s_pDirectInput->CreateDevice(GUID_SysMouse, &s_MouseDevice, nullptr); hr = _directInput->CreateDevice(GUID_SysMouse, &_mouseDevice, nullptr);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
s_MouseDevice->SetCooperativeLevel(window->getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); _mouseDevice->SetCooperativeLevel(window->getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
s_MouseDevice->SetDataFormat(&c_dfDIMouse); _mouseDevice->SetDataFormat(&c_dfDIMouse);
s_MouseDevice->Acquire(); _mouseDevice->Acquire();
s_MouseDevice->Poll(); _mouseDevice->Poll();
} }
else else
{ {
window->error(L"Mouse not found!"); throw SystemException(L"Mouse not found!");
return false;
} }
} }
return SUCCEEDED(hr);
} }
void Input::__uninit() e2d::Input::~Input()
{ {
if (s_KeyboardDevice) if (_keyboardDevice)
s_KeyboardDevice->Unacquire(); _keyboardDevice->Unacquire();
if (s_MouseDevice) if (_mouseDevice)
s_MouseDevice->Unacquire(); _mouseDevice->Unacquire();
SafeRelease(s_MouseDevice); SafeRelease(_mouseDevice);
SafeRelease(s_KeyboardDevice); SafeRelease(_keyboardDevice);
SafeRelease(s_pDirectInput); SafeRelease(_directInput);
CoUninitialize();
}
e2d::Input * e2d::Input::getInstance()
{
if (!_instance)
_instance = new (std::nothrow) Input;
return _instance;
}
void e2d::Input::destroyInstance()
{
if (_instance)
{
delete _instance;
_instance = nullptr;
}
} }
void e2d::Input::__update() void e2d::Input::__update()
@ -106,54 +118,54 @@ void e2d::Input::__update()
Input::__updateListeners(); Input::__updateListeners();
} }
void Input::__updateDeviceState() void e2d::Input::__updateDeviceState()
{ {
if (s_KeyboardDevice) if (_keyboardDevice)
{ {
HRESULT hr = s_KeyboardDevice->Poll(); HRESULT hr = _keyboardDevice->Poll();
if (FAILED(hr)) if (FAILED(hr))
{ {
hr = s_KeyboardDevice->Acquire(); hr = _keyboardDevice->Acquire();
while (hr == DIERR_INPUTLOST) while (hr == DIERR_INPUTLOST)
hr = s_KeyboardDevice->Acquire(); hr = _keyboardDevice->Acquire();
} }
else else
{ {
for (int i = 0; i < BUFFER_SIZE; ++i) for (int i = 0; i < BUFFER_SIZE; ++i)
s_KeyRecordBuffer[i] = s_KeyBuffer[i]; s_KeyRecordBuffer[i] = s_KeyBuffer[i];
s_KeyboardDevice->GetDeviceState(sizeof(s_KeyBuffer), (void**)&s_KeyBuffer); _keyboardDevice->GetDeviceState(sizeof(s_KeyBuffer), (void**)&s_KeyBuffer);
} }
} }
if (s_MouseDevice) if (_mouseDevice)
{ {
HRESULT hr = s_MouseDevice->Poll(); HRESULT hr = _mouseDevice->Poll();
if (FAILED(hr)) if (FAILED(hr))
{ {
hr = s_MouseDevice->Acquire(); hr = _mouseDevice->Acquire();
while (hr == DIERR_INPUTLOST) while (hr == DIERR_INPUTLOST)
hr = s_MouseDevice->Acquire(); hr = _mouseDevice->Acquire();
} }
else else
{ {
s_MouseRecordState = s_MouseState; _mouseStateRecord = _mouseState;
s_MouseDevice->GetDeviceState(sizeof(s_MouseState), (void**)&s_MouseState); _mouseDevice->GetDeviceState(sizeof(_mouseState), (void**)&_mouseState);
} }
} }
GetCursorPos(&s_MousePosition); GetCursorPos(&_mousePos);
ScreenToClient(Window::getInstance()->getHWnd(), &s_MousePosition); ScreenToClient(Window::getInstance()->getHWnd(), &_mousePos);
} }
bool Input::isDown(Key key) bool e2d::Input::isDown(Key key)
{ {
if (s_KeyBuffer[static_cast<int>(key)] & 0x80) if (s_KeyBuffer[static_cast<int>(key)] & 0x80)
return true; return true;
return false; return false;
} }
bool Input::isPress(Key key) bool e2d::Input::isPress(Key key)
{ {
if ((s_KeyBuffer[static_cast<int>(key)] & 0x80) && if ((s_KeyBuffer[static_cast<int>(key)] & 0x80) &&
!(s_KeyRecordBuffer[static_cast<int>(key)] & 0x80)) !(s_KeyRecordBuffer[static_cast<int>(key)] & 0x80))
@ -161,7 +173,7 @@ bool Input::isPress(Key key)
return false; return false;
} }
bool Input::isRelease(Key key) bool e2d::Input::isRelease(Key key)
{ {
if (!(s_KeyBuffer[static_cast<int>(key)] & 0x80) && if (!(s_KeyBuffer[static_cast<int>(key)] & 0x80) &&
(s_KeyRecordBuffer[static_cast<int>(key)] & 0x80)) (s_KeyRecordBuffer[static_cast<int>(key)] & 0x80))
@ -171,55 +183,55 @@ bool Input::isRelease(Key key)
bool e2d::Input::isDown(Mouse code) bool e2d::Input::isDown(Mouse code)
{ {
if (s_MouseState.rgbButtons[static_cast<int>(code)] & 0x80) if (_mouseState.rgbButtons[static_cast<int>(code)] & 0x80)
return true; return true;
return false; return false;
} }
bool e2d::Input::isPress(Mouse code) bool e2d::Input::isPress(Mouse code)
{ {
if ((s_MouseState.rgbButtons[static_cast<int>(code)] & 0x80) && if ((_mouseState.rgbButtons[static_cast<int>(code)] & 0x80) &&
!(s_MouseRecordState.rgbButtons[static_cast<int>(code)] & 0x80)) !(_mouseStateRecord.rgbButtons[static_cast<int>(code)] & 0x80))
return true; return true;
return false; return false;
} }
bool e2d::Input::isRelease(Mouse code) bool e2d::Input::isRelease(Mouse code)
{ {
if (!(s_MouseState.rgbButtons[static_cast<int>(code)] & 0x80) && if (!(_mouseState.rgbButtons[static_cast<int>(code)] & 0x80) &&
(s_MouseRecordState.rgbButtons[static_cast<int>(code)] & 0x80)) (_mouseStateRecord.rgbButtons[static_cast<int>(code)] & 0x80))
return true; return true;
return false; return false;
} }
double Input::getMouseX() double e2d::Input::getMouseX()
{ {
return (double)s_MousePosition.x; return (double)_mousePos.x;
} }
double Input::getMouseY() double e2d::Input::getMouseY()
{ {
return (double)s_MousePosition.y; return (double)_mousePos.y;
} }
Point Input::getMousePos() e2d::Point e2d::Input::getMousePos()
{ {
return Point((double)s_MousePosition.x, (double)s_MousePosition.y); return Point((double)_mousePos.x, (double)_mousePos.y);
} }
double Input::getMouseDeltaX() double e2d::Input::getMouseDeltaX()
{ {
return (double)s_MouseState.lX; return (double)_mouseState.lX;
} }
double Input::getMouseDeltaY() double e2d::Input::getMouseDeltaY()
{ {
return (double)s_MouseState.lY; return (double)_mouseState.lY;
} }
double Input::getMouseDeltaZ() double e2d::Input::getMouseDeltaZ()
{ {
return (double)s_MouseState.lZ; return (double)_mouseState.lZ;
} }
e2d::Listener * e2d::Input::addListener(const Function& func, const String& name, bool paused) e2d::Listener * e2d::Input::addListener(const Function& func, const String& name, bool paused)

View File

@ -45,6 +45,8 @@ e2d::Renderer::Renderer()
, _textRenderer(nullptr) , _textRenderer(nullptr)
, _clearColor(D2D1::ColorF(D2D1::ColorF::Black)) , _clearColor(D2D1::ColorF(D2D1::ColorF::Black))
{ {
CoInitialize(nullptr);
this->__createDeviceResources(); this->__createDeviceResources();
} }
@ -53,6 +55,8 @@ e2d::Renderer::~Renderer()
SafeRelease(_renderTarget); SafeRelease(_renderTarget);
SafeRelease(_solidBrush); SafeRelease(_solidBrush);
SafeRelease(_textRenderer); SafeRelease(_textRenderer);
CoUninitialize();
} }
bool e2d::Renderer::__createDeviceResources() bool e2d::Renderer::__createDeviceResources()

View File

@ -180,13 +180,16 @@ void e2d::Button::_fixedUpdate()
if (SceneManager::isTransitioning()) if (SceneManager::isTransitioning())
return; return;
auto input = Input::getInstance();
auto window = Window::getInstance();
if (_enable && _visiable && _normal) if (_enable && _visiable && _normal)
{ {
if (Input::isRelease(Input::Mouse::Left)) if (input->isRelease(Input::Mouse::Left))
{ {
// 鼠标左键抬起时,判断鼠标坐标是否在按钮内部 // 鼠标左键抬起时,判断鼠标坐标是否在按钮内部
if (_isSelected && if (_isSelected &&
_normal->containsPoint(Input::getMousePos())) _normal->containsPoint(input->getMousePos()))
{ {
_runCallback(); _runCallback();
} }
@ -194,9 +197,9 @@ void e2d::Button::_fixedUpdate()
_isSelected = false; _isSelected = false;
} }
if (Input::isPress(Input::Mouse::Left)) if (input->isPress(Input::Mouse::Left))
{ {
if (_normal->containsPoint(Input::getMousePos())) if (_normal->containsPoint(input->getMousePos()))
{ {
// 鼠标左键按下,且位于按钮内时,标记 _isSelected 为 true // 鼠标左键按下,且位于按钮内时,标记 _isSelected 为 true
_isSelected = true; _isSelected = true;
@ -204,28 +207,28 @@ void e2d::Button::_fixedUpdate()
} }
} }
if (_isSelected && Input::isDown(Input::Mouse::Left)) if (_isSelected && input->isDown(Input::Mouse::Left))
{ {
if (_normal->containsPoint(Input::getMousePos())) if (_normal->containsPoint(input->getMousePos()))
{ {
_setState(ButtonState::Selected); _setState(ButtonState::Selected);
Window::getInstance()->setCursor(Window::Cursor::Hand); window->setCursor(Window::Cursor::Hand);
return; return;
} }
} }
else if (_normal->containsPoint(Input::getMousePos())) else if (_normal->containsPoint(input->getMousePos()))
{ {
_setState(ButtonState::Mouseover); _setState(ButtonState::Mouseover);
Window::getInstance()->setCursor(Window::Cursor::Hand); window->setCursor(Window::Cursor::Hand);
return; return;
} }
_setState(ButtonState::Normal); _setState(ButtonState::Normal);
} }
if (_visiable && !_enable && _normal && _normal->containsPoint(Input::getMousePos())) if (_visiable && !_enable && _normal && _normal->containsPoint(input->getMousePos()))
{ {
Window::getInstance()->setCursor(Window::Cursor::No); window->setCursor(Window::Cursor::No);
} }
} }

View File

@ -8,6 +8,7 @@ e2d::Player::Player()
, _xAudio2(nullptr) , _xAudio2(nullptr)
, _masteringVoice(nullptr) , _masteringVoice(nullptr)
{ {
CoInitialize(nullptr);
} }
e2d::Player::~Player() e2d::Player::~Player()
@ -24,6 +25,8 @@ e2d::Player::~Player()
_masteringVoice->DestroyVoice(); _masteringVoice->DestroyVoice();
SafeRelease(_xAudio2); SafeRelease(_xAudio2);
CoUninitialize();
} }
e2d::Player * e2d::Player::getInstance() e2d::Player * e2d::Player::getInstance()

View File

@ -20,12 +20,9 @@ public:
// 销毁实例 // 销毁实例
static void destroyInstance(); static void destroyInstance();
// 初始化游戏
bool init();
// 启动游戏 // 启动游戏
void start( void start(
bool cleanup = true /* 自动清理资源 */ bool cleanup = true /* 自动清理资源 */
); );
// 暂停游戏 // 暂停游戏
@ -226,7 +223,7 @@ private:
class Listener; class Listener;
// 输入控制 // 输入设备
class Input class Input
{ {
friend class Game; friend class Game;
@ -300,53 +297,59 @@ public:
}; };
public: public:
// 获取输入设备实例
static Input * getInstance();
// 销毁输入设备实例
static void destroyInstance();
// 检测键盘某按键是否正被按下 // 检测键盘某按键是否正被按下
static bool isDown( bool isDown(
Key key Key key
); );
// 检测键盘某按键是否被点击 // 检测键盘某按键是否被点击
static bool isPress( bool isPress(
Key key Key key
); );
// 检测键盘某按键是否正在松开 // 检测键盘某按键是否正在松开
static bool isRelease( bool isRelease(
Key key Key key
); );
// 检测鼠标按键是否正被按下 // 检测鼠标按键是否正被按下
static bool isDown( bool isDown(
Mouse code Mouse code
); );
// 检测鼠标按键是否被点击 // 检测鼠标按键是否被点击
static bool isPress( bool isPress(
Mouse code Mouse code
); );
// 检测鼠标按键是否正在松开 // 检测鼠标按键是否正在松开
static bool isRelease( bool isRelease(
Mouse code Mouse code
); );
// 获得鼠标X轴坐标值 // 获得鼠标X轴坐标值
static double getMouseX(); double getMouseX();
// 获得鼠标Y轴坐标值 // 获得鼠标Y轴坐标值
static double getMouseY(); double getMouseY();
// 获得鼠标坐标值 // 获得鼠标坐标值
static Point getMousePos(); Point getMousePos();
// 获得鼠标X轴坐标增量 // 获得鼠标X轴坐标增量
static double getMouseDeltaX(); double getMouseDeltaX();
// 获得鼠标Y轴坐标增量 // 获得鼠标Y轴坐标增量
static double getMouseDeltaY(); double getMouseDeltaY();
// 获得鼠标Z轴鼠标滚轮坐标增量 // 获得鼠标Z轴鼠标滚轮坐标增量
static double getMouseDeltaZ(); double getMouseDeltaZ();
// 添加输入监听 // 添加输入监听
static Listener * addListener( static Listener * addListener(
@ -390,23 +393,33 @@ public:
static void removeAllListeners(); static void removeAllListeners();
private: private:
// 初始化 DirectInput 以及键盘鼠标设备 Input();
static bool __init();
~Input();
E2D_DISABLE_COPY(Input);
// 刷新输入信息 // 刷新输入信息
static void __update(); void __update();
// 刷新设备状态 // 刷新设备状态
static void __updateDeviceState(); void __updateDeviceState();
// 更新监听器 // 更新监听器
static void __updateListeners(); static void __updateListeners();
// 卸载 DirectInput
static void __uninit();
// 清空监听器 // 清空监听器
static void __clearListeners(); static void __clearListeners();
private:
IDirectInput8* _directInput;
IDirectInputDevice8* _keyboardDevice;
IDirectInputDevice8* _mouseDevice;
DIMOUSESTATE _mouseState;
DIMOUSESTATE _mouseStateRecord;
POINT _mousePos;
static Input * _instance;
}; };