Skip to content
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

Allow components to define before/after constraints #5478

Merged
merged 3 commits into from
Mar 28, 2024

Conversation

mrxz
Copy link
Contributor

@mrxz mrxz commented Feb 28, 2024

Description:
The scene calls all the tick and tock methods in the order they were added. This can cause problems when components use the output of other components. They either get called after, in which case they have up-to-date info, or before, in which case they have 1 frame stale data. The longer the chain is the more frames of 'latency' this might add. This is often an issue with components that inspect or use the position of another element (e.g. collision detection before updated controller pose, nav-mesh constraints before locomotion, etc...). This can be seen in Ada's aframe-xr-boilerplate:

update-order-PR-vid.webm

This PR expand the component definition with after and before. A components tick will be called after all tick methods of the components listed in after have taken place and before all tick methods of the components listed in before. The scene updates per component, the order among components of the same type is still undefined.

This PR also includes an alternative implementation of #5403 (fixes #5400, fixes #4164) . Since calls take place per component type, the odds that a component adds/removes components of the same type is unlikely, meaning that a happy path can be taken most of the time (directly add or remove behaviour). In case it does happen, the behaviours are marked for removal and removed after the scene is done with that particular component.

Changes proposed:

  • Allow components to define before/after constraints
  • Let the scene call tick and tock per component respecting the given constraints
  • Correctly handle removeBehavior when called from a tick or tock method
  • Use before/after constraints to fix a bug in the tracked-controls example, where quickly waving your controllers while having grabbed a cube could show the cube without highlight for brief periods.

@mrxz mrxz force-pushed the update-order branch 2 times, most recently from 4478a5e to bfb9636 Compare March 11, 2024 10:19
var warn = debug('utils:order:warn');

/**
* Derives an ordering from the elements with before and after constraints.
Copy link
Member

@dmarcos dmarcos Mar 22, 2024

Choose a reason for hiding this comment

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

order no descriptive name. not sure it needs to be a separate utils file. we can just include this function in a-scene

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The a-scene.js file is already pretty lengthy. I'd rather not append this to it, especially given that the implementation details aren't relevant from the POV of the scene.

Definitely open for (file) name suggestions. I left out component as it can also be applied to systems down the line, but if it helps clarity now, it can be included in the name.

Copy link
Member

Choose a reason for hiding this comment

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

900 LOC is not super big and purpose of utils is factor out code used from multiple files or exported. When understanding a code base having tons of files that don't know how to relate to one another a bigger problem than big files. I would just incorporate this code to a-scene

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't really agree, but ultimately a subjective point, so added it to a-scene.js.

this.componentOrder = solveOrder(components, this.componentOrder);
this.addEventListener('componentregistered', function () {
// Recompute order
self.componentOrder = solveOrder(components, self.componentOrder);
Copy link
Member

Choose a reason for hiding this comment

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

solveOrder not super descriptive. sortComponents?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not sorting, the components object isn't mutated in the process. It just returns an order which it arrives at by solving the set of before/after constraints, hence solveOrder.

Perhaps something like determineOrder (or determineComponentOrder) could work?

Copy link
Member

Choose a reason for hiding this comment

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

sortComponentsByTikTokOrder ? It's not a sort in place but still a sort

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not trying to be pedantic, but it really isn't sorting, neither in-place nor as its result. The resulting order could be used for sorting, but isn't. Naming it as such feels out of place to me.

src/core/scene/a-scene.js Outdated Show resolved Hide resolved
@dmarcos
Copy link
Member

dmarcos commented Mar 27, 2024

This one is pretty close

@dmarcos
Copy link
Member

dmarcos commented Mar 28, 2024

Thanks so much for the patient and being accommodating! Great work!

@dmarcos dmarcos merged commit c7736c4 into aframevr:master Mar 28, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants