From ba885e4e08b86d0989a39a96ee4b32bfedbf0326 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 5 May 2024 06:49:17 +0300 Subject: [PATCH] input.add_callback --- src/data/setting.hpp | 2 -- src/frontend/hud.h | 3 ++- src/logic/scripting/lua/libinput.cpp | 21 ++++++++++++++++++ src/typedefs.h | 1 + src/util/RunnablesList.hpp | 32 ++++++++++++++++++++++++++++ src/window/Events.cpp | 3 ++- src/window/input.h | 10 +++++++-- 7 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 src/util/RunnablesList.hpp diff --git a/src/data/setting.hpp b/src/data/setting.hpp index 8a84ce81..ef563207 100644 --- a/src/data/setting.hpp +++ b/src/data/setting.hpp @@ -31,8 +31,6 @@ public: virtual std::string toString() const = 0; }; -using observer_handler = std::shared_ptr; - template class ObservableSetting : public Setting { int nextid = 1; diff --git a/src/frontend/hud.h b/src/frontend/hud.h index 56fe294d..e747f1a6 100644 --- a/src/frontend/hud.h +++ b/src/frontend/hud.h @@ -2,6 +2,7 @@ #define FRONTEND_HUD_H_ #include "../typedefs.h" +#include "../util/ObjectsKeeper.hpp" #include #include @@ -63,7 +64,7 @@ public: } }; -class Hud { +class Hud : public util::ObjectsKeeper { Assets* assets; std::unique_ptr uicamera; gui::GUI* gui; diff --git a/src/logic/scripting/lua/libinput.cpp b/src/logic/scripting/lua/libinput.cpp index 37241c3e..4e3fe58c 100644 --- a/src/logic/scripting/lua/libinput.cpp +++ b/src/logic/scripting/lua/libinput.cpp @@ -5,22 +5,43 @@ #include "../../../window/input.h" #include "../../../window/Events.h" #include "../../../frontend/screens/Screen.hpp" +#include "../../../frontend/hud.h" #include "../../../engine.h" #include "LuaState.h" namespace scripting { extern lua::LuaState* state; + extern Hud* hud; } +using namespace scripting; + static int l_keycode(lua_State* L) { const char* name = lua_tostring(L, 1); lua_pushinteger(L, static_cast(input_util::keycode_from(name))); return 1; } +static int l_add_callback(lua_State* L) { + auto bindname = lua_tostring(L, 1); + const auto& bind = Events::bindings.find(bindname); + if (bind == Events::bindings.end()) { + luaL_error(L, "unknown binding %q", bindname); + } + state->pushvalue(2); + runnable callback = state->createRunnable(); + if (hud) { + hud->keepAlive(bind->second.onactived.add(callback)); + } else { + engine->keepAlive(bind->second.onactived.add(callback)); + } + return 0; +} + const luaL_Reg inputlib [] = { {"keycode", lua_wrap_errors}, + {"add_callback", lua_wrap_errors}, {NULL, NULL} }; diff --git a/src/typedefs.h b/src/typedefs.h index 3f17f60e..5fac8b88 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -7,6 +7,7 @@ #include using scriptenv = std::shared_ptr; +using observer_handler = std::shared_ptr; /// @brief dynamic integer type (64 bit signed integer) using integer_t = int64_t; diff --git a/src/util/RunnablesList.hpp b/src/util/RunnablesList.hpp new file mode 100644 index 00000000..99d4e321 --- /dev/null +++ b/src/util/RunnablesList.hpp @@ -0,0 +1,32 @@ +#ifndef UTIL_RUNNABLES_LIST_HPP_ +#define UTIL_RUNNABLES_LIST_HPP_ + +#include "../typedefs.h" +#include "../delegates.h" + +#include +#include + +namespace util { + class RunnablesList { + int nextid = 1; + std::unordered_map runnables; + public: + observer_handler add(runnable callback) { + int id = nextid++; + runnables[id] = callback; + return observer_handler(new int(id), [this](int* id) { + runnables.erase(*id); + delete id; + }); + } + + void notify() { + for (auto& entry : runnables) { + entry.second(); + } + } + }; +} + +#endif // UTIL_RUNNABLES_LIST_HPP_ diff --git a/src/window/Events.cpp b/src/window/Events.cpp index adf1ecb1..958cdddf 100644 --- a/src/window/Events.cpp +++ b/src/window/Events.cpp @@ -85,6 +85,7 @@ void Events::pollEvents() { if (!binding.state) { binding.state = true; binding.justChange = true; + binding.onactived.notify(); } } else { @@ -105,7 +106,7 @@ void Events::bind(std::string name, inputtype type, mousecode code) { } void Events::bind(std::string name, inputtype type, int code) { - bindings[name] = { type, code, false, false }; + bindings[name] = Binding(type, code); } bool Events::active(std::string name) { diff --git a/src/window/input.h b/src/window/input.h index 181cb506..b99673a3 100644 --- a/src/window/input.h +++ b/src/window/input.h @@ -1,6 +1,8 @@ #ifndef WINDOW_INPUT_H_ #define WINDOW_INPUT_H_ +#include "../util/RunnablesList.hpp" + #include /// @brief Represents glfw3 keycode values. @@ -86,8 +88,6 @@ enum class keycode : int { UNKNOWN = -1 }; - - /// @brief Represents glfw3 mouse button IDs. /// @details There is a subset of glfw3 mouse button IDs. enum class mousecode : int { @@ -104,6 +104,7 @@ inline mousecode MOUSECODES_ALL[] { namespace input_util { void initialize(); + keycode keycode_from(const std::string& name); /// @return Key label by keycode std::string to_string(keycode code); @@ -117,10 +118,15 @@ enum class inputtype { }; struct Binding { + util::RunnablesList onactived; + inputtype type; int code; bool state = false; bool justChange = false; + + Binding(){} + Binding(inputtype type, int code) : type(type), code(code) {} bool active() const { return state;