mirror of
https://github.com/godotengine/godot.git
synced 2025-02-23 23:15:07 +08:00
Merge pull request #45902 from Calinou/inputmap-nonexistent-suggestions-3.2
Print suggestions when requesting a nonexistent InputMap action (3.2)
This commit is contained in:
commit
83e4e4dc52
@ -55,9 +55,38 @@ void InputMap::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("load_from_globals"), &InputMap::load_from_globals);
|
ClassDB::bind_method(D_METHOD("load_from_globals"), &InputMap::load_from_globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an nonexistent action error message with a suggestion of the closest
|
||||||
|
* matching action name (if possible).
|
||||||
|
*/
|
||||||
|
String InputMap::_suggest_actions(const StringName &p_action) const {
|
||||||
|
|
||||||
|
List<StringName> actions = get_actions();
|
||||||
|
StringName closest_action;
|
||||||
|
float closest_similarity = 0.0;
|
||||||
|
|
||||||
|
// Find the most action with the most similar name.
|
||||||
|
for (List<StringName>::Element *E = actions.front(); E; E = E->next()) {
|
||||||
|
const float similarity = String(E->get()).similarity(p_action);
|
||||||
|
|
||||||
|
if (similarity > closest_similarity) {
|
||||||
|
closest_action = E->get();
|
||||||
|
closest_similarity = similarity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String error_message = vformat("The InputMap action \"%s\" doesn't exist.", p_action);
|
||||||
|
|
||||||
|
if (closest_similarity >= 0.4) {
|
||||||
|
// Only include a suggestion in the error message if it's similar enough.
|
||||||
|
error_message += vformat(" Did you mean \"%s\"?", closest_action);
|
||||||
|
}
|
||||||
|
return error_message;
|
||||||
|
}
|
||||||
|
|
||||||
void InputMap::add_action(const StringName &p_action, float p_deadzone) {
|
void InputMap::add_action(const StringName &p_action, float p_deadzone) {
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(input_map.has(p_action), "InputMap already has action '" + String(p_action) + "'.");
|
ERR_FAIL_COND_MSG(input_map.has(p_action), "InputMap already has action \"" + String(p_action) + "\".");
|
||||||
input_map[p_action] = Action();
|
input_map[p_action] = Action();
|
||||||
static int last_id = 1;
|
static int last_id = 1;
|
||||||
input_map[p_action].id = last_id;
|
input_map[p_action].id = last_id;
|
||||||
@ -67,7 +96,8 @@ void InputMap::add_action(const StringName &p_action, float p_deadzone) {
|
|||||||
|
|
||||||
void InputMap::erase_action(const StringName &p_action) {
|
void InputMap::erase_action(const StringName &p_action) {
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
|
||||||
|
|
||||||
input_map.erase(p_action);
|
input_map.erase(p_action);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +158,7 @@ bool InputMap::has_action(const StringName &p_action) const {
|
|||||||
|
|
||||||
void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone) {
|
void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone) {
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
|
||||||
|
|
||||||
input_map[p_action].deadzone = p_deadzone;
|
input_map[p_action].deadzone = p_deadzone;
|
||||||
}
|
}
|
||||||
@ -136,7 +166,8 @@ void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone)
|
|||||||
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
|
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
|
||||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
|
||||||
|
|
||||||
if (_find_event(input_map[p_action], p_event))
|
if (_find_event(input_map[p_action], p_event))
|
||||||
return; //already gots
|
return; //already gots
|
||||||
|
|
||||||
@ -145,13 +176,14 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent
|
|||||||
|
|
||||||
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, _suggest_actions(p_action));
|
||||||
|
|
||||||
return (_find_event(input_map[p_action], p_event) != NULL);
|
return (_find_event(input_map[p_action], p_event) != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
|
||||||
|
|
||||||
List<Ref<InputEvent> >::Element *E = _find_event(input_map[p_action], p_event);
|
List<Ref<InputEvent> >::Element *E = _find_event(input_map[p_action], p_event);
|
||||||
if (E) {
|
if (E) {
|
||||||
@ -164,7 +196,7 @@ void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEve
|
|||||||
|
|
||||||
void InputMap::action_erase_events(const StringName &p_action) {
|
void InputMap::action_erase_events(const StringName &p_action) {
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
|
||||||
|
|
||||||
input_map[p_action].inputs.clear();
|
input_map[p_action].inputs.clear();
|
||||||
}
|
}
|
||||||
@ -198,7 +230,7 @@ bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName
|
|||||||
|
|
||||||
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed, float *p_strength) const {
|
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed, float *p_strength) const {
|
||||||
Map<StringName, Action>::Element *E = input_map.find(p_action);
|
Map<StringName, Action>::Element *E = input_map.find(p_action);
|
||||||
ERR_FAIL_COND_V_MSG(!E, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
ERR_FAIL_COND_V_MSG(!E, false, _suggest_actions(p_action));
|
||||||
|
|
||||||
Ref<InputEventAction> input_event_action = p_event;
|
Ref<InputEventAction> input_event_action = p_event;
|
||||||
if (input_event_action.is_valid()) {
|
if (input_event_action.is_valid()) {
|
||||||
@ -333,8 +365,6 @@ void InputMap::load_default() {
|
|||||||
key.instance();
|
key.instance();
|
||||||
key->set_scancode(KEY_END);
|
key->set_scancode(KEY_END);
|
||||||
action_add_event("ui_end", key);
|
action_add_event("ui_end", key);
|
||||||
|
|
||||||
//set("display/window/handheld/orientation", "landscape");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InputMap::InputMap() {
|
InputMap::InputMap() {
|
||||||
|
@ -59,6 +59,7 @@ private:
|
|||||||
|
|
||||||
Array _get_action_list(const StringName &p_action);
|
Array _get_action_list(const StringName &p_action);
|
||||||
Array _get_actions();
|
Array _get_actions();
|
||||||
|
String _suggest_actions(const StringName &p_action) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
Loading…
Reference in New Issue
Block a user