/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /****************************************************************************** * * FILE * * DESCRIPTION * * PROGRAMMER * Denzil E. Long, Jr. * * VERSION INFO * $Author: Denzil_l $ * $Revision: 2 $ * $Modtime: 3/29/00 2:20p $ * $Archive: /Commando/Code/Scripts/ScriptNode.h $ * ******************************************************************************/ #ifndef _SCRIPTNODE_H_ #define _SCRIPTNODE_H_ #include "dprint.h" class ScriptNode { public: virtual ~ScriptNode() {} protected: friend class ScriptList; friend class ScriptListIter; // Retrieve next node inline ScriptNode* GetNext(void) const { return mNext; } // Set next node inline void SetNext(ScriptNode* link) { if (mNext != NULL) { assert(link != NULL); link->SetNext(mNext); } mNext = link; } // Can only be derived ScriptNode() : mNext(NULL) {} private: ScriptNode* mNext; }; class ScriptList { public: ScriptList() : mHead(NULL) {DebugPrint("ScriptList\n");} virtual ~ScriptList() {} // Add a node to this list void AddNode(ScriptNode* node) { if ((node != NULL) && !HasNode(node)) { node->SetNext(mHead); mHead = node; } } // Remove a node from the list bool RemoveNode(ScriptNode* node) { ScriptNode* previous = NULL; ScriptNode* current = mHead; while (current != NULL) { ScriptNode* next = current->GetNext(); if (current == node) { // Handle head of list condition if (previous == NULL) { mHead = next; } else { previous->SetNext(next); } return true; } // Advance to next node previous = current; current = next; } return false; } // Count the number of node in the list. int CountNodes(void) const { ScriptNode* node = mHead; int count = 0; while (node != NULL) { count++; node = node->GetNext(); } return count; } // Check if a node exists in the list. bool HasNode(ScriptNode* node) const { ScriptNode* current = mHead; while (current != NULL) { if (current == node) { return true; } current = current->GetNext(); } return false; } // Clear the list void Clear(void) { mHead = NULL; } private: friend class ScriptListIter; ScriptNode* mHead; }; // Script list iterator: This class is used to traverse or iterate a list. class ScriptListIter { public: ScriptListIter(const ScriptList& list) : mList(&list), mCurrent(list.mHead) {} // Set iterator to first node inline ScriptNode* First(void) { mCurrent = mList->mHead; return mCurrent; } // Retrieve current node inline ScriptNode* Current(void) { return mCurrent; } // Advance to next node inline void Next(void) { mCurrent = mCurrent->GetNext(); } // Test if at end of list inline bool AtEnd(void) { return (mCurrent->GetNext() == NULL); } private: const ScriptList* mList; ScriptNode* mCurrent; }; #endif // _SCRIPTNODE_H_