Skip to content

Conversation

@donmccurdy
Copy link
Member

@donmccurdy donmccurdy commented Sep 20, 2017

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:

  • Use a MutationObserver to detect new elements and new attributes. While attribute values are not flushed to the DOM, the attribute names are, so this at least covers cases like adding a new component or changing a className.
  • Listen for object3dset and object3dremove. Unlike child-added/removed, these are only triggered after the entity has loaded, so no need for a delay.
  • When any of the above listeners fire, just set a dirty flag.
  • Before each raycast, if dirty flag is set, refresh the object list.
  • Warn users if the raycaster.objects selector 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.

@dmarcos
Copy link
Member

dmarcos commented Sep 20, 2017

Thanks I'll look into it post 0.7.0 release

@donmccurdy
Copy link
Member Author

donmccurdy commented Sep 21, 2017

Added raycaster.watch property, which can be disabled if users would like to manage refreshes themselves.

/cc @machenmusik

Copy link
Member

@ngokevin ngokevin left a 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

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, {
Copy link
Member

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

this.updateOriginDirection();
this.refreshObjects = bind(this.refreshObjects, this);
this.refreshOnceChildLoaded = bind(this.refreshOnceChildLoaded, this);
this.setDirty = bind(this.setDirty, this);
Copy link
Member

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

showLine: {default: false},
useWorldCoordinates: {default: false}
useWorldCoordinates: {default: false},
watch: {default: true}
Copy link
Member

Choose a reason for hiding this comment

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

perhaps autoRefresh

// 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-.[\]#]+$/;
Copy link
Member

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

}

if (data.watch !== oldData.watch && el.isPlaying) {
data.watch ? this.play() : this.pause();
Copy link
Member

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

@donmccurdy
Copy link
Member Author

Updated based on feedback, and added a couple tests.

@ngokevin ngokevin merged commit 04f932c into aframevr:master Oct 2, 2017
@donmccurdy donmccurdy deleted the feat-raycaster-mutationobserver branch July 19, 2018 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants