godot-cpp-utils/player_input.hpp

80 lines
3.1 KiB
C++
Raw Normal View History

2024-02-13 13:59:01 +00:00
#ifndef PLAYER_INPUT_HPP
#define PLAYER_INPUT_HPP
#include <vector>
#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"
namespace godot {
class PlayerInput : public Node {
GDCLASS(PlayerInput, Node)
static void _bind_methods();
public:
// 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 {
friend class PlayerInput;
private:
// the two actions, evaluated as positive - negative
2024-02-13 13:59:01 +00:00
String actionNegative{""};
String actionPositive{""};
// 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};
// name of the method to call, expected signature is void(Ref<InputEvent>, float)
2024-02-13 13:59:01 +00:00
String methodName{""};
// pointer to the node to call methodName on
Node *object{nullptr};
// if either actionNegative or actionPositive is a _mouse_ event this will be true
bool isMouseEvent{false};
2024-02-13 13:59:01 +00:00
public:
2024-02-13 13:59:01 +00:00
Listener(String positive, String negative, Node *object, String method);
Listener(String action, Node *object, String method);
// 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);
// 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-13 13:59:01 +00:00
bool operator==(godot::PlayerInput::Listener const& b);
};
private:
// 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:
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;
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