add input.add_callback("key:...") support

This commit is contained in:
MihailRis 2024-12-25 14:08:22 +03:00
parent 5e76cdfadc
commit 96577ee041
4 changed files with 46 additions and 2 deletions

View File

@ -30,7 +30,21 @@ static int l_mousecode(lua::State* L) {
}
static int l_add_callback(lua::State* L) {
auto bindname = lua::require_string(L, 1);
std::string bindname = lua::require_string(L, 1);
size_t pos = bindname.find(':');
if (pos != std::string::npos) {
std::string prefix = bindname.substr(0, pos);
if (prefix == "key") {
if (hud == nullptr) {
throw std::runtime_error("on_hud_open is not called yet");
}
auto key = input_util::keycode_from(bindname.substr(pos + 1));
auto callback = lua::create_runnable(L);
hud->keepAlive(Events::keyCallbacks[key].add(callback));
return 0;
}
}
const auto& bind = Events::bindings.find(bindname);
if (bind == Events::bindings.end()) {
throw std::runtime_error("unknown binding " + util::quote(bindname));

View File

@ -1,5 +1,6 @@
#pragma once
#include <mutex>
#include <memory>
#include <unordered_map>
#include <utility>
@ -11,17 +12,33 @@ namespace util {
class RunnablesList {
int nextid = 1;
std::unordered_map<int, runnable> runnables;
std::mutex mutex;
public:
RunnablesList() = default;
RunnablesList(RunnablesList&& o) {
runnables = std::move(o.runnables);
nextid = o.nextid;
}
void operator=(RunnablesList&& o) {
runnables = std::move(o.runnables);
nextid = o.nextid;
}
observer_handler add(runnable callback) {
std::lock_guard lock(mutex);
int id = nextid++;
runnables[id] = std::move(callback);
return observer_handler(new int(id), [this](int* id) { //-V508
std::lock_guard lock(mutex);
runnables.erase(*id);
delete id;
});
}
void notify() {
std::lock_guard lock(mutex);
for (auto& entry : runnables) {
entry.second();
}

View File

@ -23,6 +23,7 @@ bool Events::_cursor_locked = false;
std::vector<uint> Events::codepoints;
std::vector<keycode> Events::pressedKeys;
std::unordered_map<std::string, Binding> Events::bindings;
std::unordered_map<keycode, util::RunnablesList> Events::keyCallbacks;
bool Events::pressed(keycode keycode) {
return pressed(static_cast<int>(keycode));
@ -156,6 +157,12 @@ bool Events::jactive(const std::string& name) {
void Events::setKey(int key, bool b) {
Events::keys[key] = b;
Events::frames[key] = currentFrame;
if (b) {
const auto& callbacks = keyCallbacks.find(static_cast<keycode>(key));
if (callbacks != keyCallbacks.end()) {
callbacks->second.notify();
}
}
}
void Events::setButton(int button, bool b) {
@ -173,6 +180,10 @@ void Events::setPosition(float xpos, float ypos) {
Events::cursor.y = ypos;
}
observer_handler Events::addKeyCallback(keycode key, runnable callback) {
return keyCallbacks[key].add(std::move(callback));
}
#include "coders/json.hpp"
#include "coders/toml.hpp"
@ -228,7 +239,6 @@ void Events::loadBindings(
} else if (bindType == BindType::REBIND) {
Events::rebind(key, type, code);
}
}
}
}

View File

@ -27,6 +27,7 @@ public:
static std::vector<uint> codepoints;
static std::vector<keycode> pressedKeys;
static std::unordered_map<std::string, Binding> bindings;
static std::unordered_map<keycode, util::RunnablesList> keyCallbacks;
static void pollEvents();
@ -50,6 +51,8 @@ public:
static bool active(const std::string& name);
static bool jactive(const std::string& name);
static observer_handler addKeyCallback(keycode key, runnable callback);
static void setKey(int key, bool b);
static void setButton(int button, bool b);