feat: integrated input

main
Sara 2025-01-09 21:56:28 +01:00
parent d4a436da2f
commit 1d7c318a3d
5 changed files with 49 additions and 22 deletions

View File

@ -123,8 +123,10 @@ void CanvasEngine::process_event(SDL_Event const &evt) {
this->request_close(); this->request_close();
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
this->input_map.process_event(evt);
break; break;
case SDL_KEYUP: case SDL_KEYUP:
this->input_map.process_event(evt);
break; break;
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
this->draw(render); this->draw(render);

View File

@ -1,7 +1,11 @@
#include "input_effects.hpp" #include "input_effects.hpp"
namespace ce { namespace ce {
bool GamepadButton::evaluate(SDL_Event const &evt, InputValue &value) const { GamepadButton::GamepadButton(SDL_JoystickID device, SDL_GameControllerButton button)
: which{device}
, button{button} {}
bool GamepadButton::evaluate(SDL_Event const &evt, InputValue &value) {
switch(evt.type) { switch(evt.type) {
case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONDOWN:
if(this->button == evt.cbutton.button && this->which == evt.cbutton.which) { if(this->button == evt.cbutton.button && this->which == evt.cbutton.which) {
@ -20,7 +24,11 @@ bool GamepadButton::evaluate(SDL_Event const &evt, InputValue &value) const {
return false; return false;
} }
bool GamepadAxis::evaluate(SDL_Event const &evt, InputValue &value) const { GamepadAxis::GamepadAxis(SDL_JoystickID device, SDL_GameControllerAxis axis)
: which{device}
, axis{axis} {}
bool GamepadAxis::evaluate(SDL_Event const &evt, InputValue &value) {
switch(evt.type) { switch(evt.type) {
case SDL_CONTROLLERAXISMOTION: case SDL_CONTROLLERAXISMOTION:
if(evt.caxis.axis == this->axis && evt.caxis.which == this->which) { if(evt.caxis.axis == this->axis && evt.caxis.which == this->which) {
@ -33,7 +41,10 @@ bool GamepadAxis::evaluate(SDL_Event const &evt, InputValue &value) const {
return false; return false;
} }
bool KeyboardScancode::evaluate(SDL_Event const &evt, InputValue &value) const { KeyboardScancode::KeyboardScancode(SDL_Scancode code)
: code{code} {}
bool KeyboardScancode::evaluate(SDL_Event const &evt, InputValue &value) {
switch(evt.type) { switch(evt.type) {
case SDL_KEYDOWN: case SDL_KEYDOWN:
if(evt.key.keysym.scancode == this->code) { if(evt.key.keysym.scancode == this->code) {
@ -52,7 +63,10 @@ bool KeyboardScancode::evaluate(SDL_Event const &evt, InputValue &value) const {
return false; return false;
} }
bool KeyboardKey::evaluate(SDL_Event const &evt, InputValue &value) const { KeyboardKey::KeyboardKey(SDL_Keycode code)
: key{code} {}
bool KeyboardKey::evaluate(SDL_Event const &evt, InputValue &value) {
switch(evt.type) { switch(evt.type) {
case SDL_KEYDOWN: case SDL_KEYDOWN:
if(evt.key.keysym.sym == this->key) { if(evt.key.keysym.sym == this->key) {
@ -71,10 +85,12 @@ bool KeyboardKey::evaluate(SDL_Event const &evt, InputValue &value) const {
return false; return false;
} }
bool ButtonAxis::evaluate(SDL_Event const &evt, InputValue &value) const { ButtonAxis::ButtonAxis(InputEffect *negative, InputEffect *positive)
: neg{negative}
, pos{positive} {}
bool ButtonAxis::evaluate(SDL_Event const &evt, InputValue &value) {
bool changed{false}; bool changed{false};
InputValue neg_value{0.f};
InputValue pos_value{0.f};
if(neg != nullptr) changed |= neg->evaluate(evt, neg_value); if(neg != nullptr) changed |= neg->evaluate(evt, neg_value);
if(pos != nullptr) changed |= pos->evaluate(evt, pos_value); if(pos != nullptr) changed |= pos->evaluate(evt, pos_value);
if(changed && neg_value.is<float>() && pos_value.is<float>()) { if(changed && neg_value.is<float>() && pos_value.is<float>()) {

View File

@ -10,40 +10,42 @@ struct InputEffect {
typedef std::unique_ptr<InputEffect> Ptr; typedef std::unique_ptr<InputEffect> Ptr;
virtual ~InputEffect() = default; virtual ~InputEffect() = default;
template<class Effect, typename... Param> Ptr make(Param... p); template<class Effect, typename... Param> Ptr make(Param... p);
virtual bool evaluate(SDL_Event const &evt, InputValue &value) const = 0; virtual bool evaluate(SDL_Event const &evt, InputValue &value) = 0;
}; };
struct GamepadButton : InputEffect { struct GamepadButton : InputEffect {
GamepadButton(SDL_JoystickID device, SDL_GameControllerButton button); GamepadButton(SDL_JoystickID device, SDL_GameControllerButton button);
SDL_JoystickID which{0}; SDL_JoystickID which{0};
SDL_GameControllerButton button{SDL_CONTROLLER_BUTTON_A}; SDL_GameControllerButton button{SDL_CONTROLLER_BUTTON_A};
virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; virtual bool evaluate(SDL_Event const &evt, InputValue &value) override;
}; };
struct GamepadAxis : InputEffect { struct GamepadAxis : InputEffect {
GamepadAxis(SDL_JoystickID device, SDL_GameControllerAxis axis); GamepadAxis(SDL_JoystickID device, SDL_GameControllerAxis axis);
SDL_JoystickID which{0}; SDL_JoystickID which{0};
SDL_GameControllerAxis axis{SDL_CONTROLLER_AXIS_LEFTX}; SDL_GameControllerAxis axis{SDL_CONTROLLER_AXIS_LEFTX};
virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; virtual bool evaluate(SDL_Event const &evt, InputValue &value) override;
}; };
struct KeyboardScancode : InputEffect { struct KeyboardScancode : InputEffect {
KeyboardScancode(SDL_Scancode code); KeyboardScancode(SDL_Scancode code);
SDL_Scancode code{SDL_SCANCODE_0}; SDL_Scancode code{SDL_SCANCODE_0};
virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; virtual bool evaluate(SDL_Event const &evt, InputValue &value) override;
}; };
struct KeyboardKey : InputEffect { struct KeyboardKey : InputEffect {
KeyboardKey(SDL_Keycode code); KeyboardKey(SDL_Keycode code);
SDL_Keycode key{SDLK_KP_0}; SDL_Keycode key{SDLK_KP_0};
virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; virtual bool evaluate(SDL_Event const &evt, InputValue &value) override;
}; };
struct ButtonAxis : InputEffect { struct ButtonAxis : InputEffect {
ButtonAxis(InputEffect::Ptr &negative, InputEffect::Ptr &positive); ButtonAxis(InputEffect *negative, InputEffect *positive);
InputEffect::Ptr neg{}; InputEffect::Ptr neg{};
InputValue neg_value{0.f};
InputEffect::Ptr pos{}; InputEffect::Ptr pos{};
virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; InputValue pos_value{0.f};
virtual bool evaluate(SDL_Event const &evt, InputValue &value) override;
}; };
template <class Effect, typename... Param> InputEffect::Ptr InputEffect::make(Param... p) { template <class Effect, typename... Param> InputEffect::Ptr InputEffect::make(Param... p) {

View File

@ -7,9 +7,9 @@ InputAction::InputAction(InputEffect::Ptr &effect) {
this->effects.push_back(std::move(effect)); this->effects.push_back(std::move(effect));
} }
InputAction::InputAction(std::vector<InputEffect::Ptr> &effects) { InputAction::InputAction(std::vector<InputEffect*> &effects) {
for(InputEffect::Ptr &effect : effects) for(InputEffect* effect : effects)
this->effects.push_back(std::move(effect)); this->effects.push_back(std::move(std::unique_ptr<InputEffect>(effect)));
} }
void InputAction::process_event(SDL_Event const &evt) { void InputAction::process_event(SDL_Event const &evt) {
@ -23,8 +23,14 @@ void InputAction::process_event(SDL_Event const &evt) {
this->changed.invoke(value); this->changed.invoke(value);
} }
void InputMap::bind_input(std::string const &name, std::vector<InputEffect::Ptr> &effects) { InputAction &InputMap::bind_input(std::string const &name, std::vector<InputEffect*> &&effects) {
InputAction action{InputAction(effects)}; this->bindings.insert({name, InputAction(effects)});
this->bindings.insert({name, std::move(action)}); return this->bindings[name];
}
void InputMap::process_event(SDL_Event const &evt) {
for(std::pair<std::string const, InputAction> &binding : this->bindings) {
binding.second.process_event(evt);
}
} }
} }

View File

@ -25,7 +25,7 @@ public:
Signal<InputValue> changed{}; Signal<InputValue> changed{};
InputAction() = default; InputAction() = default;
InputAction(InputEffect::Ptr &effect); InputAction(InputEffect::Ptr &effect);
InputAction(std::vector<InputEffect::Ptr> &effects); InputAction(std::vector<InputEffect*> &effects);
void process_event(SDL_Event const &evt); //!< process an incoming OS event void process_event(SDL_Event const &evt); //!< process an incoming OS event
@ -37,8 +37,9 @@ public:
class InputMap { class InputMap {
std::map<std::string, InputAction> bindings{}; std::map<std::string, InputAction> bindings{};
public: public:
void bind_input(std::string const &name, std::vector<InputEffect::Ptr> &binds); InputAction &bind_input(std::string const &name, std::vector<InputEffect*> &&binds);
InputAction &get_action(std::string const &action_id); InputAction &get_action(std::string const &action_id);
void process_event(SDL_Event const &evt);
}; };
template <class Effect> Effect *InputAction::get_effect_of_type() { template <class Effect> Effect *InputAction::get_effect_of_type() {