Ue an array removed_idx

This commit is contained in:
MJacred 2025-01-14 12:09:16 +01:00
parent f355382ef5
commit 8e75fae49e
2 changed files with 42 additions and 22 deletions

View file

@ -1709,15 +1709,23 @@ void Input::add_joy_mapping(const String &p_mapping, bool p_update_existing) {
}
void Input::remove_joy_mapping(const String &p_guid) {
int count = 0; // The amount of removals performed.
int index_removed = -1; // The smallest index where an entry was removed.
// One GUID can exist multiple times in `map_db`, and
// `add_joy_mapping` can choose not to update the existing mapping,
// so the indices can be all over the place. Therefore we need to remember them.
Vector<int> removed_idx;
int min_removed_idx = -1;
int max_removed_idx = -1;
int fallback_mapping_offset = 0;
for (int i = map_db.size() - 1; i >= 0; i--) {
if (p_guid == map_db[i].uid) {
map_db.remove_at(i);
index_removed = i;
count++;
if (max_removed_idx == -1) {
max_removed_idx = i;
}
min_removed_idx = i;
removed_idx.push_back(i);
if (i < fallback_mapping) {
fallback_mapping_offset++;
@ -1728,33 +1736,44 @@ void Input::remove_joy_mapping(const String &p_guid) {
}
}
if (index_removed == -1) {
return; // Not found.
if (min_removed_idx == -1) {
return; // Nothing removed.
}
if (fallback_mapping > 0) {
// Fixing the shifted index.
// Fix the shifted index.
fallback_mapping -= fallback_mapping_offset;
}
int removed_idx_size = removed_idx.size();
// Update joypad mapping references: some
// * should use the fallback_mapping (if set; if not, they get unmapped), or
// * need their mapping reference fixed, because the deletion(s) offset them.
for (KeyValue<int, Joypad> &E : joy_names) {
Joypad &joy = E.value;
if (joy.mapping < min_removed_idx) {
continue; // Not affected.
}
if (joy.uid == p_guid) {
_set_joypad_mapping(joy, fallback_mapping);
} else if (joy.mapping > index_removed) {
if (count == 1) {
// The map_db update offset this joypad's mapping reference, update it:
_set_joypad_mapping(joy, joy.mapping - 1);
} else {
// Re-validate the joypad's correct mapping. Fix it if necessary.
int mapping = fallback_mapping;
for (int i = 0; i < map_db.size(); i++) {
if (joy.uid == map_db[i].uid) {
mapping = i;
}
}
_set_joypad_mapping(joy, mapping);
if (joy.mapping > max_removed_idx) {
_set_joypad_mapping(joy, joy.mapping - removed_idx_size);
continue; // Simple offset fix.
}
// removed_idx is in reverse order (ie. high to low), because the first loop is in reverse order.
for (int i = 0; i < removed_idx.size(); i++) {
if (removed_idx[i] == joy.mapping) {
// Set to fallback_mapping, if defined, else unmap the joypad.
// Currently, the fallback_mapping is only set internally, and only for Android.
_set_joypad_mapping(joy, fallback_mapping);
break;
}
if (removed_idx[i] < joy.mapping) {
// Complex offset fix:
// This mapping was shifted by `(removed_idx_size - i)` deletions.
_set_joypad_mapping(joy, joy.mapping - (removed_idx_size - i));
break;
}
}
}

View file

@ -312,6 +312,7 @@
<param index="0" name="guid" type="String" />
<description>
Removes all mappings from the internal database that match the given GUID. All currently connected joypads that use this GUID will become unmapped.
On Android, Godot will map to an internal fallback mapping.
</description>
</method>
<method name="set_accelerometer">