You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Right now there's no way to prevent traverse from traversing the whole tree (save for throwing an exception). However, often it would be useful to prevent processing the child nodes, or even rest of the hierarchy.
Solution
Make traverse and the rest of the family respect special return values. The most important (in my opinion) would be the ability to ignore the children. For example:
// Somewhere in Three.js code. Could be replaced with an enum-style definition
const IGNORE_CHILDREN = new Symbol('ignore_children');
const HALT_TRAVERSE = new Symbol('halt_traverse');
// I didn't check this for mistakes, but the idea should become clear
traverse( callback ) {
const controlFlowResult = callback( this );
if (controlFlowResult === IGNORE_CHILDREN || controlFlowResult === HALT_TRAVERSE ) {
return controlFlowResult;
}
const children = this.children;
for ( let i = 0, l = children.length; i < l; i ++ ) {
const childFlowResult = children[ i ].traverse( callback );
if (childFlowResult === HALT_TRAVERSE) {
return HALT_TRAVERSE;
}
}
}
Examples how a user might use it:
Find a specific node with some property. Then stop.
//
let oneSpecimenB;
myModel.traverse(node => {
if (node.userData.isB) {
oneSpecimentB = node;
return HALT_TRAVERSE;
}
});
Run code for all nodes except for all the descendants (and the node itself) of the nodes we want to ignore
myModel.traverse(node => {
if (node.userData.ignoreChildren) {
// Optionally run operations here before returning
return IGNORE_CHILDREN;
}
// Do operations for others
});
Alternatives
For users, the alternatives are
Set an outside variable to a value from the callback to not do anything. For example
let ingoreChildren = false;
myModel.traverse(node => {
if (node.userData.ignoreChildren) {
ignoreChildren = true;
return;
}
// Do operations for others
});
This will fail after all the descendants have been traversed and the execution returns to the siblings / parent.
Use visibility in conjunction with traverseVisible. The user would run the risk of messing up visibility and it's not convenient anyway, because it would force the user to traverse the hierarchy first to change it.
getObjectByProperty only works for the direct properties of nodes, but not for userData for example. And since it's based on a simple equality comparison, it's generally less useful than a predicate based search.
Implement your own traverse. The user would just duplicate the functionality of traverse
Additional context
No response
The text was updated successfully, but these errors were encountered:
Description
Right now there's no way to prevent
traverse
from traversing the whole tree (save for throwing an exception). However, often it would be useful to prevent processing the child nodes, or even rest of the hierarchy.Solution
Make traverse and the rest of the family respect special return values. The most important (in my opinion) would be the ability to ignore the children. For example:
Examples how a user might use it:
Find a specific node with some property. Then stop.
Run code for all nodes except for all the descendants (and the node itself) of the nodes we want to ignore
Alternatives
For users, the alternatives are
This will fail after all the descendants have been traversed and the execution returns to the siblings / parent.
Use visibility in conjunction with
traverseVisible
. The user would run the risk of messing up visibility and it's not convenient anyway, because it would force the user to traverse the hierarchy first to change it.getObjectByProperty
only works for the direct properties of nodes, but not foruserData
for example. And since it's based on a simple equality comparison, it's generally less useful than a predicate based search.Implement your own
traverse
. The user would just duplicate the functionality oftraverse
Additional context
No response
The text was updated successfully, but these errors were encountered: