simplified and cleaned up new input binding implementation

This commit is contained in:
Noel Berry 2021-03-20 21:16:36 -07:00
parent 3f07c03fa5
commit f3bbda5f6c
4 changed files with 176 additions and 171 deletions

View File

@ -6,60 +6,48 @@
namespace Blah namespace Blah
{ {
// Represents a Controller Trigger or a single direction of a Controller Axis.
// Used in the Binding implementation.
struct BoundTrigger
{
// Controller Index we're bound to
int controller = 0;
// The Axis we're bound to
Axis axis = Axis::None;
// Minimum value of the axis
float threshold = 0.01f;
// requires a positive value
// otherwise requires a negative value
bool positive = true;
BoundTrigger() = default;
BoundTrigger(Axis axis);
BoundTrigger(int controller, Axis axis, float threshold, bool positive);
bool is_down(float axis_value) const;
// helper functions for frequent use cases
static BoundTrigger left_stick_left(int controller, float threshold);
static BoundTrigger left_stick_right(int controller, float threshold);
static BoundTrigger left_stick_up(int controller, float threshold);
static BoundTrigger left_stick_down(int controller, float threshold);
static BoundTrigger right_stick_left(int controller, float threshold);
static BoundTrigger right_stick_right(int controller, float threshold);
static BoundTrigger right_stick_up(int controller, float threshold);
static BoundTrigger right_stick_down(int controller, float threshold);
static BoundTrigger left_trigger(int controller, float threshold);
static BoundTrigger right_trigger(int controller, float threshold);
};
struct BoundButton
{
// Controller Index we're bound to
int controller = 0;
// Button we're bound to
Button button = Button::None;
BoundButton() = default;
BoundButton(Button button);
BoundButton(int controller, Button button);
};
// Single input Binding // Single input Binding
class Binding class Binding
{ {
public: public:
// Represents a Controller Trigger or a single direction of a Controller Axis.
struct TriggerBind
{
// Controller Index we're bound to
int controller = 0;
// The Axis we're bound to
Axis axis = Axis::None;
// Minimum value of the axis
float threshold = 0.01f;
// requires a positive value
// otherwise requires a negative value
bool positive = true;
TriggerBind() = default;
TriggerBind(Axis axis);
TriggerBind(int controller, Axis axis, float threshold, bool positive);
bool is_down(float axis_value) const;
};
// Represents a Controller Button.
struct ButtonBind
{
// Controller Index we're bound to
int controller = 0;
// Button we're bound to
Button button = Button::None;
ButtonBind() = default;
ButtonBind(Button button);
ButtonBind(int controller, Button button);
};
// Input Buffer for press events // Input Buffer for press events
float press_buffer = 0; float press_buffer = 0;
@ -68,16 +56,31 @@ namespace Blah
// List of bound Keys // List of bound Keys
StackVector<Key, 16> keys; StackVector<Key, 16> keys;
// List of bound Buttons // List of bound Buttons
StackVector<BoundButton, 16> buttons; StackVector<ButtonBind, 16> buttons;
// List of bound Triggers / Axis // List of bound Triggers / Axis
StackVector<BoundTrigger, 16> triggers; StackVector<TriggerBind, 16> triggers;
// List of bound Mouse buttons // List of bound Mouse buttons
StackVector<MouseButton, 16> mouse; StackVector<MouseButton, 16> mouse;
Binding() = default;
Binding(float press_buffer)
: press_buffer(press_buffer)
{
}
template<typename ... Args>
Binding(float press_buffer, const Args&... args)
: press_buffer(press_buffer)
{
add(args...);
}
// if the binding has been pressed // if the binding has been pressed
bool pressed() const; bool pressed() const;
@ -106,27 +109,34 @@ namespace Blah
void consume_release(); void consume_release();
// adds a key to the binding // adds a key to the binding
void add(Key key); Binding& add(Key key);
// adds a button to the binding // adds a button to the binding
void add(BoundButton button); Binding& add(ButtonBind button);
// adds an trigger to the binding // adds an trigger to the binding
void add(BoundTrigger trigger); Binding& add(TriggerBind trigger);
// adds a mouse button to the binding // adds a mouse button to the binding
void add(MouseButton mouse); Binding& add(MouseButton mouse);
// adds an input to the binding // adds an input to the binding
template<typename T, typename T2, typename ... Args> template<typename T, typename T2, typename ... Args>
void add(T first, T2 second, const Args&... args) Binding& add(T first, T2 second, const Args&... args)
{ {
add(first); add(first);
add(second, args...); add(second, args...);
return *this;
} }
// adds the left trigger to the binding
Binding& add_left_trigger(int controller, float threshold);
// adds the right trigger to the binding
Binding& add_right_trigger(int controller, float threshold);
// assigns all the bindings to the specific controller // assigns all the bindings to the specific controller
void set_controller(int index); Binding& set_controller(int index);
// removes all bindings // removes all bindings
void clear(); void clear();
@ -169,6 +179,14 @@ namespace Blah
// How to handle overlaps (ex. Left and Right are both held) // How to handle overlaps (ex. Left and Right are both held)
Overlap overlap = Overlap::Newer; Overlap overlap = Overlap::Newer;
AxisBinding() = default;
AxisBinding(const Binding& negative, const Binding& positive, Overlap overlap = Overlap::Newer)
: negative(negative)
, positive(positive)
, overlap(overlap)
{}
// Current Value from -1 to 1 // Current Value from -1 to 1
float value() const; float value() const;
@ -186,20 +204,21 @@ namespace Blah
// Adds a negative & positive binding pair // Adds a negative & positive binding pair
template<typename NegativeT, typename PositiveT> template<typename NegativeT, typename PositiveT>
void add(NegativeT negative, PositiveT positive) AxisBinding& add(NegativeT negative, PositiveT positive)
{ {
this->negative.add(negative); this->negative.add(negative);
this->positive.add(positive); this->positive.add(positive);
return *this;
} }
// Adds a Stick binding // Adds a Stick binding
void add_left_stick_x(int controller, float threshold); AxisBinding& add_left_stick_x(int controller, float threshold);
void add_left_stick_y(int controller, float threshold); AxisBinding& add_left_stick_y(int controller, float threshold);
void add_right_stick_x(int controller, float threshold); AxisBinding& add_right_stick_x(int controller, float threshold);
void add_right_stick_y(int controller, float threshold); AxisBinding& add_right_stick_y(int controller, float threshold);
// assigns all the bindings to the specific controller // assigns all the bindings to the specific controller
void set_controller(int index); AxisBinding& set_controller(int index);
// Clears all Bindings // Clears all Bindings
void clear(); void clear();
@ -209,15 +228,23 @@ namespace Blah
{ {
public: public:
// An optional threshold for circular thresholds
float round_threshold = 0.0f;
// X Axis Binding // X Axis Binding
AxisBinding x; AxisBinding x;
// Y Axis Binding // Y Axis Binding
AxisBinding y; AxisBinding y;
// An optional threshold for circular thresholds
float round_threshold = 0.0f;
StickBinding() = default;
StickBinding(const AxisBinding& x, const AxisBinding& y, float round_threshold = 0)
: x(x)
, y(y)
, round_threshold(round_threshold)
{}
// Current Value, -1 to 1 // Current Value, -1 to 1
Vec2 value() const; Vec2 value() const;
@ -235,25 +262,26 @@ namespace Blah
// Adds directional bindings // Adds directional bindings
template<typename LeftT, typename RightT, typename UpT, typename DownT> template<typename LeftT, typename RightT, typename UpT, typename DownT>
void add(LeftT left, RightT right, UpT up, DownT down) StickBinding& add(LeftT left, RightT right, UpT up, DownT down)
{ {
x.negative.add(left); x.negative.add(left);
x.positive.add(right); x.positive.add(right);
y.negative.add(up); y.negative.add(up);
y.positive.add(down); y.positive.add(down);
return *this;
} }
// Adds the dpad binding // Adds the dpad binding
void add_dpad(int controller); StickBinding& add_dpad(int controller);
// Adds the left stick binding // Adds the left stick binding
void add_left_stick(int controller, float threshold); StickBinding& add_left_stick(int controller, float threshold);
// Adds the right stick binding // Adds the right stick binding
void add_right_stick(int controller, float threshold); StickBinding& add_right_stick(int controller, float threshold);
// assigns all the bindings to the specific controller // assigns all the bindings to the specific controller
void set_controller(int index); StickBinding& set_controller(int index);
// Clears all the bindings // Clears all the bindings
void clear(); void clear();

View File

@ -17,13 +17,13 @@ namespace Blah
{ {
public: public:
// registers a new binding // registers a new binding
static BindingRef register_binding(); static BindingRef register_binding(const Binding& binding = Binding());
// registers a new axis binding // registers a new axis binding
static AxisBindingRef register_axis(); static AxisBindingRef register_axis(const AxisBinding& binding = AxisBinding());
// registers a new stick binding // registers a new stick binding
static StickBindingRef register_stick(); static StickBindingRef register_stick(const StickBinding& binding = StickBinding());
// updates all the bindings. This is called // updates all the bindings. This is called
// automatically by the App loop. // automatically by the App loop.

View File

@ -4,19 +4,19 @@
using namespace Blah; using namespace Blah;
BoundTrigger::BoundTrigger(Axis axis) Binding::TriggerBind::TriggerBind(Axis axis)
: axis(axis) : axis(axis)
{ {
} }
BoundTrigger::BoundTrigger(int controller, Axis axis, float threshold, bool positive) Binding::TriggerBind::TriggerBind(int controller, Axis axis, float threshold, bool positive)
: controller(controller), axis(axis), threshold(threshold), positive(positive) : controller(controller), axis(axis), threshold(threshold), positive(positive)
{ {
} }
bool BoundTrigger::is_down(float axis_value) const bool Binding::TriggerBind::is_down(float axis_value) const
{ {
if ((axis_value > 0 && positive) || (axis_value < 0 && !positive)) if ((axis_value > 0 && positive) || (axis_value < 0 && !positive))
{ {
@ -27,60 +27,10 @@ bool BoundTrigger::is_down(float axis_value) const
return false; return false;
} }
BoundTrigger BoundTrigger::left_stick_left(int controller, float threshold) Binding::ButtonBind::ButtonBind(Button button)
{
return BoundTrigger(controller, Axis::LeftX, threshold, false);
}
BoundTrigger BoundTrigger::left_stick_right(int controller, float threshold)
{
return BoundTrigger(controller, Axis::LeftX, threshold, true);
}
BoundTrigger BoundTrigger::left_stick_up(int controller, float threshold)
{
return BoundTrigger(controller, Axis::LeftY, threshold, false);
}
BoundTrigger BoundTrigger::left_stick_down(int controller, float threshold)
{
return BoundTrigger(controller, Axis::LeftY, threshold, true);
}
BoundTrigger BoundTrigger::right_stick_left(int controller, float threshold)
{
return BoundTrigger(controller, Axis::RightX, threshold, false);
}
BoundTrigger BoundTrigger::right_stick_right(int controller, float threshold)
{
return BoundTrigger(controller, Axis::RightX, threshold, true);
}
BoundTrigger BoundTrigger::right_stick_up(int controller, float threshold)
{
return BoundTrigger(controller, Axis::RightY, threshold, false);
}
BoundTrigger BoundTrigger::right_stick_down(int controller, float threshold)
{
return BoundTrigger(controller, Axis::RightY, threshold, true);
}
BoundTrigger BoundTrigger::left_trigger(int controller, float threshold)
{
return BoundTrigger(controller, Axis::LeftTrigger, threshold, true);
}
BoundTrigger BoundTrigger::right_trigger(int controller, float threshold)
{
return BoundTrigger(controller, Axis::RightTrigger, threshold, true);
}
BoundButton::BoundButton(Button button)
: button(button) {} : button(button) {}
BoundButton::BoundButton(int controller, Button button) Binding::ButtonBind::ButtonBind(int controller, Button button)
: controller(controller), button(button) {} : controller(controller), button(button) {}
bool Binding::pressed() const bool Binding::pressed() const
@ -167,32 +117,50 @@ void Binding::consume_release()
m_last_release_time = -1; m_last_release_time = -1;
} }
void Binding::add(Key key) Binding& Binding::add(Key key)
{ {
keys.push_back(key); keys.push_back(key);
return *this;
} }
void Binding::add(BoundButton button) Binding& Binding::add(ButtonBind button)
{ {
buttons.push_back(button); buttons.push_back(button);
return *this;
} }
void Binding::add(BoundTrigger trigger) Binding& Binding::add(TriggerBind trigger)
{ {
triggers.push_back(trigger); triggers.push_back(trigger);
return *this;
} }
void Binding::add(MouseButton button) Binding& Binding::add(MouseButton button)
{ {
mouse.push_back(button); mouse.push_back(button);
return *this;
} }
void Binding::set_controller(int index) Binding& Binding::add_left_trigger(int controller, float threshold)
{
triggers.push_back(TriggerBind(controller, Axis::LeftTrigger, threshold, true));
return *this;
}
Binding& Binding::add_right_trigger(int controller, float threshold)
{
triggers.push_back(TriggerBind(controller, Axis::RightTrigger, threshold, true));
return *this;
}
Binding& Binding::set_controller(int index)
{ {
for (auto& it : buttons) for (auto& it : buttons)
it.controller = index; it.controller = index;
for (auto& it : triggers) for (auto& it : triggers)
it.controller = index; it.controller = index;
return *this;
} }
void Binding::clear() void Binding::clear()
@ -325,7 +293,7 @@ float Binding::get_value() const
highest = mapped_value; highest = mapped_value;
} }
} }
return highest; return highest;
} }
@ -333,7 +301,7 @@ float AxisBinding::value() const
{ {
float neg = negative.value(); float neg = negative.value();
float pos = positive.value(); float pos = positive.value();
// neither are down // neither are down
if (neg <= 0 && pos <= 0) if (neg <= 0 && pos <= 0)
return 0; return 0;
@ -365,7 +333,7 @@ float AxisBinding::value() const
if (negative.timestamp() > positive.timestamp()) if (negative.timestamp() > positive.timestamp())
return -neg; return -neg;
else else
return pos; return pos;
} }
int AxisBinding::sign() const int AxisBinding::sign() const
@ -391,34 +359,39 @@ void AxisBinding::consume_release()
positive.consume_release(); positive.consume_release();
} }
void AxisBinding::add_left_stick_x(int controller, float threshold) AxisBinding& AxisBinding::add_left_stick_x(int controller, float threshold)
{ {
negative.add(BoundTrigger::left_stick_left(controller, threshold)); negative.add(Binding::TriggerBind(controller, Axis::LeftX, threshold, false));
positive.add(BoundTrigger::left_stick_right(controller, threshold)); positive.add(Binding::TriggerBind(controller, Axis::LeftX, threshold, true));
return *this;
} }
void AxisBinding::add_left_stick_y(int controller, float threshold) AxisBinding& AxisBinding::add_left_stick_y(int controller, float threshold)
{ {
negative.add(BoundTrigger::left_stick_up(controller, threshold)); negative.add(Binding::TriggerBind(controller, Axis::LeftY, threshold, false));
positive.add(BoundTrigger::left_stick_down(controller, threshold)); positive.add(Binding::TriggerBind(controller, Axis::LeftY, threshold, true));
return *this;
} }
void AxisBinding::add_right_stick_x(int controller, float threshold) AxisBinding& AxisBinding::add_right_stick_x(int controller, float threshold)
{ {
negative.add(BoundTrigger::right_stick_left(controller, threshold)); negative.add(Binding::TriggerBind(controller, Axis::RightX, threshold, false));
positive.add(BoundTrigger::right_stick_right(controller, threshold)); positive.add(Binding::TriggerBind(controller, Axis::RightX, threshold, true));
return *this;
} }
void AxisBinding::add_right_stick_y(int controller, float threshold) AxisBinding& AxisBinding::add_right_stick_y(int controller, float threshold)
{ {
negative.add(BoundTrigger::right_stick_up(controller, threshold)); negative.add(Binding::TriggerBind(controller, Axis::RightY, threshold, false));
positive.add(BoundTrigger::right_stick_down(controller, threshold)); positive.add(Binding::TriggerBind(controller, Axis::RightY, threshold, true));
return *this;
} }
void AxisBinding::set_controller(int index) AxisBinding& AxisBinding::set_controller(int index)
{ {
negative.set_controller(index); negative.set_controller(index);
positive.set_controller(index); positive.set_controller(index);
return *this;
} }
void AxisBinding::clear() void AxisBinding::clear()
@ -459,30 +432,34 @@ void StickBinding::consume_release()
y.consume_release(); y.consume_release();
} }
void StickBinding::add_dpad(int controller) StickBinding& StickBinding::add_dpad(int controller)
{ {
x.negative.add(BoundButton(controller, Button::Left)); x.negative.add(Binding::ButtonBind(controller, Button::Left));
x.positive.add(BoundButton(controller, Button::Right)); x.positive.add(Binding::ButtonBind(controller, Button::Right));
y.negative.add(BoundButton(controller, Button::Up)); y.negative.add(Binding::ButtonBind(controller, Button::Up));
y.positive.add(BoundButton(controller, Button::Down)); y.positive.add(Binding::ButtonBind(controller, Button::Down));
return *this;
} }
void StickBinding::add_left_stick(int controller, float threshold) StickBinding& StickBinding::add_left_stick(int controller, float threshold)
{ {
x.add_left_stick_x(controller, threshold); x.add_left_stick_x(controller, threshold);
y.add_left_stick_y(controller, threshold); y.add_left_stick_y(controller, threshold);
return *this;
} }
void StickBinding::add_right_stick(int controller, float threshold) StickBinding& StickBinding::add_right_stick(int controller, float threshold)
{ {
x.add_right_stick_x(controller, threshold); x.add_right_stick_x(controller, threshold);
y.add_right_stick_y(controller, threshold); y.add_right_stick_y(controller, threshold);
return *this;
} }
void StickBinding::set_controller(int index) StickBinding& StickBinding::set_controller(int index)
{ {
x.set_controller(index); x.set_controller(index);
y.set_controller(index); y.set_controller(index);
return *this;
} }
void StickBinding::clear() void StickBinding::clear()

View File

@ -6,25 +6,25 @@ Vector<std::weak_ptr<Binding>> BindingRegistry::bindings;
Vector<std::weak_ptr<AxisBinding>> BindingRegistry::axes; Vector<std::weak_ptr<AxisBinding>> BindingRegistry::axes;
Vector<std::weak_ptr<StickBinding>> BindingRegistry::sticks; Vector<std::weak_ptr<StickBinding>> BindingRegistry::sticks;
BindingRef BindingRegistry::register_binding() BindingRef BindingRegistry::register_binding(const Binding& binding)
{ {
auto binding = std::make_shared<Binding>(); auto result = std::make_shared<Binding>(binding);
bindings.push_back(std::weak_ptr<Binding>(binding)); bindings.push_back(std::weak_ptr<Binding>(result));
return binding; return result;
} }
AxisBindingRef BindingRegistry::register_axis() AxisBindingRef BindingRegistry::register_axis(const AxisBinding& binding)
{ {
auto binding = std::make_shared<AxisBinding>(); auto result = std::make_shared<AxisBinding>(binding);
axes.push_back(std::weak_ptr<AxisBinding>(binding)); axes.push_back(std::weak_ptr<AxisBinding>(result));
return binding; return result;
} }
StickBindingRef BindingRegistry::register_stick() StickBindingRef BindingRegistry::register_stick(const StickBinding& binding)
{ {
auto binding = std::make_shared<StickBinding>(); auto result = std::make_shared<StickBinding>(binding);
sticks.push_back(std::weak_ptr<StickBinding>(binding)); sticks.push_back(std::weak_ptr<StickBinding>(result));
return binding; return result;
} }
void BindingRegistry::update() void BindingRegistry::update()