diff --git a/Extra2D/include/extra2d/app/application.h b/Extra2D/include/extra2d/app/application.h index bb81cad..3011a93 100644 --- a/Extra2D/include/extra2d/app/application.h +++ b/Extra2D/include/extra2d/app/application.h @@ -9,11 +9,9 @@ namespace extra2d { class IWindow; -class IInput; class RenderBackend; class WindowModule; class RenderModule; -class InputModule; /** * @brief 应用程序类 @@ -95,12 +93,6 @@ public: */ RenderBackend *renderer(); - /** - * @brief 获取输入 - * @return 输入指针 - */ - IInput *input(); - /** * @brief 进入场景 * @param scene 场景指针 diff --git a/Extra2D/include/extra2d/extra2d.h b/Extra2D/include/extra2d/extra2d.h index 047fba1..398b7e6 100644 --- a/Extra2D/include/extra2d/extra2d.h +++ b/Extra2D/include/extra2d/extra2d.h @@ -10,17 +10,13 @@ #include #include - // Config removed - app info now in Application class // Platform -#include -#include #include #include #include - // Graphics #include #include @@ -33,7 +29,6 @@ #include #include - // Scene #include #include @@ -57,7 +52,6 @@ #include #include - // Application #include diff --git a/Extra2D/include/extra2d/platform/glfw/glfw_input.h b/Extra2D/include/extra2d/platform/glfw/glfw_input.h deleted file mode 100644 index 287d90e..0000000 --- a/Extra2D/include/extra2d/platform/glfw/glfw_input.h +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace extra2d { - -/** - * @brief GLFW 输入实现 - */ -class GLFWInput : public IInput { -public: - GLFWInput(); - ~GLFWInput() override; - - void init() override; - void shutdown() override; - void update() override; - - // Keyboard - bool down(Key key) const override; - bool pressed(Key key) const override; - bool released(Key key) const override; - - // Mouse - bool down(Mouse btn) const override; - bool pressed(Mouse btn) const override; - bool released(Mouse btn) const override; - Vec2 mouse() const override; - Vec2 mouseDelta() const override; - float scroll() const override; - float scrollDelta() const override; - void setMouse(const Vec2& pos) override; - - // Gamepad - bool gamepad() const override; - bool down(Gamepad btn) const override; - bool pressed(Gamepad btn) const override; - bool released(Gamepad btn) const override; - Vec2 leftStick() const override; - Vec2 rightStick() const override; - float leftTrigger() const override; - float rightTrigger() const override; - void vibrate(float left, float right) override; - - // Touch - bool touching() const override; - int touchCount() const override; - Vec2 touch(int index) const override; - TouchPoint touchPoint(int index) const override; - - // GLFW specific - void handleKeyEvent(int key, int scancode, int action, int mods); - void handleMouseButtonEvent(int button, int action, int mods); - void handleCursorPosEvent(double xpos, double ypos); - void handleScrollEvent(double xoffset, double yoffset); - void handleJoystickEvent(int jid, int event); - - void setWindow(GLFWwindow* window) { window_ = window; } - -private: - void updateGamepad(); - void openGamepad(); - void closeGamepad(); - - float applyDeadzone(float value) const; - - // Keyboard state - std::array(Key::Count)> keyCurrent_; - std::array(Key::Count)> keyPrevious_; - - // Mouse state - std::array(Mouse::Count)> mouseCurrent_; - std::array(Mouse::Count)> mousePrevious_; - Vec2 mousePos_; - Vec2 mouseDelta_; - float scroll_ = 0.0f; - float scrollDelta_ = 0.0f; - - // Gamepad state - std::array(Gamepad::Count)> gamepadCurrent_; - std::array(Gamepad::Count)> gamepadPrevious_; - Vec2 leftStick_; - Vec2 rightStick_; - float leftTrigger_ = 0.0f; - float rightTrigger_ = 0.0f; - int gamepadId_ = -1; - - float deadzone_ = 0.15f; - - GLFWwindow* window_ = nullptr; -}; - -} // namespace extra2d diff --git a/Extra2D/include/extra2d/platform/glfw/glfw_window.h b/Extra2D/include/extra2d/platform/glfw/glfw_window.h index 66da235..7cb9ef4 100644 --- a/Extra2D/include/extra2d/platform/glfw/glfw_window.h +++ b/Extra2D/include/extra2d/platform/glfw/glfw_window.h @@ -5,8 +5,6 @@ namespace extra2d { -class GLFWInput; - /** * @brief GLFW 窗口实现 */ @@ -46,8 +44,6 @@ public: void showCursor(bool show) override; void lockCursor(bool lock) override; - IInput* input() const override; - void onResize(ResizeCb cb) override; void onClose(CloseCb cb) override; void onFocus(FocusCb cb) override; @@ -76,8 +72,6 @@ private: static void joystickCallback(int jid, int event); GLFWwindow* glfwWindow_ = nullptr; - - UniquePtr input_; int width_ = 1280; int height_ = 720; diff --git a/Extra2D/include/extra2d/platform/iinput.h b/Extra2D/include/extra2d/platform/iinput.h deleted file mode 100644 index 08d852e..0000000 --- a/Extra2D/include/extra2d/platform/iinput.h +++ /dev/null @@ -1,175 +0,0 @@ -#pragma once - -#include -#include - -namespace extra2d { - -/** - * @brief 触摸点信息 - */ -struct TouchPoint { - int id = 0; - Vec2 position; - Vec2 delta; - bool pressed = false; - bool released = false; -}; - -/** - * @brief 输入抽象接口 - * 所有平台输入后端必须实现此接口 - */ -class IInput { -public: - virtual ~IInput() = default; - - /** - * @brief 初始化输入系统 - */ - virtual void init() = 0; - - /** - * @brief 关闭输入系统 - */ - virtual void shutdown() = 0; - - /** - * @brief 每帧更新输入状态 - */ - virtual void update() = 0; - - // ========== 键盘 ========== - - /** - * @brief 检测按键是否按下(持续状态) - */ - virtual bool down(Key key) const = 0; - - /** - * @brief 检测按键是否刚按下(仅当前帧) - */ - virtual bool pressed(Key key) const = 0; - - /** - * @brief 检测按键是否刚释放(仅当前帧) - */ - virtual bool released(Key key) const = 0; - - // ========== 鼠标 ========== - - /** - * @brief 检测鼠标按钮是否按下 - */ - virtual bool down(Mouse btn) const = 0; - - /** - * @brief 检测鼠标按钮是否刚按下 - */ - virtual bool pressed(Mouse btn) const = 0; - - /** - * @brief 检测鼠标按钮是否刚释放 - */ - virtual bool released(Mouse btn) const = 0; - - /** - * @brief 获取鼠标位置 - */ - virtual Vec2 mouse() const = 0; - - /** - * @brief 获取鼠标移动增量 - */ - virtual Vec2 mouseDelta() const = 0; - - /** - * @brief 获取滚轮值 - */ - virtual float scroll() const = 0; - - /** - * @brief 获取滚轮增量 - */ - virtual float scrollDelta() const = 0; - - /** - * @brief 设置鼠标位置 - */ - virtual void setMouse(const Vec2& pos) = 0; - - // ========== 手柄 ========== - - /** - * @brief 检测手柄是否连接 - */ - virtual bool gamepad() const = 0; - - /** - * @brief 检测手柄按钮是否按下 - */ - virtual bool down(Gamepad btn) const = 0; - - /** - * @brief 检测手柄按钮是否刚按下 - */ - virtual bool pressed(Gamepad btn) const = 0; - - /** - * @brief 检测手柄按钮是否刚释放 - */ - virtual bool released(Gamepad btn) const = 0; - - /** - * @brief 获取左摇杆值 - */ - virtual Vec2 leftStick() const = 0; - - /** - * @brief 获取右摇杆值 - */ - virtual Vec2 rightStick() const = 0; - - /** - * @brief 获取左扳机值 - */ - virtual float leftTrigger() const = 0; - - /** - * @brief 获取右扳机值 - */ - virtual float rightTrigger() const = 0; - - /** - * @brief 设置手柄振动 - * @param left 左马达强度 [0, 1] - * @param right 右马达强度 [0, 1] - */ - virtual void vibrate(float left, float right) = 0; - - // ========== 触摸 ========== - - /** - * @brief 检测是否有触摸 - */ - virtual bool touching() const = 0; - - /** - * @brief 获取触摸点数量 - */ - virtual int touchCount() const = 0; - - /** - * @brief 获取触摸点位置 - * @param index 触摸点索引 - */ - virtual Vec2 touch(int index) const = 0; - - /** - * @brief 获取触摸点信息 - * @param index 触摸点索引 - */ - virtual TouchPoint touchPoint(int index) const = 0; -}; - -} // namespace extra2d diff --git a/Extra2D/include/extra2d/platform/input_module.h b/Extra2D/include/extra2d/platform/input_module.h deleted file mode 100644 index 2cdbc4b..0000000 --- a/Extra2D/include/extra2d/platform/input_module.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace extra2d { - -/** - * @brief 输入模块配置结构 - */ -struct InputCfg { - float deadzone; - float mouseSensitivity; - bool enableVibration; - int maxGamepads; - int priority; - - InputCfg() - : deadzone(0.15f) - , mouseSensitivity(1.0f) - , enableVibration(true) - , maxGamepads(4) - , priority(20) - {} -}; - -/** - * @brief 输入模块 - * 管理输入设备 - */ -class InputModule : public Module { -public: - /** - * @brief 构造函数(Lambda 配置) - * @param configFn 配置函数 - */ - explicit InputModule(std::function configFn); - - /** - * @brief 析构函数 - */ - ~InputModule() override; - - bool init() override; - void shutdown() override; - bool ok() const override { return initialized_; } - const char* name() const override { return "input"; } - int priority() const override { return cfg_.priority; } - - /** - * @brief 获取依赖 - * @return 依赖模块类型列表 - */ - std::vector deps() const override { - return {std::type_index(typeid(WindowModule))}; - } - - /** - * @brief 获取输入接口 - * @return 输入接口指针 - */ - IInput* input() const { return input_; } - - /** - * @brief 更新输入状态 - */ - void update(); - -private: - InputCfg cfg_; - IInput* input_ = nullptr; - bool initialized_ = false; -}; - -} // namespace extra2d diff --git a/Extra2D/include/extra2d/platform/iwindow.h b/Extra2D/include/extra2d/platform/iwindow.h index 14751db..eee6822 100644 --- a/Extra2D/include/extra2d/platform/iwindow.h +++ b/Extra2D/include/extra2d/platform/iwindow.h @@ -7,8 +7,6 @@ namespace extra2d { -class IInput; - /** * @brief 光标形状 */ @@ -160,11 +158,6 @@ public: */ virtual void lockCursor(bool lock) = 0; - /** - * @brief 获取输入接口 - */ - virtual IInput* input() const = 0; - /** * @brief 窗口大小改变回调 */ diff --git a/Extra2D/include/extra2d/scene/scene_manager.h b/Extra2D/include/extra2d/scene/scene_manager.h index 66ade15..fc8341b 100644 --- a/Extra2D/include/extra2d/scene/scene_manager.h +++ b/Extra2D/include/extra2d/scene/scene_manager.h @@ -153,6 +153,7 @@ private: void doSceneSwitch(); void dispatchPointerEvents(Scene &scene); + void setupEventListeners(); std::stack> sceneStack_; std::unordered_map> namedScenes_; @@ -170,6 +171,18 @@ private: Node *captureTarget_ = nullptr; Vec2 lastPointerWorld_ = Vec2::Zero(); bool hasLastPointerWorld_ = false; + + // 鼠标状态(通过事件更新) + Vec2 mousePos_ = Vec2::Zero(); + Vec2 mouseDelta_ = Vec2::Zero(); + float scrollDelta_ = 0.0f; + bool mouseLeftPressed_ = false; + bool mouseLeftReleased_ = false; + bool mouseLeftDown_ = false; + ListenerId mouseMoveListener_ = 0; + ListenerId mousePressListener_ = 0; + ListenerId mouseReleaseListener_ = 0; + ListenerId scrollListener_ = 0; }; } // namespace extra2d diff --git a/Extra2D/src/app/application.cpp b/Extra2D/src/app/application.cpp index 7b199d8..6c1922b 100644 --- a/Extra2D/src/app/application.cpp +++ b/Extra2D/src/app/application.cpp @@ -3,8 +3,6 @@ #include #include #include -#include -#include #include #include #include @@ -183,11 +181,6 @@ void Application::mainLoop() { void Application::update() { ServiceLocator::instance().updateAll(deltaTime_); - - auto *inputMod = get(); - if (inputMod) { - inputMod->update(); - } } void Application::render() { @@ -230,11 +223,6 @@ RenderBackend *Application::renderer() { return renderMod ? renderMod->renderer() : nullptr; } -IInput *Application::input() { - auto *winMod = get(); - return (winMod && winMod->win()) ? winMod->win()->input() : nullptr; -} - void Application::enterScene(Ptr scene) { auto sceneService = ServiceLocator::instance().getService(); auto *winMod = get(); diff --git a/Extra2D/src/platform/glfw/glfw_input.cpp b/Extra2D/src/platform/glfw/glfw_input.cpp deleted file mode 100644 index e787d48..0000000 --- a/Extra2D/src/platform/glfw/glfw_input.cpp +++ /dev/null @@ -1,491 +0,0 @@ -#include -#include -#include - - -namespace extra2d { - -// GLFW 按键到引擎按键的映射 -static Key glfwToKey(int glfwKey) { - switch (glfwKey) { - // 字母键 - case GLFW_KEY_A: - return Key::A; - case GLFW_KEY_B: - return Key::B; - case GLFW_KEY_C: - return Key::C; - case GLFW_KEY_D: - return Key::D; - case GLFW_KEY_E: - return Key::E; - case GLFW_KEY_F: - return Key::F; - case GLFW_KEY_G: - return Key::G; - case GLFW_KEY_H: - return Key::H; - case GLFW_KEY_I: - return Key::I; - case GLFW_KEY_J: - return Key::J; - case GLFW_KEY_K: - return Key::K; - case GLFW_KEY_L: - return Key::L; - case GLFW_KEY_M: - return Key::M; - case GLFW_KEY_N: - return Key::N; - case GLFW_KEY_O: - return Key::O; - case GLFW_KEY_P: - return Key::P; - case GLFW_KEY_Q: - return Key::Q; - case GLFW_KEY_R: - return Key::R; - case GLFW_KEY_S: - return Key::S; - case GLFW_KEY_T: - return Key::T; - case GLFW_KEY_U: - return Key::U; - case GLFW_KEY_V: - return Key::V; - case GLFW_KEY_W: - return Key::W; - case GLFW_KEY_X: - return Key::X; - case GLFW_KEY_Y: - return Key::Y; - case GLFW_KEY_Z: - return Key::Z; - - // 数字键 - case GLFW_KEY_0: - return Key::Num0; - case GLFW_KEY_1: - return Key::Num1; - case GLFW_KEY_2: - return Key::Num2; - case GLFW_KEY_3: - return Key::Num3; - case GLFW_KEY_4: - return Key::Num4; - case GLFW_KEY_5: - return Key::Num5; - case GLFW_KEY_6: - return Key::Num6; - case GLFW_KEY_7: - return Key::Num7; - case GLFW_KEY_8: - return Key::Num8; - case GLFW_KEY_9: - return Key::Num9; - - // 功能键 - case GLFW_KEY_F1: - return Key::F1; - case GLFW_KEY_F2: - return Key::F2; - case GLFW_KEY_F3: - return Key::F3; - case GLFW_KEY_F4: - return Key::F4; - case GLFW_KEY_F5: - return Key::F5; - case GLFW_KEY_F6: - return Key::F6; - case GLFW_KEY_F7: - return Key::F7; - case GLFW_KEY_F8: - return Key::F8; - case GLFW_KEY_F9: - return Key::F9; - case GLFW_KEY_F10: - return Key::F10; - case GLFW_KEY_F11: - return Key::F11; - case GLFW_KEY_F12: - return Key::F12; - - // 特殊键 - case GLFW_KEY_SPACE: - return Key::Space; - case GLFW_KEY_ENTER: - return Key::Enter; - case GLFW_KEY_ESCAPE: - return Key::Escape; - case GLFW_KEY_TAB: - return Key::Tab; - case GLFW_KEY_BACKSPACE: - return Key::Backspace; - case GLFW_KEY_INSERT: - return Key::Insert; - case GLFW_KEY_DELETE: - return Key::Delete; - case GLFW_KEY_HOME: - return Key::Home; - case GLFW_KEY_END: - return Key::End; - case GLFW_KEY_PAGE_UP: - return Key::PageUp; - case GLFW_KEY_PAGE_DOWN: - return Key::PageDown; - - // 方向键 - case GLFW_KEY_UP: - return Key::Up; - case GLFW_KEY_DOWN: - return Key::Down; - case GLFW_KEY_LEFT: - return Key::Left; - case GLFW_KEY_RIGHT: - return Key::Right; - - // 修饰键 - case GLFW_KEY_LEFT_SHIFT: - return Key::LShift; - case GLFW_KEY_RIGHT_SHIFT: - return Key::RShift; - case GLFW_KEY_LEFT_CONTROL: - return Key::LCtrl; - case GLFW_KEY_RIGHT_CONTROL: - return Key::RCtrl; - case GLFW_KEY_LEFT_ALT: - return Key::LAlt; - case GLFW_KEY_RIGHT_ALT: - return Key::RAlt; - - // 锁定键 - case GLFW_KEY_CAPS_LOCK: - return Key::CapsLock; - case GLFW_KEY_NUM_LOCK: - return Key::NumLock; - case GLFW_KEY_SCROLL_LOCK: - return Key::ScrollLock; - - default: - return Key::None; - } -} - -GLFWInput::GLFWInput() { - keyCurrent_.fill(false); - keyPrevious_.fill(false); - mouseCurrent_.fill(false); - mousePrevious_.fill(false); - gamepadCurrent_.fill(false); - gamepadPrevious_.fill(false); -} - -GLFWInput::~GLFWInput() { shutdown(); } - -void GLFWInput::init() { - E2D_LOG_INFO("GLFWInput 已初始化"); - openGamepad(); -} - -void GLFWInput::shutdown() { - closeGamepad(); - E2D_LOG_INFO("GLFWInput 已关闭"); -} - -void GLFWInput::update() { - // 保存上一帧状态 - keyPrevious_ = keyCurrent_; - mousePrevious_ = mouseCurrent_; - gamepadPrevious_ = gamepadCurrent_; - - // 重置增量 - scrollDelta_ = 0.0f; - mouseDelta_ = Vec2{0.0f, 0.0f}; - - // 更新游戏手柄 - updateGamepad(); - - // 更新键盘状态(通过轮询 GLFW) - if (window_) { - for (int i = GLFW_KEY_SPACE; i <= GLFW_KEY_LAST; ++i) { - Key key = glfwToKey(i); - if (key != Key::None) { - int state = glfwGetKey(window_, i); - keyCurrent_[static_cast(key)] = (state == GLFW_PRESS); - } - } - - // 更新鼠标按钮状态 - for (int i = 0; i < static_cast(Mouse::Count); ++i) { - int glfwButton = GLFW_MOUSE_BUTTON_1 + i; - if (glfwButton <= GLFW_MOUSE_BUTTON_LAST) { - int state = glfwGetMouseButton(window_, glfwButton); - mouseCurrent_[i] = (state == GLFW_PRESS); - } - } - - // 获取鼠标位置 - double x, y; - glfwGetCursorPos(window_, &x, &y); - mousePos_ = Vec2{static_cast(x), static_cast(y)}; - } -} - -bool GLFWInput::down(Key key) const { - size_t idx = static_cast(key); - if (idx < keyCurrent_.size()) { - return keyCurrent_[idx]; - } - return false; -} - -bool GLFWInput::pressed(Key key) const { - size_t idx = static_cast(key); - if (idx < keyCurrent_.size()) { - return keyCurrent_[idx] && !keyPrevious_[idx]; - } - return false; -} - -bool GLFWInput::released(Key key) const { - size_t idx = static_cast(key); - if (idx < keyCurrent_.size()) { - return !keyCurrent_[idx] && keyPrevious_[idx]; - } - return false; -} - -bool GLFWInput::down(Mouse btn) const { - size_t idx = static_cast(btn); - if (idx < mouseCurrent_.size()) { - return mouseCurrent_[idx]; - } - return false; -} - -bool GLFWInput::pressed(Mouse btn) const { - size_t idx = static_cast(btn); - if (idx < mouseCurrent_.size()) { - return mouseCurrent_[idx] && !mousePrevious_[idx]; - } - return false; -} - -bool GLFWInput::released(Mouse btn) const { - size_t idx = static_cast(btn); - if (idx < mouseCurrent_.size()) { - return !mouseCurrent_[idx] && mousePrevious_[idx]; - } - return false; -} - -Vec2 GLFWInput::mouse() const { return mousePos_; } - -Vec2 GLFWInput::mouseDelta() const { return mouseDelta_; } - -float GLFWInput::scroll() const { return scroll_; } - -float GLFWInput::scrollDelta() const { return scrollDelta_; } - -void GLFWInput::setMouse(const Vec2 &pos) { - if (window_) { - glfwSetCursorPos(window_, pos.x, pos.y); - } -} - -bool GLFWInput::gamepad() const { return gamepadId_ != -1; } - -bool GLFWInput::down(Gamepad btn) const { - size_t idx = static_cast(btn); - if (idx < gamepadCurrent_.size()) { - return gamepadCurrent_[idx]; - } - return false; -} - -bool GLFWInput::pressed(Gamepad btn) const { - size_t idx = static_cast(btn); - if (idx < gamepadCurrent_.size()) { - return gamepadCurrent_[idx] && !gamepadPrevious_[idx]; - } - return false; -} - -bool GLFWInput::released(Gamepad btn) const { - size_t idx = static_cast(btn); - if (idx < gamepadCurrent_.size()) { - return !gamepadCurrent_[idx] && gamepadPrevious_[idx]; - } - return false; -} - -Vec2 GLFWInput::leftStick() const { return leftStick_; } - -Vec2 GLFWInput::rightStick() const { return rightStick_; } - -float GLFWInput::leftTrigger() const { return leftTrigger_; } - -float GLFWInput::rightTrigger() const { return rightTrigger_; } - -void GLFWInput::vibrate(float left, float right) { - // GLFW 本身不支持震动,需要平台特定的代码 - // 这里可以扩展为使用平台特定的 API - (void)left; - (void)right; -} - -bool GLFWInput::touching() const { return false; } - -int GLFWInput::touchCount() const { return 0; } - -Vec2 GLFWInput::touch(int index) const { - (void)index; - return Vec2{0.0f, 0.0f}; -} - -TouchPoint GLFWInput::touchPoint(int index) const { - (void)index; - return TouchPoint{}; -} - -// 事件处理函数 -void GLFWInput::handleKeyEvent(int key, int scancode, int action, int mods) { - (void)scancode; - (void)mods; - - Key eKey = glfwToKey(key); - if (eKey != Key::None) { - size_t idx = static_cast(eKey); - if (action == GLFW_PRESS) { - keyCurrent_[idx] = true; - } else if (action == GLFW_RELEASE) { - keyCurrent_[idx] = false; - } - } -} - -void GLFWInput::handleMouseButtonEvent(int button, int action, int mods) { - (void)mods; - - if (button >= GLFW_MOUSE_BUTTON_1 && button <= GLFW_MOUSE_BUTTON_LAST) { - size_t idx = static_cast(button - GLFW_MOUSE_BUTTON_1); - if (idx < mouseCurrent_.size()) { - if (action == GLFW_PRESS) { - mouseCurrent_[idx] = true; - } else if (action == GLFW_RELEASE) { - mouseCurrent_[idx] = false; - } - } - } -} - -void GLFWInput::handleCursorPosEvent(double xpos, double ypos) { - Vec2 newPos{static_cast(xpos), static_cast(ypos)}; - mouseDelta_ = newPos - mousePos_; - mousePos_ = newPos; -} - -void GLFWInput::handleScrollEvent(double xoffset, double yoffset) { - (void)xoffset; - scroll_ += static_cast(yoffset); - scrollDelta_ += static_cast(yoffset); -} - -void GLFWInput::handleJoystickEvent(int jid, int event) { - if (event == GLFW_CONNECTED) { - E2D_LOG_INFO("游戏手柄已连接: {}", jid); - if (gamepadId_ == -1) { - openGamepad(); - } - } else if (event == GLFW_DISCONNECTED) { - if (jid == gamepadId_) { - E2D_LOG_INFO("游戏手柄已断开: {}", jid); - closeGamepad(); - } - } -} - -void GLFWInput::updateGamepad() { - if (gamepadId_ == -1) { - return; - } - - GLFWgamepadstate state; - if (!glfwGetGamepadState(gamepadId_, &state)) { - return; - } - - // 更新按钮状态 - gamepadCurrent_[static_cast(Gamepad::A)] = - state.buttons[GLFW_GAMEPAD_BUTTON_A] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::B)] = - state.buttons[GLFW_GAMEPAD_BUTTON_B] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::X)] = - state.buttons[GLFW_GAMEPAD_BUTTON_X] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::Y)] = - state.buttons[GLFW_GAMEPAD_BUTTON_Y] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::Back)] = - state.buttons[GLFW_GAMEPAD_BUTTON_BACK] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::Start)] = - state.buttons[GLFW_GAMEPAD_BUTTON_START] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::LStick)] = - state.buttons[GLFW_GAMEPAD_BUTTON_LEFT_THUMB] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::RStick)] = - state.buttons[GLFW_GAMEPAD_BUTTON_RIGHT_THUMB] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::LB)] = - state.buttons[GLFW_GAMEPAD_BUTTON_LEFT_BUMPER] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::RB)] = - state.buttons[GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::DUp)] = - state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_UP] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::DDown)] = - state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_DOWN] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::DLeft)] = - state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_LEFT] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::DRight)] = - state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_RIGHT] == GLFW_PRESS; - gamepadCurrent_[static_cast(Gamepad::Guide)] = - state.buttons[GLFW_GAMEPAD_BUTTON_GUIDE] == GLFW_PRESS; - - // 更新摇杆值(应用死区) - leftStick_.x = applyDeadzone(state.axes[GLFW_GAMEPAD_AXIS_LEFT_X]); - leftStick_.y = applyDeadzone(state.axes[GLFW_GAMEPAD_AXIS_LEFT_Y]); - rightStick_.x = applyDeadzone(state.axes[GLFW_GAMEPAD_AXIS_RIGHT_X]); - rightStick_.y = applyDeadzone(state.axes[GLFW_GAMEPAD_AXIS_RIGHT_Y]); - - // 更新扳机值(范围 [0, 1]) - leftTrigger_ = (state.axes[GLFW_GAMEPAD_AXIS_LEFT_TRIGGER] + 1.0f) * 0.5f; - rightTrigger_ = (state.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER] + 1.0f) * 0.5f; -} - -void GLFWInput::openGamepad() { - for (int jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; ++jid) { - if (glfwJoystickPresent(jid) && glfwJoystickIsGamepad(jid)) { - gamepadId_ = jid; - E2D_LOG_INFO("游戏手柄已打开: {}", glfwGetGamepadName(jid)); - return; - } - } -} - -void GLFWInput::closeGamepad() { - if (gamepadId_ != -1) { - gamepadId_ = -1; - gamepadCurrent_.fill(false); - gamepadPrevious_.fill(false); - leftStick_ = Vec2{0.0f, 0.0f}; - rightStick_ = Vec2{0.0f, 0.0f}; - leftTrigger_ = 0.0f; - rightTrigger_ = 0.0f; - } -} - -float GLFWInput::applyDeadzone(float value) const { - if (std::abs(value) < deadzone_) { - return 0.0f; - } - float sign = value >= 0.0f ? 1.0f : -1.0f; - return sign * (std::abs(value) - deadzone_) / (1.0f - deadzone_); -} - -} // namespace extra2d diff --git a/Extra2D/src/platform/glfw/glfw_window.cpp b/Extra2D/src/platform/glfw/glfw_window.cpp index 82f6ecf..63b1b5a 100644 --- a/Extra2D/src/platform/glfw/glfw_window.cpp +++ b/Extra2D/src/platform/glfw/glfw_window.cpp @@ -1,4 +1,3 @@ -#include #include #include @@ -92,20 +91,11 @@ bool GLFWWindow::create(const std::string &title, int width, int height, glfwSetKeyCallback(glfwWindow_, keyCallback); glfwSetJoystickCallback(joystickCallback); - input_ = makeUnique(); - input_->setWindow(glfwWindow_); - input_->init(); - E2D_LOG_INFO("GLFW 窗口创建成功: {}x{}", width_, height_); return true; } void GLFWWindow::destroy() { - if (input_) { - input_->shutdown(); - input_.reset(); - } - if (glfwWindow_) { glfwDestroyWindow(glfwWindow_); glfwWindow_ = nullptr; @@ -118,10 +108,6 @@ void GLFWWindow::poll() { if (!glfwWindow_) return; - if (input_) { - input_->update(); - } - glfwPollEvents(); } @@ -313,8 +299,6 @@ void GLFWWindow::lockCursor(bool lock) { #endif } -IInput *GLFWWindow::input() const { return input_.get(); } - void GLFWWindow::onResize(ResizeCb cb) { resizeCb_ = cb; } void GLFWWindow::onClose(CloseCb cb) { closeCb_ = cb; } @@ -415,9 +399,6 @@ void GLFWWindow::cursorPosCallback(GLFWwindow *window, double xpos, double ypos) { GLFWWindow *self = static_cast(glfwGetWindowUserPointer(window)); - if (self && self->input_) { - self->input_->handleCursorPosEvent(xpos, ypos); - } // 将事件推送到事件服务 auto eventService = ServiceLocator::instance().getService(); @@ -433,9 +414,6 @@ void GLFWWindow::mouseButtonCallback(GLFWwindow *window, int button, int action, int mods) { GLFWWindow *self = static_cast(glfwGetWindowUserPointer(window)); - if (self && self->input_) { - self->input_->handleMouseButtonEvent(button, action, mods); - } // 将事件推送到事件服务 auto eventService = ServiceLocator::instance().getService(); @@ -458,9 +436,6 @@ void GLFWWindow::scrollCallback(GLFWwindow *window, double xoffset, double yoffset) { GLFWWindow *self = static_cast(glfwGetWindowUserPointer(window)); - if (self && self->input_) { - self->input_->handleScrollEvent(xoffset, yoffset); - } // 将事件推送到事件服务 auto eventService = ServiceLocator::instance().getService(); @@ -478,9 +453,6 @@ void GLFWWindow::keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { GLFWWindow *self = static_cast(glfwGetWindowUserPointer(window)); - if (self && self->input_) { - self->input_->handleKeyEvent(key, scancode, action, mods); - } // 将事件推送到事件服务 auto eventService = ServiceLocator::instance().getService(); diff --git a/Extra2D/src/platform/input_module.cpp b/Extra2D/src/platform/input_module.cpp deleted file mode 100644 index 67e8914..0000000 --- a/Extra2D/src/platform/input_module.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include - - -namespace extra2d { - -InputModule::InputModule(std::function configFn) { - configFn(cfg_); -} - -InputModule::~InputModule() { - if (initialized_) { - shutdown(); - } -} - -bool InputModule::init() { - if (initialized_) - return true; - - // 获取WindowModule依赖 - auto *winMod = Registry::instance().get(); - if (!winMod || !winMod->win()) { - return false; - } - - // 获取输入接口 - input_ = winMod->win()->input(); - if (!input_) { - return false; - } - - initialized_ = true; - return true; -} - -void InputModule::shutdown() { - if (!initialized_) - return; - - input_ = nullptr; - initialized_ = false; -} - -void InputModule::update() { - if (initialized_ && input_) { - input_->update(); - } -} - -} // namespace extra2d diff --git a/Extra2D/src/scene/scene_manager.cpp b/Extra2D/src/scene/scene_manager.cpp index a91274d..58e389f 100644 --- a/Extra2D/src/scene/scene_manager.cpp +++ b/Extra2D/src/scene/scene_manager.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -10,6 +10,7 @@ #include #include #include +#include #include namespace extra2d { @@ -71,9 +72,51 @@ void dispatchToNode(Node *node, Event &event) { */ SceneManager &SceneManager::get() { static SceneManager instance; + static bool initialized = false; + if (!initialized) { + instance.setupEventListeners(); + initialized = true; + } return instance; } +/** + * @brief 设置事件监听器 + */ +void SceneManager::setupEventListeners() { + auto eventService = ServiceLocator::instance().getService(); + if (!eventService) { + return; + } + + mouseMoveListener_ = eventService->addListener(EventType::MouseMoved, [this](Event &e) { + auto &mouseEvent = std::get(e.data); + mousePos_ = mouseEvent.position; + mouseDelta_ = mouseEvent.delta; + }); + + mousePressListener_ = eventService->addListener(EventType::MouseButtonPressed, [this](Event &e) { + auto &mouseEvent = std::get(e.data); + if (mouseEvent.button == static_cast(Mouse::Left)) { + mouseLeftPressed_ = true; + mouseLeftDown_ = true; + } + }); + + mouseReleaseListener_ = eventService->addListener(EventType::MouseButtonReleased, [this](Event &e) { + auto &mouseEvent = std::get(e.data); + if (mouseEvent.button == static_cast(Mouse::Left)) { + mouseLeftReleased_ = true; + mouseLeftDown_ = false; + } + }); + + scrollListener_ = eventService->addListener(EventType::MouseScrolled, [this](Event &e) { + auto &scrollEvent = std::get(e.data); + scrollDelta_ = scrollEvent.offset.y; + }); +} + /** * @brief 运行指定场景 * @param scene 要运行的场景智能指针 @@ -747,10 +790,7 @@ void SceneManager::finishTransition() { * 处理鼠标悬停、移动、点击和滚轮事件 */ void SceneManager::dispatchPointerEvents(Scene &scene) { - auto *input = Application::get().input(); - if (!input) - return; - Vec2 screenPos = input->mouse(); + Vec2 screenPos = mousePos_; Vec2 worldPos = screenPos; if (auto *camera = scene.getActiveCamera()) { @@ -787,13 +827,12 @@ void SceneManager::dispatchPointerEvents(Scene &scene) { dispatchToNode(hoverTarget_, evt); } - float scrollDelta = input->scrollDelta(); - if (hoverTarget_ && scrollDelta != 0.0f) { - Event evt = Event::createMouseScroll(Vec2(0.0f, scrollDelta), worldPos); + if (hoverTarget_ && scrollDelta_ != 0.0f) { + Event evt = Event::createMouseScroll(Vec2(0.0f, scrollDelta_), worldPos); dispatchToNode(hoverTarget_, evt); } - if (input->pressed(Mouse::Left)) { + if (mouseLeftPressed_) { captureTarget_ = hoverTarget_; if (captureTarget_) { Event evt = Event::createMouseButtonPress(static_cast(Mouse::Left), @@ -807,7 +846,7 @@ void SceneManager::dispatchPointerEvents(Scene &scene) { } } - if (input->released(Mouse::Left)) { + if (mouseLeftReleased_) { Node *target = captureTarget_ ? captureTarget_ : hoverTarget_; if (target) { Event evt = Event::createMouseButtonRelease(static_cast(Mouse::Left), @@ -831,6 +870,12 @@ void SceneManager::dispatchPointerEvents(Scene &scene) { } lastPointerWorld_ = worldPos; + + // 重置每帧状态 + mouseLeftPressed_ = false; + mouseLeftReleased_ = false; + scrollDelta_ = 0.0f; + mouseDelta_ = Vec2::Zero(); } void SceneManager::doSceneSwitch() {} diff --git a/examples/basic/main.cpp b/examples/basic/main.cpp index 02a0983..29f2913 100644 --- a/examples/basic/main.cpp +++ b/examples/basic/main.cpp @@ -105,16 +105,12 @@ int main(int argc, char *argv[]) { cfg.w = 1280; cfg.h = 720; cfg.priority = 0; - cfg.backend = "glfw"; }); app.use([](auto &cfg) { cfg.priority = 10; - cfg.backend = "opengl"; }); - app.use([](auto &cfg) { cfg.priority = 20; }); - std::cout << "Initializing application..." << std::endl; if (!app.init()) { std::cerr << "Failed to initialize application!" << std::endl; diff --git a/examples/hello_module/main.cpp b/examples/hello_module/main.cpp index 2302bde..b0361ea 100644 --- a/examples/hello_module/main.cpp +++ b/examples/hello_module/main.cpp @@ -43,10 +43,8 @@ int main(int argc, char *argv[]) { app.use([](auto &cfg) { cfg.w = 800; cfg.h = 600; - cfg.backend = "glfw"; }); app.use([](auto &cfg) { - cfg.backend = "opengl"; cfg.priority = 10; }); app.use([](auto &cfg) { diff --git a/examples/image_display/main.cpp b/examples/image_display/main.cpp index b25bbb0..f27bfce 100644 --- a/examples/image_display/main.cpp +++ b/examples/image_display/main.cpp @@ -101,16 +101,12 @@ int main(int argc, char *argv[]) { cfg.h = 720; cfg.title = "Extra2D 图片显示示例"; cfg.priority = 0; - cfg.backend = "sdl2"; }); app.use([](auto &cfg) { cfg.priority = 10; - cfg.backend = "opengl"; }); - app.use([](auto &cfg) { cfg.priority = 20; }); - if (!app.init()) { std::cerr << "Failed to initialize application!" << std::endl; return -1; diff --git a/examples/text_rendering/main.cpp b/examples/text_rendering/main.cpp index 17cb764..2265dfd 100644 --- a/examples/text_rendering/main.cpp +++ b/examples/text_rendering/main.cpp @@ -116,8 +116,6 @@ int main(int argc, char *argv[]) { app.use([](auto &cfg) { cfg.priority = 10; }); - app.use([](auto &cfg) { cfg.priority = 20; }); - if (!app.init()) { E2D_LOG_INFO("Failed to initialize application!"); return -1;