package com.indyforge.twod.engine.graphics.rendering.scenegraph.util.iteration; import java.util.Deque; import java.util.Iterator; import java.util.LinkedList; import java.util.NoSuchElementException; import com.indyforge.twod.engine.graphics.rendering.scenegraph.Entity; import com.indyforge.twod.engine.util.iteration.ArrayIterator; /** * This is a recursive-child iterator implementation. * * @author Christopher Probst */ public final class RecursiveChildIterator extends AbstractEntityIterator { // The iteration stack private final Deque<Iterator<? extends Entity>> stack = new LinkedList<Iterator<? extends Entity>>(); /** * Creates a new recursive child iterator using the given root. The root * will be part of the iteration, too. * * @param root * The root entity. */ public RecursiveChildIterator(Entity root) { this(root, true); } /** * Creates a new recursive child iterator using the given root. * * @param root * The root entity. * @param includeRoot * The include-root flag. */ public RecursiveChildIterator(Entity root, boolean includeRoot) { if (root == null) { throw new NullPointerException("root"); } // Create new iterator Iterator<? extends Entity> itr = includeRoot ? new ArrayIterator<Entity>( root) : new ChildIterator(root, false); // Only push if valid if (itr.hasNext()) { // Start with the root iterator stack.push(itr); } } /* * (non-Javadoc) * * @see java.util.Iterator#hasNext() */ @Override public boolean hasNext() { return !stack.isEmpty(); } /* * (non-Javadoc) * * @see java.util.Iterator#next() */ @Override public Entity next() { // Do we have any elements ? if (!hasNext()) { throw new NoSuchElementException(); } // Get itr Iterator<? extends Entity> itr = stack.getFirst(); // Get next entity removePtr = itr.next(); // Pop if (!itr.hasNext()) { stack.pop(); } // Are there any children ? if (removePtr.hasChildren()) { // Offer next child iterator if valid stack.push(new ChildIterator(removePtr, false)); } return removePtr; } }