-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
[raycaster] Use MutationObserver and object3dset/remove to refresh. #3070
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[raycaster] Use MutationObserver and object3dset/remove to refresh. #3070
Conversation
|
Thanks I'll look into it post 0.7.0 release |
|
Added /cc @machenmusik |
ngokevin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The approach looks good to me to continue with tests, will want to mention in perf best practices section to watch out for this potentially
src/components/raycaster.js
Outdated
| this.el.sceneEl.addEventListener('child-attached', this.refreshOnceChildLoaded); | ||
| this.el.sceneEl.addEventListener('child-detached', this.refreshObjects); | ||
| if (!this.data.watch) { return; } | ||
| this.observer.observe(this.el.sceneEl, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could store/reuse this object as a constant
src/components/raycaster.js
Outdated
| this.updateOriginDirection(); | ||
| this.refreshObjects = bind(this.refreshObjects, this); | ||
| this.refreshOnceChildLoaded = bind(this.refreshOnceChildLoaded, this); | ||
| this.setDirty = bind(this.setDirty, this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I re-ran some jsperf stuff, we can just start using vanilla bind. I don't think there's perf difference
src/components/raycaster.js
Outdated
| showLine: {default: false}, | ||
| useWorldCoordinates: {default: false} | ||
| useWorldCoordinates: {default: false}, | ||
| watch: {default: true} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps autoRefresh
src/components/raycaster.js
Outdated
| // Defines selectors that should be 'safe' for the MutationObserver used to | ||
| // refresh the whitelist. Less common selectors, like [position=0 2 0], cannot | ||
| // be detected here. | ||
| var SAFE_SELECTOR_RE = /^[\w\s-.[\]#]+$/; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can explain more what this selector matches, and name maybe like OBSERVER_SELECTOR_RE
src/components/raycaster.js
Outdated
| } | ||
|
|
||
| if (data.watch !== oldData.watch && el.isPlaying) { | ||
| data.watch ? this.play() : this.pause(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not call handlers from other handlers, can extract to separate methods
|
Updated based on feedback, and added a couple tests. |
This is a proposed fix for #2980 and #3067. It's not possible to perfectly detect when the whitelist may have changed — direct calls to
el.object3D.add(mesh)will be missed, for example — but this covers all of the A-Frame API surface I think.Changes:
object3dsetandobject3dremove. Unlike child-added/removed, these are only triggered after the entity has loaded, so no need for a delay.raycaster.objectsselector is exotic, like[position=0 2 0], which will be missed by our MutationObserver.If this direction looks OK, I'll add tests. It's a bigger change than we should include for 0.7.0, and can wait for 0.7.1 or 0.8.0.