#include "player_input.hpp" #include "godot_macros.h" #include "godot_cpp/classes/input.hpp" #include "godot_cpp/classes/input_event.hpp" #include "godot_cpp/classes/input_event_mouse_motion.hpp" #include namespace godot { void PlayerInput::_bind_methods() {} PlayerInput::Listener::Listener(String positive, String negative, Node *object, String method) : actionNegative{negative} , actionPositive{positive} , methodName{method} , object{object} , isMouseEvent{positive.begins_with("_mouse_") || negative.begins_with("_mouse_")} {} float PlayerInput::Listener::evaluate_event(Ref const &event, String const &action) { Input *input = Input::get_singleton(); if(!action.begins_with("_mouse_")) { return float(input->is_action_pressed(action)); } else { InputEventMouseMotion *motion = Object::cast_to(*event); if(motion == nullptr) return 0.f; if(action.ends_with("_up") || action.ends_with("_right")) { return motion->get_relative().x; } if(action.ends_with("_right") || action.ends_with("_left")) { return motion->get_relative().y; } } return 0.f; } bool PlayerInput::Listener::has_changed(Ref const &event) { return ( (!event->is_class("InputEventMouseMotion") || this->isMouseEvent ) || event->is_action(this->actionNegative) || event->is_action(this->actionPositive) ); } float PlayerInput::Listener::evaluate(Ref const &event) { float positive = PlayerInput::Listener::evaluate_event(event, this->actionPositive); float negative = PlayerInput::Listener::evaluate_event(event, this->actionNegative); float newest = positive - negative; if(lastCached != newest) this->object->call(this->methodName, event, newest); return (lastCached = newest); } bool PlayerInput::Listener::operator==(godot::PlayerInput::Listener const& b) { return this->methodName == b.methodName && this->object == b.object && this->actionNegative == b.actionNegative && this->actionPositive == b.actionPositive; } void PlayerInput::_unhandled_input(Ref const &event) { GDGAMEONLY(); for(Listener& listener: this->listeners) { if(listener.has_changed(event)) { listener.evaluate(event); } } } void PlayerInput::listen_to(Listener const& listener) { this->listeners.push_back(listener); } void PlayerInput::stop_listening(Node *node) { for(size_t i = 0; i < this->listeners.size(); ++i) { Listener& l = this->listeners.at(i); if(l.object == node) { this->listeners.erase(this->listeners.begin() + i); i--; } } } void PlayerInput::stop_listening(Listener const& listener) { std::vector::iterator itr = std::find(this->listeners.begin(), this->listeners.end(), listener); if(itr != this->listeners.end()) this->listeners.erase(itr); } }