using System; using System.Diagnostics; namespace SpaceInvaders { public class DLinkMan : List { //------------------------------------------------------------------- // FIELDS //------------------------------------------------------------------- public DLinkIterator poIterator; public DLink pHead; public DLink pTail; //------------------------------------------------------------------- // CONSTRUCTION //------------------------------------------------------------------- public DLinkMan() : base() { //LTN: owned by dlink manager this.poIterator = new DLinkIterator(); Debug.Assert(this.poIterator != null); this.pHead = null; this.pTail = null; } //------------------------------------------------------------------- // PUBLIC METHODS //------------------------------------------------------------------- public override void AddToFront(Node pNode) { //check node Debug.Assert(pNode != null); DLink pLink = (DLink)pNode; //if list empty, add as head if (pHead == null) { pHead = pTail = pLink; pLink.pNext = null; pLink.pPrev = null; } //else, add to front else { //attach new node to head pLink.pNext = pHead; pLink.pPrev = null; //update head pHead.pPrev = pLink; pHead = pLink; } Debug.Assert(pHead != null); } public override void AddByPriority(Node pNode) { //check node Debug.Assert(pNode != null); DLink pLink = (DLink)pNode; if (this.pHead == null) { //empty list, add w/o priority check this.pHead = this.pTail = pLink; pLink.pNext = null; pLink.pPrev = null; } else { DLink pCurr = this.pHead; DLink pPrev = null; //iterate list while (pCurr != null) { if (pCurr.ComparePriority(pLink)) { //curr priority <= InNode priority //exit break; } pPrev = pCurr; //save ref pCurr = pCurr.pNext; //get next } if (pCurr == null) { //reached end of list, add at end pPrev.pNext = pLink; pLink.pPrev = pPrev; pLink.pNext = null; //update tail ptr this.pTail = pLink; } else if (pCurr == this.pHead) { //add as head pLink.pNext = this.pHead; this.pHead.pPrev = pLink; //update head this.pHead = pLink; } else { //add before pPrev.pNext = pLink; pCurr.pPrev = pLink; pLink.pPrev = pPrev; pLink.pNext = pCurr; } } Debug.Assert(pHead != null); } public override void InsertAfter(Node pNewNode, Node pNodeBefore) { DLink pNewLink = (DLink)pNewNode; DLink pPrevLink = (DLink)pNodeBefore; pNewLink.pNext = pPrevLink.pNext; pNewLink.pPrev = pPrevLink; if(pPrevLink.pNext != null) { pPrevLink.pNext = pNewLink; } //set previous pPrevLink.pNext = pNewLink; } public override void InsertBefore(Node pNewNode, Node pNodeAfter) { DLink pNewLink = (DLink)pNewNode; DLink pNextLink = (DLink)pNodeAfter; //link new node before "next" link pNewLink.pNext = pNextLink; pNewLink.pPrev = pNextLink.pPrev; //head condition if(pNextLink.pPrev != null) { pNextLink.pPrev.pNext = pNewLink; } //fix next node pointer pNextLink.pPrev = pNewLink; } //active & reserve: remove front node public override Node RemoveFromFront() { //check list exists Debug.Assert(pHead != null); DLink pLink = pHead; //only node on list if (pHead.pNext == null) { //pHead = null; pHead = pTail = null; } //else remove head else { pHead = pHead.pNext; pHead.pPrev = null; } //clear links pLink.Reset(); return pLink; } //active: remove specific node public override void Remove(Node pNode) { //check node Debug.Assert(pHead != null); Debug.Assert(pNode != null); DLink pLink = (DLink)pNode; if (pLink.pPrev == null && pLink.pNext == null) { //only node on list this.pHead = this.pTail = null; } else if (pLink.pPrev == null && pLink.pNext != null) { //first node on list this.pHead = pLink.pNext; pLink.pNext.pPrev = pLink.pPrev; } else if (pLink == this.pTail) { //last node this.pTail = pTail.pPrev; pLink.pPrev.pNext = null; } else { //middle node pLink.pNext.pPrev = pLink.pPrev; pLink.pPrev.pNext = pLink.pNext; } //clear links pLink.Reset(); } public override Iterator GetIterator() { poIterator.Reset(this.pHead); return poIterator; } } }