jalse.entities.EntityTreeWalker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of JALSE Show documentation
Show all versions of JALSE Show documentation
Java Artificial Life Simulation Engine
package jalse.entities;
import jalse.entities.EntityVisitor.EntityVisitResult;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Objects;
import java.util.Queue;
class EntityTreeWalker {
private final EntityContainer container;
private final int maxDepth;
private final EntityVisitor visitor;
private final Queue walkers;
private final Iterator iterator;
private boolean ignoreSiblings;
private boolean exited;
EntityTreeWalker(final EntityContainer container, final int maxDepth, final EntityVisitor visitor) {
this.container = Objects.requireNonNull(container);
this.visitor = Objects.requireNonNull(visitor);
if (maxDepth <= 0) {
throw new IllegalArgumentException();
}
this.maxDepth = maxDepth;
walkers = new LinkedList<>();
iterator = container.streamEntities().iterator(); // Lazy
exited = false;
}
private boolean canAddChild() {
return !ignoreSiblings && iterator.hasNext();
}
private boolean canWalkChild() {
return !walkers.isEmpty();
}
public EntityContainer getContainer() {
return container;
}
public int getMaxDepth() {
return maxDepth;
}
public EntityVisitor getVisitor() {
return visitor;
}
private boolean hasExited() {
return exited;
}
public boolean isWalking() {
return !hasExited() && (canAddChild() || canWalkChild());
}
public Entity walk() {
if (!isWalking()) {
throw new IllegalStateException();
}
/*
* Visit direct children.
*/
if (canAddChild()) {
final Entity e = iterator.next();
final EntityVisitResult result = visitor.visit(e);
if (result == EntityVisitResult.EXIT) {
exited = true;
return e;
}
/*
* Remove other children.
*/
if (result == EntityVisitResult.IGNORE_SIBLINGS) {
ignoreSiblings = true;
walkers.clear();
}
/*
* Do not walk through child descendants.
*/
if (maxDepth > 1 && result != EntityVisitResult.IGNORE_CHILDREN) {
final EntityTreeWalker child = new EntityTreeWalker(e, maxDepth - 1, visitor);
if (child.isWalking()) {
walkers.add(child);
}
}
return e;
}
/*
* Walk already visited child.
*/
final EntityTreeWalker child = walkers.element();
final Entity e = child.walk();
/*
* Child has been fully traversed.
*/
if (!child.isWalking()) {
walkers.remove();
}
return e;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy