Rewrite routing data buffers to strip old entries + sort by key to make queries not touch scattered data. Entries D,A,B,B,A,C,B --> A,A,B,B,B,C,D Index A:1 B:2 C:5 D:0 --> A:0 B:2 C:5 D:6 See 'Metrics->Key Owners & Shortcut Routing' to visualize the result of that operation.
| 9350 | // Index A:1 B:2 C:5 D:0 --> A:0 B:2 C:5 D:6 |
| 9351 | // See 'Metrics->Key Owners & Shortcut Routing' to visualize the result of that operation. |
| 9352 | static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt) |
| 9353 | { |
| 9354 | ImGuiContext& g = *GImGui; |
| 9355 | rt->EntriesNext.resize(0); |
| 9356 | for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) |
| 9357 | { |
| 9358 | const int new_routing_start_idx = rt->EntriesNext.Size; |
| 9359 | ImGuiKeyRoutingData* routing_entry; |
| 9360 | for (int old_routing_idx = rt->Index[key - ImGuiKey_NamedKey_BEGIN]; old_routing_idx != -1; old_routing_idx = routing_entry->NextEntryIndex) |
| 9361 | { |
| 9362 | routing_entry = &rt->Entries[old_routing_idx]; |
| 9363 | routing_entry->RoutingCurrScore = routing_entry->RoutingNextScore; |
| 9364 | routing_entry->RoutingCurr = routing_entry->RoutingNext; // Update entry |
| 9365 | routing_entry->RoutingNext = ImGuiKeyOwner_NoOwner; |
| 9366 | routing_entry->RoutingNextScore = 255; |
| 9367 | if (routing_entry->RoutingCurr == ImGuiKeyOwner_NoOwner) |
| 9368 | continue; |
| 9369 | rt->EntriesNext.push_back(*routing_entry); // Write alive ones into new buffer |
| 9370 | |
| 9371 | // Apply routing to owner if there's no owner already (RoutingCurr == None at this point) |
| 9372 | // This is the result of previous frame's SetShortcutRouting() call. |
| 9373 | if (routing_entry->Mods == g.IO.KeyMods) |
| 9374 | { |
| 9375 | ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key); |
| 9376 | if (owner_data->OwnerCurr == ImGuiKeyOwner_NoOwner) |
| 9377 | { |
| 9378 | owner_data->OwnerCurr = routing_entry->RoutingCurr; |
| 9379 | //IMGUI_DEBUG_LOG("SetKeyOwner(%s, owner_id=0x%08X) via Routing\n", GetKeyName(key), routing_entry->RoutingCurr); |
| 9380 | } |
| 9381 | } |
| 9382 | } |
| 9383 | |
| 9384 | // Rewrite linked-list |
| 9385 | rt->Index[key - ImGuiKey_NamedKey_BEGIN] = (ImGuiKeyRoutingIndex)(new_routing_start_idx < rt->EntriesNext.Size ? new_routing_start_idx : -1); |
| 9386 | for (int n = new_routing_start_idx; n < rt->EntriesNext.Size; n++) |
| 9387 | rt->EntriesNext[n].NextEntryIndex = (ImGuiKeyRoutingIndex)((n + 1 < rt->EntriesNext.Size) ? n + 1 : -1); |
| 9388 | } |
| 9389 | rt->Entries.swap(rt->EntriesNext); // Swap new and old indexes |
| 9390 | } |
| 9391 | |
| 9392 | // owner_id may be None/Any, but routing_id needs to be always be set, so we default to GetCurrentFocusScope(). |
| 9393 | static inline ImGuiID GetRoutingIdFromOwnerId(ImGuiID owner_id) |
nothing calls this directly
no test coverage detected