- Added a method to retrieve actions and axes from a resource by name.

- InputResources call their signals with default values before disconnecting.
This commit is contained in:
2026-08-19 19:01:52 -04:00
parent fb0293ac14
commit f615cddd43
3 changed files with 119 additions and 75 deletions
+30 -1
View File
@@ -67,9 +67,38 @@ void InputResource::update_axes_mouse_event(const Ref<InputEventMouseMotion> eve
const InputAxis *axis = cast_to<InputAxis>(this->input_axes[i]); const InputAxis *axis = cast_to<InputAxis>(this->input_axes[i]);
const StringName signal = StringName("_on_") + axis->get_axis_name() + INPUTAXIS_TWO_DIMENSIONAL_SUFFIX; const StringName signal = StringName("_on_") + axis->get_axis_name() + INPUTAXIS_TWO_DIMENSIONAL_SUFFIX;
if (axis->get_include_mouse() && this->has_signal(signal)) if (axis->get_include_mouse() && this->has_signal(signal))
this->emit_signal(signal, delta, Vector2(event->get_relative().x, event->get_relative().y) * 0.001 / delta); {
this->emit_signal(signal, delta, event->get_relative() * 0.000001f / delta);
} }
} }
}
Ref<InputAction> InputResource::find_input_action(const StringName &name) const
{
for (uint8_t i = 0; i < this->input_actions.size(); i++)
{
const Ref<InputAction> action = cast_to<InputAction>(this->input_actions[i]);
if (action->get_action_name() == name)
{
return action;
}
}
return nullptr;
}
Ref<InputAxis> InputResource::find_input_axis(const StringName &name) const
{
for (uint8_t i = 0; i < this->input_axes.size(); i++)
{
const Ref<InputAxis> axis = cast_to<InputAxis>(this->input_axes[i]);
if (axis->get_axis_name() == name)
{
return axis;
}
}
return nullptr;
}
Vector3 InputAxis::get_spherical_vector() const Vector3 InputAxis::get_spherical_vector() const
+6 -1
View File
@@ -88,7 +88,6 @@ protected:
ClassDB::bind_method(D_METHOD("is_active"), &InputAction::is_active); ClassDB::bind_method(D_METHOD("is_active"), &InputAction::is_active);
ClassDB::bind_method(D_METHOD("set_active", "active"), &InputAction::set_active); ClassDB::bind_method(D_METHOD("set_active", "active"), &InputAction::set_active);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
} }
}; };
@@ -196,6 +195,9 @@ public:
void set_input_axes(const TypedArray<InputAxis> input_axes) { this->input_axes = input_axes; } void set_input_axes(const TypedArray<InputAxis> input_axes) { this->input_axes = input_axes; }
TypedArray<InputAxis> get_input_axes() const { return this->input_axes; } TypedArray<InputAxis> get_input_axes() const { return this->input_axes; }
Ref<InputAction> find_input_action(const StringName &name) const;
Ref<InputAxis> find_input_axis(const StringName &name) const;
protected: protected:
TypedArray<InputAction> input_actions; TypedArray<InputAction> input_actions;
TypedArray<InputAxis> input_axes; TypedArray<InputAxis> input_axes;
@@ -207,6 +209,9 @@ protected:
{ // input_actions, input_axes { // input_actions, input_axes
ADD_GETTER_SETTER_HINTED(InputResource, input_actions, Variant::ARRAY, PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "InputAction")); ADD_GETTER_SETTER_HINTED(InputResource, input_actions, Variant::ARRAY, PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "InputAction"));
ADD_GETTER_SETTER_HINTED(InputResource, input_axes, Variant::ARRAY, PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "InputAxis")); ADD_GETTER_SETTER_HINTED(InputResource, input_axes, Variant::ARRAY, PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "InputAxis"));
BIND_METHOD_1PARAM(InputResource, find_input_action, name);
BIND_METHOD_1PARAM(InputResource, find_input_axis, name);
} }
{ // update { // update
+65 -55
View File
@@ -22,29 +22,23 @@ GDSINGLETON_CPP(InputHandler);
void InputHandler::_process(double delta) void InputHandler::_process(double delta)
{ {
for (InputResource *resource : this->active_resources) for (InputResource *resource : this->active_resources)
{
resource->update_axes(delta); resource->update_axes(delta);
} }
}
void InputHandler::_input(const Ref<InputEvent> &event) void InputHandler::_input(const Ref<InputEvent> &event)
{ {
for (InputResource *resource : this->active_resources) for (InputResource *resource : this->active_resources)
{ {
if (event->is_action_type()) if (event->is_action_type())
{
resource->update_buttons(event, this->get_process_delta_time()); resource->update_buttons(event, this->get_process_delta_time());
}
else if (const InputEventMouseMotion *mouse_event = cast_to<InputEventMouseMotion>(event.ptr())) else if (const InputEventMouseMotion *mouse_event = cast_to<InputEventMouseMotion>(event.ptr()))
{ {
const Input *input = Input::get_singleton(); const Input *input = Input::get_singleton();
if (input->get_mouse_mode() != Input::MOUSE_MODE_VISIBLE) if (input->get_mouse_mode() != Input::MOUSE_MODE_VISIBLE)
{
resource->update_axes_mouse_event(event, this->get_process_delta_time()); resource->update_axes_mouse_event(event, this->get_process_delta_time());
} }
} }
} }
}
void InputHandler::add_input_resource(Node *target, InputResource *resource) void InputHandler::add_input_resource(Node *target, InputResource *resource)
{ {
@@ -57,9 +51,7 @@ void InputHandler::add_input_resource(Node *target, InputResource *resource)
if (const InputAction *action = cast_to<InputAction>(input_actions[i])) if (const InputAction *action = cast_to<InputAction>(input_actions[i]))
{ {
if (!input_map->has_action(action->get_action_name())) if (!input_map->has_action(action->get_action_name()))
{
input_map->add_action(action->get_action_name(), action->get_deadzone()); input_map->add_action(action->get_action_name(), action->get_deadzone());
}
for(uint8_t s = 0; s < 2; s++) for(uint8_t s = 0; s < 2; s++)
{ {
@@ -68,9 +60,7 @@ void InputHandler::add_input_resource(Node *target, InputResource *resource)
{ {
const TypedArray<InputEvent> &events = action->get_input_events(); const TypedArray<InputEvent> &events = action->get_input_events();
if (!resource->has_signal(signal_name)) if (!resource->has_signal(signal_name))
{
resource->add_user_signal(signal_name); resource->add_user_signal(signal_name);
}
for (uint8_t e = 0; e < events.size(); e++) for (uint8_t e = 0; e < events.size(); e++)
{ {
const Ref<InputEvent> &event = events[e]; const Ref<InputEvent> &event = events[e];
@@ -91,14 +81,8 @@ void InputHandler::add_input_resource(Node *target, InputResource *resource)
for(uint8_t s = 0; s <= axis_dimensions; s++) for(uint8_t s = 0; s <= axis_dimensions; s++)
{ {
const StringName signal_name = StringName("_on_") + axis->get_axis_name() + this->input_axis_suffixes[s]; const StringName signal_name = StringName("_on_") + axis->get_axis_name() + this->input_axis_suffixes[s];
if (!resource->has_signal(signal_name)) if (!resource->has_signal(signal_name)) resource->add_user_signal(signal_name);
{ if (target->has_method(signal_name)) resource->connect(signal_name, Callable(target, signal_name));
resource->add_user_signal(signal_name);
}
if (target->has_method(signal_name))
{
resource->connect(signal_name, Callable(target, signal_name));
}
} }
const StringName &axis_name = axis->get_axis_name(); const StringName &axis_name = axis->get_axis_name();
@@ -177,6 +161,7 @@ void InputHandler::_enable_mouse_capture()
void InputHandler::remove_input_resource(Node *target, InputResource *resource) void InputHandler::remove_input_resource(Node *target, InputResource *resource)
{ {
Input *input = Input::get_singleton();
InputMap *input_map = InputMap::get_singleton(); InputMap *input_map = InputMap::get_singleton();
const TypedArray<InputAction> &input_actions = resource->get_input_actions(); const TypedArray<InputAction> &input_actions = resource->get_input_actions();
const TypedArray<InputAxis> &input_axes = resource->get_input_axes(); const TypedArray<InputAxis> &input_axes = resource->get_input_axes();
@@ -185,15 +170,16 @@ void InputHandler::remove_input_resource(Node *target, InputResource *resource)
{ {
if (const InputAction *action = cast_to<InputAction>(input_actions[i])) if (const InputAction *action = cast_to<InputAction>(input_actions[i]))
{ {
input->action_release(action->get_action_name());
input_map->action_erase_events(action->get_action_name()); input_map->action_erase_events(action->get_action_name());
for(uint8_t s = 0; s < 2; s++)
{ const StringName signal_name_pressed = StringName("_on_") + action->get_action_name() + input_action_suffixes[0];
const StringName signal_name = StringName("_on_") + action->get_action_name() + input_action_suffixes[s]; if (target->has_method(signal_name_pressed)) resource->disconnect(signal_name_pressed, Callable(target, signal_name_pressed));
if (target->has_method(signal_name))
{ const StringName signal_name_released = StringName("_on_") + action->get_action_name() + input_action_suffixes[1];
resource->disconnect(signal_name, Callable(target, signal_name)); const Callable callable_released = Callable(target, signal_name_released);
} callable_released.call();
} if (target->has_method(signal_name_released)) resource->disconnect(signal_name_released, callable_released);
} }
} }
@@ -201,13 +187,28 @@ void InputHandler::remove_input_resource(Node *target, InputResource *resource)
{ {
if (const InputAxis *axis = cast_to<InputAxis>(input_axes[i])) if (const InputAxis *axis = cast_to<InputAxis>(input_axes[i]))
{ {
for(uint8_t s = 0; s < 3; s++) const StringName signal_name_one = StringName("_on_") + axis->get_axis_name() + this->input_axis_suffixes[0];
if (target->has_method(signal_name_one))
{ {
const StringName signal_name = StringName("_on_") + axis->get_axis_name() + this->input_axis_suffixes[s]; if (resource->has_signal(signal_name_one))
if (target->has_method(signal_name)) resource->emit_signal(signal_name_one, this->get_process_delta_time(), 0.0f);
{ resource->disconnect(signal_name_one, Callable(target, signal_name_one));
resource->disconnect(signal_name, Callable(target, signal_name));
} }
const StringName signal_name_two = StringName("_on_") + axis->get_axis_name() + this->input_axis_suffixes[1];
if (target->has_method(signal_name_two))
{
if (resource->has_signal(signal_name_two))
resource->emit_signal(signal_name_two, this->get_process_delta_time(), Vector2(0.0f, 0.0f));
resource->disconnect(signal_name_two, Callable(target, signal_name_two));
}
const StringName signal_name_three = StringName("_on_") + axis->get_axis_name() + this->input_axis_suffixes[2];
if (target->has_method(signal_name_three))
{
if (resource->has_signal(signal_name_three))
resource->emit_signal(signal_name_three, this->get_process_delta_time(), Vector3(0.0f, 0.0f, 0.0f));
resource->disconnect(signal_name_three, Callable(target, signal_name_three));
} }
/* /*
@@ -217,35 +218,44 @@ void InputHandler::remove_input_resource(Node *target, InputResource *resource)
* side effects, but I'm keeping it commented here in case there * side effects, but I'm keeping it commented here in case there
* turns out to be a reason to put it back later. * turns out to be a reason to put it back later.
*/ */
// const StringName &axis_name = axis->get_axis_name(); const StringName &axis_name = axis->get_axis_name();
// const uint8_t &axis_dimensions = axis->get_axis_dimensions(); const uint8_t &axis_dimensions = axis->get_axis_dimensions();
// const float &deadzone = axis->get_deadzone(); const float &deadzone = axis->get_deadzone();
// if (axis_dimensions >= InputAxis::AXIS_DIMENSIONS::ONE) if (axis_dimensions >= InputAxis::AXIS_DIMENSIONS::ONE)
// { {
// const StringName &left_axis_action = axis_name + INPUTAXIS_LEFT_SUFFIX; const StringName &left_axis_action = axis_name + INPUTAXIS_LEFT_SUFFIX;
// const StringName &right_axis_action = axis_name + INPUTAXIS_RIGHT_SUFFIX; const StringName &right_axis_action = axis_name + INPUTAXIS_RIGHT_SUFFIX;
// input_map->action_erase_events(left_axis_action); input->action_release(left_axis_action);
// input_map->action_erase_events(right_axis_action); input->action_release(right_axis_action);
// }
// if (axis_dimensions >= InputAxis::AXIS_DIMENSIONS::TWO) input_map->action_erase_events(left_axis_action);
// { input_map->action_erase_events(right_axis_action);
// const StringName &back_axis_action = axis_name + INPUTAXIS_BACK_SUFFIX; }
// const StringName &forward_axis_action = axis_name + INPUTAXIS_FORWARD_SUFFIX;
// input_map->action_erase_events(back_axis_action); if (axis_dimensions >= InputAxis::AXIS_DIMENSIONS::TWO)
// input_map->action_erase_events(forward_axis_action); {
// } const StringName &back_axis_action = axis_name + INPUTAXIS_BACK_SUFFIX;
const StringName &forward_axis_action = axis_name + INPUTAXIS_FORWARD_SUFFIX;
// if (axis_dimensions >= InputAxis::AXIS_DIMENSIONS::THREE) input->action_release(back_axis_action);
// { input->action_release(forward_axis_action);
// const StringName &down_axis_action = axis_name + INPUTAXIS_DOWN_SUFFIX;
// const StringName &up_axis_action = axis_name + INPUTAXIS_UP_SUFFIX;
// input_map->action_erase_events(down_axis_action); input_map->action_erase_events(back_axis_action);
// input_map->action_erase_events(up_axis_action); input_map->action_erase_events(forward_axis_action);
// } }
if (axis_dimensions >= InputAxis::AXIS_DIMENSIONS::THREE)
{
const StringName &down_axis_action = axis_name + INPUTAXIS_DOWN_SUFFIX;
const StringName &up_axis_action = axis_name + INPUTAXIS_UP_SUFFIX;
input->action_release(down_axis_action);
input->action_release(up_axis_action);
input_map->action_erase_events(down_axis_action);
input_map->action_erase_events(up_axis_action);
}
if (axis->get_include_mouse()) if (axis->get_include_mouse())
{ {