using System; using System.Diagnostics; namespace SpaceInvaders { public abstract class Manager { //------------------------------------------------------------------- // FIELDS //------------------------------------------------------------------- private readonly List poReserve; private readonly List poActive; private int numActive; //total active nodes private int numReserve; //total reserve nodes private int totalNum; //total nodes created private int numGrow; //num to grow reserve //------------------------------------------------------------------- // ABSTRACT METHODS //------------------------------------------------------------------- protected abstract Node derivedCreate(); //------------------------------------------------------------------- // CONSTRUCTION //------------------------------------------------------------------- public Manager(List pActive, List pReserve, int initialReserve = 3, int growReserve = 2) { //check incoming values Debug.Assert(pActive != null); Debug.Assert(pReserve != null); Debug.Assert(initialReserve >= 0); Debug.Assert(growReserve > 0); //set defaults this.poReserve = pReserve; this.poActive = pActive; this.numActive = 0; this.numReserve = 0; this.totalNum = 0; this.numGrow = growReserve; //set up reserve this.FillReserve(initialReserve); } //------------------------------------------------------------------ // PROTECTED METHODS //------------------------------------------------------------------ protected void SetReserve(int numReserve, int growReserve) { this.numGrow = growReserve; if (numReserve > this.numReserve) { this.FillReserve(numReserve - this.numReserve); } } protected Node GetReserve() { Iterator pIterator = poReserve.GetIterator(); Debug.Assert(pIterator != null); //if empty, fill reserve if (pIterator.First() == null) { this.FillReserve(this.numGrow); } //take node from reserve Node pNode = poReserve.RemoveFromFront(); Debug.Assert(pNode != null); //update stats this.numReserve--; return pNode; } protected Iterator GetActiveIterator() { return poActive.GetIterator(); } protected Node AddToFront() { Iterator pIterator = poReserve.GetIterator(); Debug.Assert(pIterator != null); //if empty, fill reserve if (pIterator.First() == null) { this.FillReserve(this.numGrow); } //take node from reserve Node pNode = poReserve.RemoveFromFront(); Debug.Assert(pNode != null); //add to active poActive.AddToFront(pNode); //update stats this.numActive++; this.numReserve--; return pNode; } protected Node AddByPriority(Node pNode) { Debug.Assert(pNode != null); //add poActive.AddByPriority(pNode); //update stats this.numActive++; return pNode; } protected void Remove(Node pNode) { //check value Debug.Assert(pNode != null); //active: remove node poActive.Remove(pNode); //reset node pNode.Reset(); //return to reserve list poReserve.AddToFront(pNode); //update stats this.numActive--; this.numReserve++; } protected Node Find(Node pNode) { Iterator pIterator = poActive.GetIterator(); Debug.Assert(pIterator != null); Node pTemp = pIterator.First(); //go thro list find node while (!pIterator.IsDone()) { if (pTemp.Compare(pNode)) //if found, exit loop { break; } pTemp = pIterator.Next(); //else, get next } return pTemp; } protected void PrintStats() { Debug.WriteLine("\n*******" + this.ToString() + " Begin *******\n"); Debug.WriteLine(" Grow Reserve by: {0} ", numGrow); Debug.WriteLine(" Total Nodes: {0} ", totalNum); Debug.WriteLine(" Total Reserve: {0} ", numReserve); Debug.WriteLine(" Total Active: {0} \n", numActive); Debug.WriteLine("\n----------- Active List: -----------\n"); Iterator pActiveIterator = poActive.GetIterator(); Debug.Assert(pActiveIterator != null); Node pActiveNode = (Node)pActiveIterator.First(); //print active head if (pActiveNode == null) { Debug.WriteLine("Active Head: null"); } else { Debug.WriteLine("Active Head: {0}", pActiveNode.GetHashCode()); } Node pData = (Node)pActiveIterator.First(); int i = 0; while (!pActiveIterator.IsDone()) { Debug.WriteLine(" {0}: -------------", i); pData.PrintStats(); i++; pData = (Node)pActiveIterator.Next(); } Debug.WriteLine("\n----------- Reserve List: ----------\n"); Iterator pReserveIterator = poReserve.GetIterator(); Debug.Assert(pReserveIterator != null); Node pReserveNode = pReserveIterator.First(); //print reserve head if (pReserveNode == null) { Debug.WriteLine("Reserve Head: null\n"); } else { Debug.WriteLine("Reserve Head: {0}\n", pReserveNode.GetHashCode()); } i = 0; pData = (Node)pReserveIterator.First(); while (!pReserveIterator.IsDone()) { Debug.WriteLine(" {0}: -------------", i); pData.PrintStats(); i++; pData = pReserveIterator.Next(); } Debug.WriteLine("\n****************** Manager End ******************\n"); } //------------------------------------------------------------------ // PRIVATE METHODS //------------------------------------------------------------------ //Helper: fill reserve pool private void FillReserve(int initialReserve) { //check value Debug.Assert(initialReserve >= 0); //update stats this.totalNum += initialReserve; this.numReserve += initialReserve; //loop to fill reserve for (int i = 0; i < initialReserve; i++) { //create node <-- linke & data Node pNode = this.derivedCreate(); Debug.Assert(pNode != null); poReserve.AddToFront(pNode); } } } //end class } //end namespace