Refactor/keyboard controller#7761
Open
vanshika2720 wants to merge 2 commits into
Open
Conversation
Move keyboard shortcut dispatch, modifier key handling (Alt/Ctrl/Shift), arrow key navigation, space bar play/stop, copy/paste shortcuts, tempo widget integration, and current-key-code state from activity.js into a new js/keyboard-controller.js module. The module exposes a clean public API via setupKeyboardController(activity) and delegates all calls from activity to the new KeyboardController class. No behavioral changes; all existing keyboard shortcuts are preserved exactly. What was moved - __keyPressed - full shortcut dispatch (~390 lines) - getCurrentKeyCode / clearCurrentKeyCode - key-code state used by the Keyboard Sensor block - Keyboard listener registration and disposal (own document-level addEventListener/removeEventListener, independent of Activity's request-scoped listener tracking so the shortcut keeps working for the lifetime of the page, matching prior behavior) loader.js: add "keyboard-controller" to the activity/activity shim deps list and paths map, matching the existing controller extraction pattern. Updated activity_toolbar_integration.test.js: the "keyboard-triggered execution shortcuts" tests exercised __keyPressed directly and now mock setupKeyboardController like the other controller setup calls; equivalent (and expanded) coverage moves to the new dedicated keyboard-controller.test.js suite. Signed-off-by: Vanshika <pahalvanshikaa@gmail.com>
Add a dedicated Jest suite for KeyboardController covering setup, current-key-code state, listener lifecycle (registered on setup, removed by dispose, dispose is idempotent), arrow key navigation, space bar play/stop, copy/paste shortcuts, tempo widget integration, Alt/Ctrl/Shift modifier combinations, ignoring shortcuts while a text input is focused, palette scrolling, and stage scrolling. Tests assert on observable effects (blocks moving, playback starting/ stopping, tempo changing, stage scrolling) rather than on internal calls like addEventListener/removeEventListener, so the suite survives future implementation changes. Signed-off-by: Vanshika <pahalvanshikaa@gmail.com>
Contributor
Author
Contributor
|
This PR has merge conflicts with Please rebase your branch: # Add upstream remote (one-time setup)
git remote add upstream https://github.com/sugarlabs/musicblocks.git
# Fetch latest master and rebase
git fetch upstream
git rebase upstream/master
# Resolve any conflicts, then:
git push --force-with-lease origin YOUR_BRANCH
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR optimizes node add/remove operations in the scheduler cache by eliminating O(n)
NodeListscans performed while holding the global scheduler cache mutex.Previously,
AddOrUpdateNode()performed a linear scan overNodeListto determine whether a node already existed before appending it. Similarly,RemoveNode()scanned the slice to locate the node before removing it, resulting in O(n) lookup and additional O(n) slice copying.To improve scalability, this PR introduces a
nodeListIndex(map[string]int) that is maintained alongsideNodeList. The index provides O(1) membership checks and enables efficient node removal using swap-delete while keeping the index synchronized.AddOrUpdateNode()now uses the index map to determine whether a node already exists before appending it.RemoveNode()performs O(1) lookup through the index map, replaces the removed entry with the last element in the slice, updates the swapped node's index, and truncates the slice.To preserve compatibility with existing tests that construct
SchedulerCachedirectly, the index is lazily initialized from an existingNodeListwhen necessary.No behavioral changes are intended. The scheduler cache continues to expose the same functionality, and
NodeListordering remains effectively unchanged from the scheduler's perspective since ordering is not relied upon by snapshot generation.Test Plan
Added and updated unit tests covering:
NodeListentries.NodeListandnodeListIndex.nodeListIndexremains consistent after every add and remove operation.Added benchmarks for node add/remove operations at 100-, 500-, and 2000-node scale to compare the optimized implementation against the previous linear-scan approach.
Additional Notes
This optimization is internal to the scheduler cache and does not introduce any user-facing changes or API modifications.
The implementation reduces mutex hold time during node add/remove events, improving scalability and reducing lock contention in large clusters while preserving existing scheduler behavior.
Only files directly related to this optimization were modified:
pkg/scheduler/cache/event_handlers.gopkg/scheduler/cache/cache.go(index initialization)pkg/scheduler/cache/*_test.gopkg/scheduler/cache/*_benchmark_test.go