refactor: replace references to Events with Input
This commit is contained in:
parent
4c48afbb90
commit
b202d1455b
@ -5,12 +5,12 @@
|
|||||||
#include "content/ContentBuilder.hpp"
|
#include "content/ContentBuilder.hpp"
|
||||||
#include "io/io.hpp"
|
#include "io/io.hpp"
|
||||||
#include "io/engine_paths.hpp"
|
#include "io/engine_paths.hpp"
|
||||||
#include "window/Events.hpp"
|
|
||||||
#include "window/input.hpp"
|
#include "window/input.hpp"
|
||||||
#include "voxels/Block.hpp"
|
#include "voxels/Block.hpp"
|
||||||
|
#include "coders/toml.hpp"
|
||||||
|
|
||||||
// All in-game definitions (blocks, items, etc..)
|
// All in-game definitions (blocks, items, etc..)
|
||||||
void corecontent::setup(ContentBuilder& builder) {
|
void corecontent::setup(Input& input, ContentBuilder& builder) {
|
||||||
{
|
{
|
||||||
Block& block = builder.blocks.create(CORE_AIR);
|
Block& block = builder.blocks.create(CORE_AIR);
|
||||||
block.replaceable = true;
|
block.replaceable = true;
|
||||||
@ -29,8 +29,8 @@ void corecontent::setup(ContentBuilder& builder) {
|
|||||||
|
|
||||||
auto bindsFile = "res:bindings.toml";
|
auto bindsFile = "res:bindings.toml";
|
||||||
if (io::is_regular_file(bindsFile)) {
|
if (io::is_regular_file(bindsFile)) {
|
||||||
Events::loadBindings(
|
input.getBindings().read(
|
||||||
bindsFile, io::read_string(bindsFile), BindType::BIND
|
toml::parse(bindsFile, io::read_string(bindsFile)), BindType::BIND
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,8 +28,9 @@ inline const std::string BIND_PLAYER_FAST_INTERACTOIN =
|
|||||||
"player.fast_interaction";
|
"player.fast_interaction";
|
||||||
inline const std::string BIND_HUD_INVENTORY = "hud.inventory";
|
inline const std::string BIND_HUD_INVENTORY = "hud.inventory";
|
||||||
|
|
||||||
|
class Input;
|
||||||
class ContentBuilder;
|
class ContentBuilder;
|
||||||
|
|
||||||
namespace corecontent {
|
namespace corecontent {
|
||||||
void setup(ContentBuilder& builder);
|
void setup(Input& input, ContentBuilder& builder);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -149,7 +149,9 @@ void Engine::loadControls() {
|
|||||||
if (io::is_regular_file(controls_file)) {
|
if (io::is_regular_file(controls_file)) {
|
||||||
logger.info() << "loading controls";
|
logger.info() << "loading controls";
|
||||||
std::string text = io::read_string(controls_file);
|
std::string text = io::read_string(controls_file);
|
||||||
Events::loadBindings(controls_file.string(), text, BindType::BIND);
|
input->getBindings().read(
|
||||||
|
toml::parse(controls_file.string(), text), BindType::BIND
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,13 +161,13 @@ void Engine::onAssetsLoaded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Engine::updateHotkeys() {
|
void Engine::updateHotkeys() {
|
||||||
if (Events::jpressed(keycode::F2)) {
|
if (input->jpressed(keycode::F2)) {
|
||||||
saveScreenshot();
|
saveScreenshot();
|
||||||
}
|
}
|
||||||
if (Events::jpressed(keycode::F8)) {
|
if (input->jpressed(keycode::F8)) {
|
||||||
gui->toggleDebug();
|
gui->toggleDebug();
|
||||||
}
|
}
|
||||||
if (Events::jpressed(keycode::F11)) {
|
if (input->jpressed(keycode::F11)) {
|
||||||
settings.display.fullscreen.toggle();
|
settings.display.fullscreen.toggle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +226,7 @@ void Engine::saveSettings() {
|
|||||||
io::write_string(paths.getSettingsFile(), toml::stringify(*settingsHandler));
|
io::write_string(paths.getSettingsFile(), toml::stringify(*settingsHandler));
|
||||||
if (!params.headless) {
|
if (!params.headless) {
|
||||||
logger.info() << "saving bindings";
|
logger.info() << "saving bindings";
|
||||||
io::write_string(paths.getControlsFile(), Events::writeBindings());
|
io::write_string(paths.getControlsFile(), input->getBindings().write());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,12 +326,14 @@ void Engine::loadAssets() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_configs(const io::path& root) {
|
static void load_configs(Engine& engine, const io::path& root) {
|
||||||
|
auto& input = engine.getInput();
|
||||||
auto configFolder = root / "config";
|
auto configFolder = root / "config";
|
||||||
auto bindsFile = configFolder / "bindings.toml";
|
auto bindsFile = configFolder / "bindings.toml";
|
||||||
if (io::is_regular_file(bindsFile)) {
|
if (io::is_regular_file(bindsFile)) {
|
||||||
Events::loadBindings(
|
input.getBindings().read(
|
||||||
bindsFile.string(), io::read_string(bindsFile), BindType::BIND
|
toml::parse(bindsFile.string(), io::read_string(bindsFile)),
|
||||||
|
BindType::BIND
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,7 +347,7 @@ void Engine::loadContent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentBuilder contentBuilder;
|
ContentBuilder contentBuilder;
|
||||||
corecontent::setup(contentBuilder);
|
corecontent::setup(*input, contentBuilder);
|
||||||
|
|
||||||
paths.setContentPacks(&contentPacks);
|
paths.setContentPacks(&contentPacks);
|
||||||
PacksManager manager = createPacksManager(paths.getCurrentWorldFolder());
|
PacksManager manager = createPacksManager(paths.getCurrentWorldFolder());
|
||||||
@ -365,11 +369,11 @@ void Engine::loadContent() {
|
|||||||
// Load content
|
// Load content
|
||||||
{
|
{
|
||||||
ContentLoader(&corePack, contentBuilder, *resPaths).load();
|
ContentLoader(&corePack, contentBuilder, *resPaths).load();
|
||||||
load_configs(corePack.folder);
|
load_configs(*this, corePack.folder);
|
||||||
}
|
}
|
||||||
for (auto& pack : contentPacks) {
|
for (auto& pack : contentPacks) {
|
||||||
ContentLoader(&pack, contentBuilder, *resPaths).load();
|
ContentLoader(&pack, contentBuilder, *resPaths).load();
|
||||||
load_configs(pack.folder);
|
load_configs(*this, pack.folder);
|
||||||
}
|
}
|
||||||
content = contentBuilder.build();
|
content = contentBuilder.build();
|
||||||
scripting::on_content_load(content.get());
|
scripting::on_content_load(content.get());
|
||||||
@ -389,7 +393,7 @@ void Engine::resetContent() {
|
|||||||
{
|
{
|
||||||
auto pack = ContentPack::createCore(paths);
|
auto pack = ContentPack::createCore(paths);
|
||||||
resRoots.push_back({"core", pack.folder});
|
resRoots.push_back({"core", pack.folder});
|
||||||
load_configs(pack.folder);
|
load_configs(*this, pack.folder);
|
||||||
}
|
}
|
||||||
auto manager = createPacksManager(io::path());
|
auto manager = createPacksManager(io::path());
|
||||||
manager.scan();
|
manager.scan();
|
||||||
|
|||||||
@ -331,7 +331,7 @@ void Hud::update(bool visible) {
|
|||||||
processInput(visible);
|
processInput(visible);
|
||||||
}
|
}
|
||||||
if ((menu.hasOpenPage() || inventoryOpen) == input.getCursor().locked) {
|
if ((menu.hasOpenPage() || inventoryOpen) == input.getCursor().locked) {
|
||||||
Events::toggleCursor();
|
input.toggleCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockUI) {
|
if (blockUI) {
|
||||||
|
|||||||
@ -105,7 +105,7 @@ LevelScreen::~LevelScreen() {
|
|||||||
}
|
}
|
||||||
scripting::on_frontend_close();
|
scripting::on_frontend_close();
|
||||||
// unblock all bindings
|
// unblock all bindings
|
||||||
Events::enableBindings();
|
input.getBindings().enableAll();
|
||||||
controller->onWorldQuit();
|
controller->onWorldQuit();
|
||||||
engine.getPaths().setCurrentWorldFolder("");
|
engine.getPaths().setCurrentWorldFolder("");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,10 +178,10 @@ void GUI::actFocused() {
|
|||||||
focus = nullptr;
|
focus = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (auto codepoint : Events::codepoints) {
|
for (auto codepoint : input.getCodepoints()) {
|
||||||
focus->typed(codepoint);
|
focus->typed(codepoint);
|
||||||
}
|
}
|
||||||
for (auto key : Events::pressedKeys) {
|
for (auto key : input.getPressedKeys()) {
|
||||||
focus->keyPressed(key);
|
focus->keyPressed(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ void GUI::act(float delta, const Viewport& vp) {
|
|||||||
updateTooltip(delta);
|
updateTooltip(delta);
|
||||||
|
|
||||||
const auto& cursor = input.getCursor();
|
const auto& cursor = input.getCursor();
|
||||||
if (!Events::isCursorLocked()) {
|
if (!cursor.locked) {
|
||||||
actMouse(delta, cursor);
|
actMouse(delta, cursor);
|
||||||
} else {
|
} else {
|
||||||
if (hover) {
|
if (hover) {
|
||||||
@ -357,3 +357,7 @@ void GUI::toggleDebug() {
|
|||||||
const Input& GUI::getInput() const {
|
const Input& GUI::getInput() const {
|
||||||
return engine.getInput();
|
return engine.getInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Input& GUI::getInput() {
|
||||||
|
return engine.getInput();
|
||||||
|
}
|
||||||
|
|||||||
@ -157,5 +157,6 @@ namespace gui {
|
|||||||
|
|
||||||
void toggleDebug();
|
void toggleDebug();
|
||||||
const Input& getInput() const;
|
const Input& getInput() const;
|
||||||
|
Input& getInput();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -281,7 +281,8 @@ bool SlotView::isHighlighted() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SlotView::performLeftClick(ItemStack& stack, ItemStack& grabbed) {
|
void SlotView::performLeftClick(ItemStack& stack, ItemStack& grabbed) {
|
||||||
if (layout.taking && Events::pressed(keycode::LEFT_SHIFT)) {
|
const auto& input = gui.getInput();
|
||||||
|
if (layout.taking && input.pressed(keycode::LEFT_SHIFT)) {
|
||||||
if (layout.shareFunc) {
|
if (layout.shareFunc) {
|
||||||
layout.shareFunc(layout.index, stack);
|
layout.shareFunc(layout.index, stack);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -587,7 +587,7 @@ static std::shared_ptr<UINode> read_input_bind_box(
|
|||||||
UiXmlReader& reader, const xml::xmlelement& element
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
auto bindname = element.attr("binding").getText();
|
auto bindname = element.attr("binding").getText();
|
||||||
auto& found = Events::requireBinding(bindname);
|
auto& found = reader.getGUI().getInput().getBindings().require(bindname);
|
||||||
glm::vec4 padding = element.attr("padding", "6").asVec4();
|
glm::vec4 padding = element.attr("padding", "6").asVec4();
|
||||||
auto bindbox =
|
auto bindbox =
|
||||||
std::make_shared<InputBindBox>(reader.getGUI(), found, padding);
|
std::make_shared<InputBindBox>(reader.getGUI(), found, padding);
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include "util/stringutil.hpp"
|
#include "util/stringutil.hpp"
|
||||||
#include "window/Events.hpp"
|
#include "window/Events.hpp"
|
||||||
#include "window/input.hpp"
|
#include "window/input.hpp"
|
||||||
|
#include "coders/toml.hpp"
|
||||||
|
|
||||||
namespace scripting {
|
namespace scripting {
|
||||||
extern Hud* hud;
|
extern Hud* hud;
|
||||||
@ -55,7 +56,7 @@ static int l_add_callback(lua::State* L) {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if (handler == nullptr) {
|
if (handler == nullptr) {
|
||||||
auto& bind = input.requireBinding(bindname);
|
auto& bind = input.getBindings().require(bindname);
|
||||||
handler = bind.onactived.add(callback);
|
handler = bind.onactived.add(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,13 +94,13 @@ static int l_get_bindings(lua::State* L) {
|
|||||||
|
|
||||||
static int l_get_binding_text(lua::State* L) {
|
static int l_get_binding_text(lua::State* L) {
|
||||||
auto bindname = lua::require_string(L, 1);
|
auto bindname = lua::require_string(L, 1);
|
||||||
const auto& bind = engine->getInput().requireBinding(bindname);
|
const auto& bind = engine->getInput().getBindings().require(bindname);
|
||||||
return lua::pushstring(L, bind.text());
|
return lua::pushstring(L, bind.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_is_active(lua::State* L) {
|
static int l_is_active(lua::State* L) {
|
||||||
auto bindname = lua::require_string(L, 1);
|
auto bindname = lua::require_string(L, 1);
|
||||||
auto& bind = engine->getInput().requireBinding(bindname);
|
auto& bind = engine->getInput().getBindings().require(bindname);
|
||||||
return lua::pushboolean(L, bind.active());
|
return lua::pushboolean(L, bind.active());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,8 +129,9 @@ static void reset_pack_bindings(const io::path& packFolder) {
|
|||||||
auto configFolder = packFolder / "config";
|
auto configFolder = packFolder / "config";
|
||||||
auto bindsFile = configFolder / "bindings.toml";
|
auto bindsFile = configFolder / "bindings.toml";
|
||||||
if (io::is_regular_file(bindsFile)) {
|
if (io::is_regular_file(bindsFile)) {
|
||||||
Events::loadBindings(
|
engine->getInput().getBindings().read(
|
||||||
bindsFile.string(), io::read_string(bindsFile), BindType::REBIND
|
toml::parse(bindsFile.string(), io::read_string(bindsFile)),
|
||||||
|
BindType::REBIND
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,7 +147,7 @@ static int l_reset_bindings(lua::State*) {
|
|||||||
static int l_set_enabled(lua::State* L) {
|
static int l_set_enabled(lua::State* L) {
|
||||||
std::string bindname = lua::require_string(L, 1);
|
std::string bindname = lua::require_string(L, 1);
|
||||||
bool enabled = lua::toboolean(L, 2);
|
bool enabled = lua::toboolean(L, 2);
|
||||||
engine->getInput().requireBinding(bindname).enabled = enabled;
|
engine->getInput().getBindings().require(bindname).enabled = enabled;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -184,71 +184,6 @@ observer_handler Events::addKeyCallback(keycode key, KeyCallback callback) {
|
|||||||
return ::key_callbacks[key].add(std::move(callback));
|
return ::key_callbacks[key].add(std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "coders/json.hpp"
|
|
||||||
#include "coders/toml.hpp"
|
|
||||||
|
|
||||||
std::string Events::writeBindings() {
|
|
||||||
auto obj = dv::object();
|
|
||||||
for (auto& entry : bindings.getAll()) {
|
|
||||||
const auto& binding = entry.second;
|
|
||||||
std::string value;
|
|
||||||
switch (binding.type) {
|
|
||||||
case inputtype::keyboard:
|
|
||||||
value =
|
|
||||||
"key:" +
|
|
||||||
input_util::get_name(static_cast<keycode>(binding.code));
|
|
||||||
break;
|
|
||||||
case inputtype::mouse:
|
|
||||||
value =
|
|
||||||
"mouse:" +
|
|
||||||
input_util::get_name(static_cast<mousecode>(binding.code));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("unsupported control type");
|
|
||||||
}
|
|
||||||
obj[entry.first] = std::move(value);
|
|
||||||
}
|
|
||||||
return toml::stringify(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::loadBindings(
|
|
||||||
const std::string& filename, const std::string& source,
|
|
||||||
BindType bindType
|
|
||||||
) {
|
|
||||||
auto map = toml::parse(filename, source);
|
|
||||||
for (auto& [sectionName, section] : map.asObject()) {
|
|
||||||
for (auto& [name, value] : section.asObject()) {
|
|
||||||
auto key = sectionName + "." + name;
|
|
||||||
auto [prefix, codename] = util::split_at(value.asString(), ':');
|
|
||||||
inputtype type;
|
|
||||||
int code;
|
|
||||||
if (prefix == "key") {
|
|
||||||
type = inputtype::keyboard;
|
|
||||||
code = static_cast<int>(input_util::keycode_from(codename));
|
|
||||||
} else if (prefix == "mouse") {
|
|
||||||
type = inputtype::mouse;
|
|
||||||
code = static_cast<int>(input_util::mousecode_from(codename));
|
|
||||||
} else {
|
|
||||||
logger.error()
|
|
||||||
<< "unknown input type: " << prefix << " (binding "
|
|
||||||
<< util::quote(key) << ")";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (bindType == BindType::BIND) {
|
|
||||||
Events::bind(key, type, code);
|
|
||||||
} else if (bindType == BindType::REBIND) {
|
|
||||||
Events::rebind(key, type, code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::enableBindings() {
|
|
||||||
for (auto& entry : bindings.getAll()) {
|
|
||||||
entry.second.enabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Events::isCursorLocked() {
|
bool Events::isCursorLocked() {
|
||||||
return cursor_locked;
|
return cursor_locked;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,11 +10,6 @@
|
|||||||
|
|
||||||
inline constexpr short KEYS_BUFFER_SIZE = 1036;
|
inline constexpr short KEYS_BUFFER_SIZE = 1036;
|
||||||
|
|
||||||
enum class BindType {
|
|
||||||
BIND = 0,
|
|
||||||
REBIND = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Events {
|
namespace Events {
|
||||||
extern int scroll;
|
extern int scroll;
|
||||||
extern glm::vec2 delta;
|
extern glm::vec2 delta;
|
||||||
@ -55,13 +50,5 @@ namespace Events {
|
|||||||
|
|
||||||
void setPosition(float xpos, float ypos);
|
void setPosition(float xpos, float ypos);
|
||||||
|
|
||||||
std::string writeBindings();
|
|
||||||
void loadBindings(
|
|
||||||
const std::string& filename,
|
|
||||||
const std::string& source,
|
|
||||||
BindType bindType
|
|
||||||
);
|
|
||||||
void enableBindings();
|
|
||||||
|
|
||||||
bool isCursorLocked();
|
bool isCursorLocked();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -189,10 +189,6 @@ public:
|
|||||||
return Events::getScroll();
|
return Events::getScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding& requireBinding(const std::string& name) override {
|
|
||||||
return Events::requireBinding(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pressed(keycode keycode) const override {
|
bool pressed(keycode keycode) const override {
|
||||||
return Events::pressed(keycode);
|
return Events::pressed(keycode);
|
||||||
}
|
}
|
||||||
@ -215,6 +211,10 @@ public:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toggleCursor() override {
|
||||||
|
Events::toggleCursor();
|
||||||
|
}
|
||||||
|
|
||||||
Bindings& getBindings() override {
|
Bindings& getBindings() override {
|
||||||
return Events::bindings;
|
return Events::bindings;
|
||||||
}
|
}
|
||||||
@ -226,6 +226,14 @@ public:
|
|||||||
observer_handler addKeyCallback(keycode key, KeyCallback callback) override {
|
observer_handler addKeyCallback(keycode key, KeyCallback callback) override {
|
||||||
return Events::addKeyCallback(key, std::move(callback));
|
return Events::addKeyCallback(key, std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<keycode>& getPressedKeys() const override {
|
||||||
|
return Events::pressedKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<uint>& getCodepoints() const override {
|
||||||
|
return Events::codepoints;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static_assert(!std::is_abstract<GLFWInput>());
|
static_assert(!std::is_abstract<GLFWInput>());
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
#include "input.hpp"
|
#include "input.hpp"
|
||||||
|
|
||||||
|
#include "debug/Logger.hpp"
|
||||||
|
#include "util/stringutil.hpp"
|
||||||
|
#include "data/dv.hpp"
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@ -8,6 +12,8 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
static debug::Logger logger("input");
|
||||||
|
|
||||||
static std::unordered_map<std::string, int> keycodes {
|
static std::unordered_map<std::string, int> keycodes {
|
||||||
{"enter", GLFW_KEY_ENTER},
|
{"enter", GLFW_KEY_ENTER},
|
||||||
{"space", GLFW_KEY_SPACE},
|
{"space", GLFW_KEY_SPACE},
|
||||||
@ -225,3 +231,64 @@ std::string input_util::to_string(mousecode code) {
|
|||||||
return "unknown button";
|
return "unknown button";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Binding& Bindings::require(const std::string& name) const {
|
||||||
|
if (const auto found = get(name)) {
|
||||||
|
return *found;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("binding '" + name + "' does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Bindings::read(const dv::value& map, BindType bindType) {
|
||||||
|
for (auto& [sectionName, section] : map.asObject()) {
|
||||||
|
for (auto& [name, value] : section.asObject()) {
|
||||||
|
auto key = sectionName + "." + name;
|
||||||
|
auto [prefix, codename] = util::split_at(value.asString(), ':');
|
||||||
|
inputtype type;
|
||||||
|
int code;
|
||||||
|
if (prefix == "key") {
|
||||||
|
type = inputtype::keyboard;
|
||||||
|
code = static_cast<int>(input_util::keycode_from(codename));
|
||||||
|
} else if (prefix == "mouse") {
|
||||||
|
type = inputtype::mouse;
|
||||||
|
code = static_cast<int>(input_util::mousecode_from(codename));
|
||||||
|
} else {
|
||||||
|
logger.error()
|
||||||
|
<< "unknown input type: " << prefix << " (binding "
|
||||||
|
<< util::quote(key) << ")";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (bindType == BindType::BIND) {
|
||||||
|
bind(key, type, code);
|
||||||
|
} else if (bindType == BindType::REBIND) {
|
||||||
|
rebind(key, type, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "coders/toml.hpp"
|
||||||
|
|
||||||
|
std::string Bindings::write() const {
|
||||||
|
auto obj = dv::object();
|
||||||
|
for (auto& entry : bindings) {
|
||||||
|
const auto& binding = entry.second;
|
||||||
|
std::string value;
|
||||||
|
switch (binding.type) {
|
||||||
|
case inputtype::keyboard:
|
||||||
|
value =
|
||||||
|
"key:" +
|
||||||
|
input_util::get_name(static_cast<keycode>(binding.code));
|
||||||
|
break;
|
||||||
|
case inputtype::mouse:
|
||||||
|
value =
|
||||||
|
"mouse:" +
|
||||||
|
input_util::get_name(static_cast<mousecode>(binding.code));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unsupported control type");
|
||||||
|
}
|
||||||
|
obj[entry.first] = std::move(value);
|
||||||
|
}
|
||||||
|
return toml::stringify(obj);
|
||||||
|
}
|
||||||
|
|||||||
@ -5,6 +5,15 @@
|
|||||||
|
|
||||||
#include "util/HandlersList.hpp"
|
#include "util/HandlersList.hpp"
|
||||||
|
|
||||||
|
namespace dv {
|
||||||
|
class value;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class BindType {
|
||||||
|
BIND = 0,
|
||||||
|
REBIND = 1
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Represents glfw3 keycode values.
|
/// @brief Represents glfw3 keycode values.
|
||||||
enum class keycode : int {
|
enum class keycode : int {
|
||||||
SPACE = 32,
|
SPACE = 32,
|
||||||
@ -195,6 +204,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Binding* get(const std::string& name) {
|
Binding* get(const std::string& name) {
|
||||||
|
return const_cast<Bindings*>(this)->get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Binding* get(const std::string& name) const {
|
||||||
const auto found = bindings.find(name);
|
const auto found = bindings.find(name);
|
||||||
if (found == bindings.end()) {
|
if (found == bindings.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -202,13 +215,32 @@ public:
|
|||||||
return &found->second;
|
return &found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binding& require(const std::string& name) {
|
||||||
|
return const_cast<Bindings*>(this)->require(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Binding& require(const std::string& name) const;
|
||||||
|
|
||||||
void bind(const std::string& name, inputtype type, int code) {
|
void bind(const std::string& name, inputtype type, int code) {
|
||||||
bindings.try_emplace(name, Binding(type, code));
|
bindings.try_emplace(name, Binding(type, code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rebind(const std::string& name, inputtype type, int code) {
|
||||||
|
require(name) = Binding(type, code);
|
||||||
|
}
|
||||||
|
|
||||||
auto& getAll() {
|
auto& getAll() {
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enableAll() {
|
||||||
|
for (auto& entry : bindings) {
|
||||||
|
entry.second.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void read(const dv::value& map, BindType bindType);
|
||||||
|
std::string write() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CursorState {
|
struct CursorState {
|
||||||
@ -227,8 +259,6 @@ public:
|
|||||||
|
|
||||||
virtual int getScroll() = 0;
|
virtual int getScroll() = 0;
|
||||||
|
|
||||||
virtual Binding& requireBinding(const std::string& name) = 0;
|
|
||||||
|
|
||||||
virtual bool pressed(keycode keycode) const = 0;
|
virtual bool pressed(keycode keycode) const = 0;
|
||||||
virtual bool jpressed(keycode keycode) const = 0;
|
virtual bool jpressed(keycode keycode) const = 0;
|
||||||
|
|
||||||
@ -237,14 +267,18 @@ public:
|
|||||||
|
|
||||||
virtual CursorState getCursor() const = 0;
|
virtual CursorState getCursor() const = 0;
|
||||||
|
|
||||||
|
virtual void toggleCursor() = 0;
|
||||||
|
|
||||||
virtual Bindings& getBindings() = 0;
|
virtual Bindings& getBindings() = 0;
|
||||||
|
|
||||||
virtual const Bindings& getBindings() const = 0;
|
virtual const Bindings& getBindings() const = 0;
|
||||||
|
|
||||||
virtual observer_handler addKeyCallback(keycode key, KeyCallback callback) = 0;
|
virtual observer_handler addKeyCallback(keycode key, KeyCallback callback) = 0;
|
||||||
|
|
||||||
|
virtual const std::vector<keycode>& getPressedKeys() const = 0;
|
||||||
|
virtual const std::vector<uint>& getCodepoints() const = 0;
|
||||||
|
|
||||||
observer_handler addCallback(const std::string& name, KeyCallback callback) {
|
observer_handler addCallback(const std::string& name, KeyCallback callback) {
|
||||||
return requireBinding(name).onactived.add(callback);
|
return getBindings().require(name).onactived.add(callback);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user