Skip to content

fix: improve XrControllers script robustness and documentation#8410

Merged
willeastcott merged 4 commits into
mainfrom
fix-xr-controllers-improvements
Jan 26, 2026
Merged

fix: improve XrControllers script robustness and documentation#8410
willeastcott merged 4 commits into
mainfrom
fix-xr-controllers-improvements

Conversation

@willeastcott

@willeastcott willeastcott commented Jan 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fix race condition when input source is removed during async profile loading
  • Add XR session end cleanup to destroy all controller entities
  • Add proper destroy lifecycle with event listener cleanup
  • Change profile loading from parallel to sequential (stop on first success)
  • Add comprehensive JSDoc documentation and type imports
  • Add visibility control (visible property) for controller models
  • Fire xr:controller:add and xr:controller:remove events for coordination
  • Clean up loaded assets when controllers are removed

Technical Details

Bug Fixes:

  1. Race condition - Added _pendingInputSources Set to track input sources during async loading. Checks validity after each async operation and cleans up resources if removed.
  2. Session end cleanup - Added listener for app.xr.on('end', ...) that destroys all controller entities when the XR session ends.
  3. Destroy lifecycle - Added _onDestroy() method using once('destroy', ...) pattern for proper event listener cleanup.
  4. Sequential loading - Changed from Promise.all() to sequential loop that stops on first successful profile match.

Enhancements:

  • Comprehensive JSDoc documentation matching other XR scripts
  • visible getter/setter for showing/hiding controller models
  • Events for other scripts to coordinate with controller lifecycle
  • Asset cleanup when controllers are removed

Test plan

  • Test in VR with controller input
  • Test with hand tracking
  • Test rapid session start/stop
  • Verify controllers clean up on session end
  • Run xr-menu example

- Fix race condition when input source is removed during async profile loading

- Add XR session end cleanup to destroy all controller entities

- Add proper destroy lifecycle with event listener cleanup

- Change profile loading from parallel to sequential (stop on first success)

- Add comprehensive JSDoc documentation and type imports

- Add visibility control (visible property) for controller models

- Fire xr:controller:add and xr:controller:remove events for coordination

- Add getControllerEntity() helper method

- Clean up loaded assets when controllers are removed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the XrControllers script to be more robust around XR input lifecycle, cleans up resources correctly, and documents its behavior and API for easier integration with other XR scripts.

Changes:

  • Refactors controller lifecycle management: adds _pendingInputSources to avoid races during async profile loading, centralizes session-end and destroy cleanup, and introduces _onInputSourceAdd / _onInputSourceRemove / _onXrEnd helpers.
  • Switches profile loading from parallel to sequential (first-success wins), adds controller visibility control (visible getter/setter) and a getControllerEntity() helper, and starts firing xr:controller:add / xr:controller:remove events.
  • Adds comprehensive JSDoc annotations and type imports to align with other XR-related scripts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/esm/xr-controllers.mjs Outdated
@willeastcott willeastcott merged commit 95da22d into main Jan 26, 2026
7 checks passed
@willeastcott willeastcott deleted the fix-xr-controllers-improvements branch January 26, 2026 01:25
willeastcott added a commit that referenced this pull request Jan 26, 2026
* fix: improve XrControllers script robustness and documentation

- Fix race condition when input source is removed during async profile loading

- Add XR session end cleanup to destroy all controller entities

- Add proper destroy lifecycle with event listener cleanup

- Change profile loading from parallel to sequential (stop on first success)

- Add comprehensive JSDoc documentation and type imports

- Add visibility control (visible property) for controller models

- Fire xr:controller:add and xr:controller:remove events for coordination

- Add getControllerEntity() helper method

- Clean up loaded assets when controllers are removed

* refactor: remove redundant getControllerEntity helper method

* refactor: centralize controller cleanup to prevent asset leaks

* refactor: use recursive helper to avoid await-in-loop lint error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: scripts area: xr XR related issue enhancement Request for a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants