// // Private Methods // /// <summary> /// Searches for the next node in the PCS Tree /// </summary> /// <param name="current"></param> /// <param name="canUseChild"> /// Can the next node be a child node? /// </param> /// <returns></returns> private PCSTreeNode privGetNext(PCSTreeNode current, bool canUseChild = true) { PCSTreeNode theNextNode = null; // If there is a child and can use it if ((current.Child != null) && canUseChild) { theNextNode = current.Child; } // If there is a sibling (and no child) else if (current.Sibling != null) { theNextNode = current.Sibling; } // If there is a parent (and no child or sibling) else if (current.Parent != this.treeRoot) { // Search the parent's sibling theNextNode = this.privGetNext(current.Parent, false); } // If there is no parent, child or sibling else { theNextNode = null; } return(theNextNode); }
// // Methods // /// <summary> /// Adds a new child to this node /// </summary> /// <param name="newChild"></param> public void AddChild(PCSTreeNode newChild) { Debug.Assert(newChild.sibling == null, "The new child shouldn't have any other siblings"); // Add the new child if this has no children if (this.child == null) { // Point down to the child this.child = newChild; // Make child point up to this newChild.parent = this; // Tell GameObject that a new child was added this.OnPCSNewChild(false); } // If children already exist, add new child as // the new sibling of the existing children else { this.child.AddSibling(newChild); // Tell GameObject that a new child was added this.OnPCSNewChild(true); } }
/// <summary> /// Initialize the iterator /// </summary> /// <param name="root"> /// The root node of the PCS Tree /// </param> public PCSIterator(PCSTreeNode root) { //Debug.Assert(root != null); this.treeRoot = root; this.currentNode = root; }
/// <summary> /// Initialize the traverser /// </summary> /// <param name="root"> /// The root node of the PCS Tree /// </param> public PCSTraverser(PCSTreeNode root) { //Debug.Assert(root != null, "The PCS Root should not be null for the traverse to work!"); this.treeRoot = root; this.currentNode = root; }
// // Private Methods // /// <summary> /// Gives a new sibling node to this node. /// Warning: assumes neither have next siblings /// </summary> /// <param name="newSibling"></param> private void AddSibling(PCSTreeNode newSibling) { Debug.Assert(newSibling.sibling == null, "The new sibling shouldn't have any other siblings"); // Add new sibling if this has no sibling if (this.sibling == null) { this.sibling = newSibling; // Give the new sibling the same parent newSibling.parent = this.parent; } // See if the next sibling can add the new sibling (recursive!) else { this.sibling.AddSibling(newSibling); } }
/// <summary> /// Removes itself from any existing PCS hierarchy, including children /// </summary> public void RemoveThisPCSNode() { // X Parent if (this.parent == null) { // X Parent, X Child if (this.child == null) { // X Parent, X Child, X Sibling if (this.sibling == null) { // Do nothing } // X Parent, X Child, O Sibling else { Debug.Assert(this.sibling.parent == null, "The sibling shouldn't have a parent if this node didn't either."); this.sibling = null; } } // X Parent, O Child else { // X Parent, O Child, X Sibling if (this.sibling == null) { this.RemoveChildrenNodes(); } // X Parent, O Child, O Sibling else { Debug.Assert(this.sibling.parent == null, "The sibling shouldn't have a parent if this node didn't either."); this.sibling = null; this.RemoveChildrenNodes(); } } } // O Parent else { // O Parent, X Child if (this.child == null) { // O Parent, X Child, X Sibling if (this.sibling == null) { // If this node is also the first and only if (ReferenceEquals(this, this.parent.child)) { // This should be the end case of // recursive child unlinking this.parent.child = null; this.parent = null; } else { // Find the second to last sibling (backItr) PCSTreeNode backItr = this.parent.child; PCSTreeNode frontItr = backItr.sibling; while (ReferenceEquals(this, frontItr) == false) { frontItr = frontItr.sibling; backItr = backItr.sibling; } // Second to last node is now last node backItr.sibling = null; // This now doesn't have a parent this.parent = null; } } // O Parent, X Child, O Sibling else { // If parent points to this node (to be removed) if (ReferenceEquals(this.parent.child, this)) { // Correct the child pointer for parent this.parent.child = this.sibling; } // If parent points to no child else if (this.parent.child == null) { // Do nothing?? } // If parent points to another sibling else { // Find the sibling before this node (backItr) PCSTreeNode backItr = this.parent.child; PCSTreeNode forwardItr = backItr.sibling; while (ReferenceEquals(forwardItr, this) == false) { Debug.Assert(forwardItr != null); backItr = backItr.sibling; forwardItr = forwardItr.sibling; } // Point the previous sibling to the next sibling backItr.sibling = this.sibling; } // Unlink this parent and next sibling this.parent = null; this.sibling = null; } } // O Parent, O Child else { // O Parent, O Child, X Sibling if (this.sibling == null) { // If this node is also the first and only if (ReferenceEquals(this, this.parent.child)) { this.parent.child = null; this.parent = null; } else { // Find the second to last sibling (backItr) PCSTreeNode backItr = this.parent.child; PCSTreeNode frontItr = backItr.sibling; while (ReferenceEquals(this, frontItr) == false) { frontItr = frontItr.sibling; backItr = backItr.sibling; } // Second to last node is now last node backItr.sibling = null; // This now doesn't have a parent this.parent = null; } this.RemoveChildrenNodes(); } // O Parent, O Child, O Sibling else { // If parent points to this node (to be removed) if (ReferenceEquals(this.parent.child, this)) { // Correct the child pointer for parent this.parent.child = this.sibling; } // If parent points to no child else if (this.parent.child == null) { // Do nothing?? } // If parent points to another sibling else { // Find the sibling before this node (backItr) PCSTreeNode backItr = this.parent.child; PCSTreeNode forwardItr = backItr.sibling; while (ReferenceEquals(forwardItr, this) == false) { Debug.Assert(forwardItr != null); backItr = backItr.sibling; forwardItr = forwardItr.sibling; } // Point the previous sibling to the next sibling backItr.sibling = this.sibling; } // Unlink this parent and next sibling this.parent = null; this.sibling = null; this.RemoveChildrenNodes(); } } } this.OnPCSUnlink(); }
// // Constructor // public PCSTreeNode() { this.parent = null; this.child = null; this.sibling = null; }
/// <summary> /// Moves this iterator to the next PCSTreeNode and then returns it /// </summary> /// <returns></returns> public PCSTreeNode GetNext() { this.currentNode = this.privGetNext(this.currentNode); return(this.currentNode); }
/// <summary> /// Moves this iterator back to the root of the PCS Tree /// </summary> public void StartOver() { this.currentNode = treeRoot; }
/// <summary> /// Sets a new root for this iterator /// </summary> /// <param name="newRoot"></param> public void Reassign(PCSTreeNode newRoot) { this.treeRoot = newRoot; this.currentNode = newRoot; }
/// <summary> /// Moves this traverser to the next sibling /// </summary> /// <returns></returns> public void NextSibling() { this.currentNode = this.currentNode.Sibling; }
/// <summary> /// Moves this traverser to the next child /// </summary> /// <returns></returns> public void NextChild() { this.currentNode = this.currentNode.Child; }