2024-02-13 13:59:01 +00:00
|
|
|
#ifndef PLAYER_INPUT_HPP
|
|
|
|
#define PLAYER_INPUT_HPP
|
|
|
|
|
|
|
|
#include <vector>
|
2024-02-19 00:04:14 +00:00
|
|
|
#include <optional>
|
2024-02-13 13:59:01 +00:00
|
|
|
#include "godot_cpp/classes/input.hpp"
|
|
|
|
#include "godot_cpp/classes/input_event.hpp"
|
|
|
|
#include "godot_cpp/classes/node.hpp"
|
2024-04-10 10:44:50 +00:00
|
|
|
#include "godot_cpp/variant/callable.hpp"
|
2024-02-13 13:59:01 +00:00
|
|
|
|
|
|
|
namespace godot {
|
|
|
|
class PlayerInput : public Node {
|
|
|
|
GDCLASS(PlayerInput, Node)
|
|
|
|
static void _bind_methods();
|
|
|
|
public:
|
2024-02-19 00:04:14 +00:00
|
|
|
// a listener is a combination of a positive and negative action and a listener function.
|
|
|
|
// listener functions use godot's Object::call function.
|
|
|
|
// So they require a Node instance and a function name.
|
|
|
|
// The expected signature is void(Ref<InputEvent>, float)
|
|
|
|
// actions can also be "special" actions prefixed with _.
|
|
|
|
// special actions include _mouse_up, _mouse_down, _mouse_left and _mouse_right
|
|
|
|
// which rather than checking action_is_down,
|
|
|
|
// will use PlayerInput::get_last_mouse_motion() to poll the current state.
|
2024-02-13 13:59:01 +00:00
|
|
|
struct Listener {
|
2024-02-13 20:39:50 +00:00
|
|
|
friend class PlayerInput;
|
|
|
|
private:
|
2024-02-19 00:04:14 +00:00
|
|
|
// the two actions, evaluated as positive - negative
|
2024-02-13 13:59:01 +00:00
|
|
|
String actionNegative{""};
|
|
|
|
String actionPositive{""};
|
2024-02-19 00:04:14 +00:00
|
|
|
// the last cached action, if the newest result matches this, the event will be considered
|
|
|
|
// duplicate and ignored (not passed to listener)
|
2024-02-13 13:59:01 +00:00
|
|
|
float lastCached{0.f};
|
2024-04-10 10:44:50 +00:00
|
|
|
Callable callable;
|
2024-02-19 00:04:14 +00:00
|
|
|
// if either actionNegative or actionPositive is a _mouse_ event this will be true
|
2024-02-13 20:39:50 +00:00
|
|
|
bool isMouseEvent{false};
|
2024-02-13 13:59:01 +00:00
|
|
|
|
2024-02-13 20:39:50 +00:00
|
|
|
public:
|
2024-04-10 10:44:50 +00:00
|
|
|
Listener(String positive, String negative, Callable callable);
|
|
|
|
Listener(String action, Callable callable);
|
2024-02-19 00:04:14 +00:00
|
|
|
// evaluate the current state of an action.
|
|
|
|
static std::optional<float> evaluate_action(String const &action);
|
|
|
|
// check if this event has any chance to result in a trigger, does not evaluate the event or
|
|
|
|
// poll current input state
|
2024-02-13 13:59:01 +00:00
|
|
|
bool has_changed(Ref<InputEvent> const &event);
|
2024-02-19 00:04:14 +00:00
|
|
|
// evaluate the event for changes to either actionPositive or actionNegative
|
2024-02-13 13:59:01 +00:00
|
|
|
float evaluate(Ref<InputEvent> const &event);
|
2024-02-19 00:04:14 +00:00
|
|
|
|
2024-02-13 13:59:01 +00:00
|
|
|
bool operator==(godot::PlayerInput::Listener const& b);
|
|
|
|
};
|
|
|
|
private:
|
2024-02-19 00:04:14 +00:00
|
|
|
// the last mouse motion, updated by the primary instance
|
|
|
|
static Vector2 lastMouseMotion;
|
|
|
|
// does a primary instance exist
|
|
|
|
static bool primaryExists;
|
|
|
|
// is this the primary instance
|
|
|
|
// the primary instance is responsible for updating static
|
|
|
|
// variables like lastMouseMotion
|
|
|
|
bool isPrimary{false};
|
|
|
|
|
|
|
|
// current listeners for this instance
|
2024-02-13 13:59:01 +00:00
|
|
|
std::vector<Listener> listeners{};
|
|
|
|
public:
|
2024-02-19 00:04:14 +00:00
|
|
|
static Vector2 get_last_mouse_motion();
|
|
|
|
|
|
|
|
virtual void _enter_tree() override;
|
|
|
|
virtual void _exit_tree() override;
|
2024-02-13 13:59:01 +00:00
|
|
|
virtual void _unhandled_input(Ref<InputEvent> const &event) override;
|
2024-02-19 00:04:14 +00:00
|
|
|
virtual void _process(double deltaTime) override;
|
2024-02-13 13:59:01 +00:00
|
|
|
|
|
|
|
void listen_to(Listener const& listener);
|
|
|
|
void stop_listening(Node *node);
|
|
|
|
void stop_listening(Listener const& listener);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif // !PLAYER_INPUT_HPP
|