Skip to content

Commit 8e75fae

Browse files
committed
Ue an array removed_idx
1 parent f355382 commit 8e75fae

File tree

2 files changed

+42
-22
lines changed

2 files changed

+42
-22
lines changed

core/input/input.cpp

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,15 +1709,23 @@ void Input::add_joy_mapping(const String &p_mapping, bool p_update_existing) {
17091709
}
17101710

17111711
void Input::remove_joy_mapping(const String &p_guid) {
1712-
int count = 0; // The amount of removals performed.
1713-
int index_removed = -1; // The smallest index where an entry was removed.
1712+
// One GUID can exist multiple times in `map_db`, and
1713+
// `add_joy_mapping` can choose not to update the existing mapping,
1714+
// so the indices can be all over the place. Therefore we need to remember them.
1715+
Vector<int> removed_idx;
1716+
int min_removed_idx = -1;
1717+
int max_removed_idx = -1;
17141718
int fallback_mapping_offset = 0;
17151719

17161720
for (int i = map_db.size() - 1; i >= 0; i--) {
17171721
if (p_guid == map_db[i].uid) {
17181722
map_db.remove_at(i);
1719-
index_removed = i;
1720-
count++;
1723+
1724+
if (max_removed_idx == -1) {
1725+
max_removed_idx = i;
1726+
}
1727+
min_removed_idx = i;
1728+
removed_idx.push_back(i);
17211729

17221730
if (i < fallback_mapping) {
17231731
fallback_mapping_offset++;
@@ -1728,33 +1736,44 @@ void Input::remove_joy_mapping(const String &p_guid) {
17281736
}
17291737
}
17301738

1731-
if (index_removed == -1) {
1732-
return; // Not found.
1739+
if (min_removed_idx == -1) {
1740+
return; // Nothing removed.
17331741
}
17341742

17351743
if (fallback_mapping > 0) {
1736-
// Fixing the shifted index.
1744+
// Fix the shifted index.
17371745
fallback_mapping -= fallback_mapping_offset;
17381746
}
17391747

1748+
int removed_idx_size = removed_idx.size();
1749+
1750+
// Update joypad mapping references: some
1751+
// * should use the fallback_mapping (if set; if not, they get unmapped), or
1752+
// * need their mapping reference fixed, because the deletion(s) offset them.
17401753
for (KeyValue<int, Joypad> &E : joy_names) {
17411754
Joypad &joy = E.value;
1755+
if (joy.mapping < min_removed_idx) {
1756+
continue; // Not affected.
1757+
}
17421758

1743-
if (joy.uid == p_guid) {
1744-
_set_joypad_mapping(joy, fallback_mapping);
1745-
} else if (joy.mapping > index_removed) {
1746-
if (count == 1) {
1747-
// The map_db update offset this joypad's mapping reference, update it:
1748-
_set_joypad_mapping(joy, joy.mapping - 1);
1749-
} else {
1750-
// Re-validate the joypad's correct mapping. Fix it if necessary.
1751-
int mapping = fallback_mapping;
1752-
for (int i = 0; i < map_db.size(); i++) {
1753-
if (joy.uid == map_db[i].uid) {
1754-
mapping = i;
1755-
}
1756-
}
1757-
_set_joypad_mapping(joy, mapping);
1759+
if (joy.mapping > max_removed_idx) {
1760+
_set_joypad_mapping(joy, joy.mapping - removed_idx_size);
1761+
continue; // Simple offset fix.
1762+
}
1763+
1764+
// removed_idx is in reverse order (ie. high to low), because the first loop is in reverse order.
1765+
for (int i = 0; i < removed_idx.size(); i++) {
1766+
if (removed_idx[i] == joy.mapping) {
1767+
// Set to fallback_mapping, if defined, else unmap the joypad.
1768+
// Currently, the fallback_mapping is only set internally, and only for Android.
1769+
_set_joypad_mapping(joy, fallback_mapping);
1770+
break;
1771+
}
1772+
if (removed_idx[i] < joy.mapping) {
1773+
// Complex offset fix:
1774+
// This mapping was shifted by `(removed_idx_size - i)` deletions.
1775+
_set_joypad_mapping(joy, joy.mapping - (removed_idx_size - i));
1776+
break;
17581777
}
17591778
}
17601779
}

doc/classes/Input.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@
312312
<param index="0" name="guid" type="String" />
313313
<description>
314314
Removes all mappings from the internal database that match the given GUID. All currently connected joypads that use this GUID will become unmapped.
315+
On Android, Godot will map to an internal fallback mapping.
315316
</description>
316317
</method>
317318
<method name="set_accelerometer">

0 commit comments

Comments
 (0)