ECSTASY
All in the name
Loading...
Searching...
No Matches
ActionBindings.cpp
Go to the documentation of this file.
1
11
12#include "ActionBindings.hpp"
13#include <iostream>
14#include <regex>
16
18
20{
22 {
23 toml::table table;
24
26 for (ActionBinding action : _bindings) {
28 std::string key = std::string("Action-") + std::to_string(action.actionId);
29 toml::node *nodePtr = table.get(key);
31
33 if (!nodePtr)
34 nodePtr = &table.emplace<toml::array>(key).first->second;
35
36 toml::node &node = *nodePtr;
37 value << action.type << "->";
38 switch (action.type) {
39 case ActionBinding::Type::MouseButton: value << action.mouseButton; break;
40 case ActionBinding::Type::Key: value << action.key; break;
41 case ActionBinding::Type::GamepadButton: value << action.gamepadButton; break;
42 case ActionBinding::Type::GamepadAxis: value << action.gamepadAxis; break;
43 default: continue;
44 }
45 node.as_array()->emplace_back(value.str());
46 }
47
48 return table;
49 }
50
51 bool ActionBindings::load(const toml::table &bindings) noexcept
52 {
53 _bindings.clear();
54 const std::regex reActionName("^Action-([0-9]+)$");
55 const std::regex reActionValue("^(\\w+)->(\\w+)$");
56 std::cmatch match;
57
58 for (auto &&[key, value] : bindings) {
59 if (!std::regex_match(key.data(), match, reActionName)) [[unlikely]] {
60 std::cerr << "Invalid action name." << std::endl;
61 break;
62 }
63
64 Action::Id actionId = std::stoul(match[1].str());
65 if (!value.is_array()) [[unlikely]] {
66 std::cerr << "Action '" << key.data() << "' is not a valid toml array." << std::endl;
67 continue;
68 }
69
70 value.as_array()->for_each([this, &match, &reActionValue, &actionId](auto &&input) {
71 if constexpr (toml::is_string<decltype(input)>) {
72 if (!std::regex_match(input.as_string()->get().data(), match, reActionValue))
73 return;
75
76 std::istringstream ss(match[1].str());
77 ss >> type;
78 ss.clear();
79 ss.str(match[2].str());
80
81 switch (type) {
83 _bindings.emplace_back(
84 actionId, util::serialization::Serializer::deserialize<event::Mouse::Button>(ss));
85 break;
87 _bindings.emplace_back(
88 actionId, util::serialization::Serializer::deserialize<event::Keyboard::Key>(ss));
89 break;
91 _bindings.emplace_back(
92 actionId, util::serialization::Serializer::deserialize<event::Gamepad::Button>(ss));
93 break;
95 _bindings.emplace_back(
96 actionId, util::serialization::Serializer::deserialize<event::Gamepad::Axis>(ss));
97 break;
98 default: break;
99 }
100 // clang-format off
101 }});
102 // clang-format on
103 }
104 return true;
105 }
106
107 bool ActionBindings::contains(ActionBinding binding) const noexcept
108 {
109 return std::find(_bindings.cbegin(), _bindings.cend(), binding) != _bindings.cend();
110 }
111} // namespace ecstasy::integration::user_action
Action binding class, represent a binding between an input and a given action.
@ GamepadButton
The action is bound to a gamepad button state.
@ MouseButton
The action is bound to a mouse button state.
@ Key
The action is bound to a keyboard key state.
@ GamepadAxis
The action is bound to a gamepad axis state.
toml::table dump() const noexcept
Dump the bindings as a toml table.
bool load(const toml::table &bindings) noexcept
Load a given toml table representing a list of bindings.
bool contains(ActionBinding action) const noexcept
Check whether action is contained in the internal ActionBinding vector.
decltype(auto) emplace_back(Args &&... args)
virtual array * as_array() noexcept=0
std::pair< iterator, bool > emplace(KeyType &&key, ValueArgs &&... args)
node * get(std::string_view key) noexcept
T clear(T... args)
T endl(T... args)
T find(T... args)
Event integration.
Definition Event.hpp:25
User action integration.
Definition Action.hpp:18
constexpr bool is_string
T regex_match(T... args)
T stoul(T... args)
T str(T... args)
size_t Id
Action identifier type.
Definition Action.hpp:27
T to_string(T... args)
Serialize and deserialize objects.