diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 70fed241..4381a867 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -11,10 +11,12 @@ e2d::Game::Game() , _paused(false) , _initialized(false) { + CoInitialize(nullptr); } e2d::Game::~Game() { + CoUninitialize(); } 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) { if (!_initialized) @@ -75,8 +42,11 @@ void e2d::Game::start(bool cleanup) throw Exception(L"开始游戏前未进行初始化"); } + auto gc = GC::getInstance(); + auto input = Input::getInstance(); auto window = Window::getInstance(); auto renderer = Renderer::getInstance(); + // 初始化场景管理器 SceneManager::__init(); @@ -101,7 +71,7 @@ void e2d::Game::start(bool cleanup) // 判断是否达到了刷新状态 if (Time::__isReady()) { - Input::__update(); // 获取用户输入 + input->__update(); // 获取用户输入 Timer::__update(); // 更新定时器 ActionManager::__update(); // 更新动作管理器 SceneManager::__update(); // 更新场景内容 @@ -111,8 +81,8 @@ void e2d::Game::start(bool cleanup) } else { - Time::__sleep(); // 挂起线程 - GC::getInstance()->__update(); // 刷新内存池 + Time::__sleep(); // 挂起线程 + gc->__update(); // 刷新内存池 } } @@ -160,9 +130,6 @@ void e2d::Game::quit() void e2d::Game::cleanup() { - if (!_initialized) - return; - // 删除所有场景 SceneManager::__uninit(); // 删除输入监听器 @@ -175,12 +142,6 @@ void e2d::Game::cleanup() Image::clearCache(); // 清空定时器 Timer::__uninit(); - // 关闭输入 - Input::__uninit(); // 删除所有对象 GC::getInstance()->clear(); - - CoUninitialize(); - - _initialized = false; } diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index 829ea9da..b101d6c2 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -1,39 +1,37 @@ #include "..\e2dbase.h" #include "..\e2dtool.h" #include "..\e2dmanager.h" - #pragma comment(lib, "dinput8.lib") -using namespace e2d; - #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_KeyRecordBuffer[BUFFER_SIZE] = { 0 }; // 键盘消息二级缓冲区 - -static IDirectInputDevice8* s_MouseDevice = nullptr; // 鼠标设备接口 -static DIMOUSESTATE s_MouseState; // 鼠标信息存储结构体 -static DIMOUSESTATE s_MouseRecordState; // 鼠标信息二级缓冲 -static POINT s_MousePosition; // 鼠标位置存储结构体 - static std::vector 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_KeyRecordBuffer, sizeof(s_KeyRecordBuffer)); - ZeroMemory(&s_MouseState, sizeof(s_MouseState)); - ZeroMemory(&s_MouseRecordState, sizeof(s_MouseRecordState)); + ZeroMemory(&_mouseState, sizeof(_mouseState)); + ZeroMemory(&_mouseStateRecord, sizeof(_mouseStateRecord)); // 初始化接口对象 HRESULT hr = DirectInput8Create( HINST_THISCOMPONENT, DIRECTINPUT_VERSION, IID_IDirectInput8, - (void**)&s_pDirectInput, + (void**)&_directInput, nullptr ); @@ -42,62 +40,76 @@ bool Input::__init() if (SUCCEEDED(hr)) { // 初始化键盘设备 - hr = s_pDirectInput->CreateDevice( + hr = _directInput->CreateDevice( GUID_SysKeyboard, - &s_KeyboardDevice, + &_keyboardDevice, nullptr ); if (SUCCEEDED(hr)) { - s_KeyboardDevice->SetCooperativeLevel( + _keyboardDevice->SetCooperativeLevel( window->getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE ); - s_KeyboardDevice->SetDataFormat( + _keyboardDevice->SetDataFormat( &c_dfDIKeyboard); - s_KeyboardDevice->Acquire(); - s_KeyboardDevice->Poll(); + _keyboardDevice->Acquire(); + _keyboardDevice->Poll(); } else { - window->error(L"Keyboard not found!"); - return false; + throw SystemException(L"Keyboard not found!"); } } if (SUCCEEDED(hr)) { // 初始化鼠标设备 - hr = s_pDirectInput->CreateDevice(GUID_SysMouse, &s_MouseDevice, nullptr); + hr = _directInput->CreateDevice(GUID_SysMouse, &_mouseDevice, nullptr); if (SUCCEEDED(hr)) { - s_MouseDevice->SetCooperativeLevel(window->getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); - s_MouseDevice->SetDataFormat(&c_dfDIMouse); - s_MouseDevice->Acquire(); - s_MouseDevice->Poll(); + _mouseDevice->SetCooperativeLevel(window->getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); + _mouseDevice->SetDataFormat(&c_dfDIMouse); + _mouseDevice->Acquire(); + _mouseDevice->Poll(); } else { - window->error(L"Mouse not found!"); - return false; + throw SystemException(L"Mouse not found!"); } } - - return SUCCEEDED(hr); } -void Input::__uninit() +e2d::Input::~Input() { - if (s_KeyboardDevice) - s_KeyboardDevice->Unacquire(); - if (s_MouseDevice) - s_MouseDevice->Unacquire(); + if (_keyboardDevice) + _keyboardDevice->Unacquire(); + if (_mouseDevice) + _mouseDevice->Unacquire(); - SafeRelease(s_MouseDevice); - SafeRelease(s_KeyboardDevice); - SafeRelease(s_pDirectInput); + SafeRelease(_mouseDevice); + SafeRelease(_keyboardDevice); + 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() @@ -106,54 +118,54 @@ void e2d::Input::__update() 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)) { - hr = s_KeyboardDevice->Acquire(); + hr = _keyboardDevice->Acquire(); while (hr == DIERR_INPUTLOST) - hr = s_KeyboardDevice->Acquire(); + hr = _keyboardDevice->Acquire(); } else { for (int i = 0; i < BUFFER_SIZE; ++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)) { - hr = s_MouseDevice->Acquire(); + hr = _mouseDevice->Acquire(); while (hr == DIERR_INPUTLOST) - hr = s_MouseDevice->Acquire(); + hr = _mouseDevice->Acquire(); } else { - s_MouseRecordState = s_MouseState; - s_MouseDevice->GetDeviceState(sizeof(s_MouseState), (void**)&s_MouseState); + _mouseStateRecord = _mouseState; + _mouseDevice->GetDeviceState(sizeof(_mouseState), (void**)&_mouseState); } } - GetCursorPos(&s_MousePosition); - ScreenToClient(Window::getInstance()->getHWnd(), &s_MousePosition); + GetCursorPos(&_mousePos); + ScreenToClient(Window::getInstance()->getHWnd(), &_mousePos); } -bool Input::isDown(Key key) +bool e2d::Input::isDown(Key key) { if (s_KeyBuffer[static_cast(key)] & 0x80) return true; return false; } -bool Input::isPress(Key key) +bool e2d::Input::isPress(Key key) { if ((s_KeyBuffer[static_cast(key)] & 0x80) && !(s_KeyRecordBuffer[static_cast(key)] & 0x80)) @@ -161,7 +173,7 @@ bool Input::isPress(Key key) return false; } -bool Input::isRelease(Key key) +bool e2d::Input::isRelease(Key key) { if (!(s_KeyBuffer[static_cast(key)] & 0x80) && (s_KeyRecordBuffer[static_cast(key)] & 0x80)) @@ -171,55 +183,55 @@ bool Input::isRelease(Key key) bool e2d::Input::isDown(Mouse code) { - if (s_MouseState.rgbButtons[static_cast(code)] & 0x80) + if (_mouseState.rgbButtons[static_cast(code)] & 0x80) return true; return false; } bool e2d::Input::isPress(Mouse code) { - if ((s_MouseState.rgbButtons[static_cast(code)] & 0x80) && - !(s_MouseRecordState.rgbButtons[static_cast(code)] & 0x80)) + if ((_mouseState.rgbButtons[static_cast(code)] & 0x80) && + !(_mouseStateRecord.rgbButtons[static_cast(code)] & 0x80)) return true; return false; } bool e2d::Input::isRelease(Mouse code) { - if (!(s_MouseState.rgbButtons[static_cast(code)] & 0x80) && - (s_MouseRecordState.rgbButtons[static_cast(code)] & 0x80)) + if (!(_mouseState.rgbButtons[static_cast(code)] & 0x80) && + (_mouseStateRecord.rgbButtons[static_cast(code)] & 0x80)) return true; 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) diff --git a/core/Base/Renderer.cpp b/core/Base/Renderer.cpp index 6021bde9..1e6d5710 100644 --- a/core/Base/Renderer.cpp +++ b/core/Base/Renderer.cpp @@ -45,6 +45,8 @@ e2d::Renderer::Renderer() , _textRenderer(nullptr) , _clearColor(D2D1::ColorF(D2D1::ColorF::Black)) { + CoInitialize(nullptr); + this->__createDeviceResources(); } @@ -53,6 +55,8 @@ e2d::Renderer::~Renderer() SafeRelease(_renderTarget); SafeRelease(_solidBrush); SafeRelease(_textRenderer); + + CoUninitialize(); } bool e2d::Renderer::__createDeviceResources() diff --git a/core/Node/Button.cpp b/core/Node/Button.cpp index 8588b5b8..b273545d 100644 --- a/core/Node/Button.cpp +++ b/core/Node/Button.cpp @@ -180,13 +180,16 @@ void e2d::Button::_fixedUpdate() if (SceneManager::isTransitioning()) return; + auto input = Input::getInstance(); + auto window = Window::getInstance(); + if (_enable && _visiable && _normal) { - if (Input::isRelease(Input::Mouse::Left)) + if (input->isRelease(Input::Mouse::Left)) { // 鼠标左键抬起时,判断鼠标坐标是否在按钮内部 if (_isSelected && - _normal->containsPoint(Input::getMousePos())) + _normal->containsPoint(input->getMousePos())) { _runCallback(); } @@ -194,9 +197,9 @@ void e2d::Button::_fixedUpdate() _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; @@ -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); - Window::getInstance()->setCursor(Window::Cursor::Hand); + window->setCursor(Window::Cursor::Hand); return; } } - else if (_normal->containsPoint(Input::getMousePos())) + else if (_normal->containsPoint(input->getMousePos())) { _setState(ButtonState::Mouseover); - Window::getInstance()->setCursor(Window::Cursor::Hand); + window->setCursor(Window::Cursor::Hand); return; } _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); } } diff --git a/core/Tool/Player.cpp b/core/Tool/Player.cpp index 771cb6b2..96c3581b 100644 --- a/core/Tool/Player.cpp +++ b/core/Tool/Player.cpp @@ -8,6 +8,7 @@ e2d::Player::Player() , _xAudio2(nullptr) , _masteringVoice(nullptr) { + CoInitialize(nullptr); } e2d::Player::~Player() @@ -24,6 +25,8 @@ e2d::Player::~Player() _masteringVoice->DestroyVoice(); SafeRelease(_xAudio2); + + CoUninitialize(); } e2d::Player * e2d::Player::getInstance() diff --git a/core/e2dbase.h b/core/e2dbase.h index c4843878..b080dccc 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -20,12 +20,9 @@ public: // 销毁实例 static void destroyInstance(); - // 初始化游戏 - bool init(); - // 启动游戏 void start( - bool cleanup = true /* 自动清理资源 */ + bool cleanup = true /* 自动清理资源 */ ); // 暂停游戏 @@ -226,7 +223,7 @@ private: class Listener; -// 输入控制 +// 输入设备 class Input { friend class Game; @@ -300,53 +297,59 @@ public: }; public: + // 获取输入设备实例 + static Input * getInstance(); + + // 销毁输入设备实例 + static void destroyInstance(); + // 检测键盘某按键是否正被按下 - static bool isDown( + bool isDown( Key key ); // 检测键盘某按键是否被点击 - static bool isPress( + bool isPress( Key key ); // 检测键盘某按键是否正在松开 - static bool isRelease( + bool isRelease( Key key ); // 检测鼠标按键是否正被按下 - static bool isDown( + bool isDown( Mouse code ); // 检测鼠标按键是否被点击 - static bool isPress( + bool isPress( Mouse code ); // 检测鼠标按键是否正在松开 - static bool isRelease( + bool isRelease( Mouse code ); // 获得鼠标X轴坐标值 - static double getMouseX(); + double getMouseX(); // 获得鼠标Y轴坐标值 - static double getMouseY(); + double getMouseY(); // 获得鼠标坐标值 - static Point getMousePos(); + Point getMousePos(); // 获得鼠标X轴坐标增量 - static double getMouseDeltaX(); + double getMouseDeltaX(); // 获得鼠标Y轴坐标增量 - static double getMouseDeltaY(); + double getMouseDeltaY(); // 获得鼠标Z轴(鼠标滚轮)坐标增量 - static double getMouseDeltaZ(); + double getMouseDeltaZ(); // 添加输入监听 static Listener * addListener( @@ -390,23 +393,33 @@ public: static void removeAllListeners(); private: - // 初始化 DirectInput 以及键盘鼠标设备 - static bool __init(); + Input(); + + ~Input(); + + E2D_DISABLE_COPY(Input); // 刷新输入信息 - static void __update(); + void __update(); // 刷新设备状态 - static void __updateDeviceState(); + void __updateDeviceState(); // 更新监听器 static void __updateListeners(); - // 卸载 DirectInput - static void __uninit(); - // 清空监听器 static void __clearListeners(); + +private: + IDirectInput8* _directInput; + IDirectInputDevice8* _keyboardDevice; + IDirectInputDevice8* _mouseDevice; + DIMOUSESTATE _mouseState; + DIMOUSESTATE _mouseStateRecord; + POINT _mousePos; + + static Input * _instance; };