// // Copyright 2020 Electronic Arts Inc. // // TiberianDawn.DLL and RedAlert.dll and corresponding source code 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. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed // in the hope that it will be useful, but with permitted additional restrictions // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT // distributed with this program. You should have received a copy of the // GNU General Public License along with permitted additional restrictions // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection /* $Header: /CounterStrike/LINK.CPP 1 3/03/97 10:25a Joe_bostic $ */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : Command & Conquer * * * * File Name : LINK.CPP * * * * Programmer : Joe L. Bostic * * * * Start Date : 01/15/95 * * * * Last Update : January 19, 1995 [JLB] * * * *---------------------------------------------------------------------------------------------* * Functions: * * LinkClass::Add -- This object adds itself to the given list * * LinkClass::Add_Head -- This gadget makes itself the head of the given list. * * LinkClass::Add_Tail -- Add myself to the end of the given list. * * LinkClass::Get_Next -- Fetches the next object in list. * * LinkClass::Get_Prev -- Fetches previous object in linked list. * * LinkClass::Head_Of_List -- Finds the head of the list. * * LinkClass::LinkClass -- Copy constructor for linked list object. * * LinkClass::Remove -- Removes the specified object from the list. * * LinkClass::Tail_Of_List -- Scans for the object at the end of the list. * * LinkClass::Zap -- Forces the link pointers to NULL. * * LinkClass::operator= -- Assignment operator for linked list class object. * * LinkClass::~LinkClass -- Default destructor for linked list object. * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "function.h" #include "link.h" /*********************************************************************************************** * LinkClass::LinkClass -- Copy constructor for linked list object. * * * * This copy constructor, unlike the assignment operator, doesn't have to deal with an * * already initialized and legal link object to the left of the "=". It merely puts the * * destination object into the same list as the source object. * * * * INPUT: link -- Reference to the object on the right of the "=". * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ LinkClass::LinkClass(LinkClass const & link) : Next(0), Prev(0) { /* ** Add this object to the same list that the copy object ** resides in. */ Add((LinkClass &)link); } /*********************************************************************************************** * LinkClass::~LinkClass -- Default destructor for linked list object. * * * * This default destructor will remove the object from any linked list it may be part of. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ LinkClass::~LinkClass(void) { Remove(); } /*********************************************************************************************** * LinkClass::Zap -- Forces the link pointers to NULL. * * * * This routine will "zap" out the link pointers. This is usually necessary when the link * * pointers start in an undefined state, but we KNOW that they aren't pointing to anything * * valid. In such a case it becomes necessary to zap them so that when the object is added * * to a list, it will be added correctly. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 01/19/1995 JLB : Created. * *=============================================================================================*/ void LinkClass::Zap(void) { Next = 0; Prev = 0; } /*********************************************************************************************** * LinkClass::operator= -- Assignment operator for linked list class object. * * * * The assignment operator makes sure that the previous and next pointers remain valid. * * Because this class only consists of pointers, the assignment operator doesn't actually * * transfer any data from the source object. It merely makes the destination object part * * of the same list as the source object. In essence, this is transferring information * * but not the actual values. * * * * If the destination object is already part of another list, it is removed from that list * * before being added to the source object's list. This ensures that either list remains * * in a valid condition. * * * * INPUT: link -- The object to the right of the "=" operator. * * * * OUTPUT: Returns a reference to the rightmost object -- per standard assignment rules. * * * * WARNINGS: none * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ LinkClass & LinkClass::operator = (LinkClass const & link) { if (&link == this) return(*this); Remove(); Add((LinkClass &)link); return(*this); } /*********************************************************************************************** * LinkClass::Get_Next -- Fetches the next object in list. * * * * This routine will return with a pointer to the next object in the list. If there are * * no more objects, then NULL is returned. * * * * INPUT: none * * * * OUTPUT: Returns with pointer to next object in list or NULL if at end of list. * * * * WARNINGS: none * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ LinkClass * LinkClass::Get_Next(void) const { return(Next); } /*********************************************************************************************** * LinkClass::Get_Prev -- Fetches previous object in linked list. * * * * Use this routine to get a pointer to the previous object in the linked list. If there * * are no previous objects (such as at the head of the list), then NULL is returned. * * * * INPUT: none * * * * OUTPUT: Returns with a pointer to the previous object in the list or NULL if none. * * * * WARNINGS: none * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ LinkClass * LinkClass::Get_Prev(void) const { return(Prev); } /*********************************************************************************************** * LinkClass::Head_Of_List -- Finds the head of the list. * * * * Use this routine to scan for and return a reference to the object at the head of the * * list. * * * * INPUT: none * * * * OUTPUT: Returns with a reference to the object at the head of the list. * * * * WARNINGS: none * * * * HISTORY: * * 01/19/1995 JLB : Created. * *=============================================================================================*/ LinkClass & LinkClass::Head_Of_List(void) { LinkClass * link = this; while (link->Prev) { link = link->Prev; if (link == this) break; // Safety check } return(*link); } /*********************************************************************************************** * LinkClass::Tail_Of_List -- Scans for the object at the end of the list. * * * * Use this routine to scan for and return a reference to the object at the end of the * * list. * * * * INPUT: none * * * * OUTPUT: Returns with a reference to the object at the end of the list. * * * * WARNINGS: none * * * * HISTORY: * * 01/19/1995 JLB : Created. * *=============================================================================================*/ LinkClass & LinkClass::Tail_Of_List(void) { LinkClass * link = this; while (link->Next) { link = link->Next; if (link == this) break; // Safety check } return(*link); } /*********************************************************************************************** * LinkClass::Add -- This object adds itself to the given list * * * * Use this routine to add a link object to the list, but to be added right after the * * given link. This allows inserting a link in the middle of the chain. A quite necessary * * ability if the chain is order dependant (e.g., the gadget system). * * * * INPUT: list -- gadget object to add this one to * * * * OUTPUT: Returns with a pointer to the head of the list. * * * * WARNINGS: none * * * * HISTORY: * * 01/19/1995 JLB : Created. * *=============================================================================================*/ LinkClass & LinkClass::Add(LinkClass & list) { LinkClass * ptr; /* ** Save ptr to next gadget. */ ptr = list.Next; /* ** Link myself in after 'list'. */ list.Next = this; Prev = &list; /* ** Link myself to next gadget, if there is one. */ Next = ptr; if (ptr) { ptr->Prev = this; } return(Head_Of_List()); } /*********************************************************************************************** * LinkClass::Add_Head -- This gadget makes itself the head of the given list. * * * * INPUT: list -- the list to make myself the head of * * * * OUTPUT: Returns with a reference to the object at the head of the list. This should be * * the same object that is passed in. * * * * WARNINGS: none * * * * HISTORY: * * 01/19/1995 JLB : Created. * *=============================================================================================*/ LinkClass & LinkClass::Add_Head(LinkClass & list) { LinkClass * ptr; /* ** Get head of given list. */ ptr = &list.Head_Of_List(); /* ** Link myself in front of it. */ ptr->Prev = this; Next = ptr; Prev = NULL; return(*this); } /*********************************************************************************************** * LinkClass::Add_Tail -- Add myself to the end of the given list. * * * * INPUT: list -- list to add myself to * * * * OUTPUT: the head of the list * * * * WARNINGS: The previous and next pointers for the added object MUST have been properly * * initialized for this routine to work correctly. * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ LinkClass & LinkClass::Add_Tail(LinkClass & list) { LinkClass * ptr; /* ** Get head of given list. */ ptr = &list.Tail_Of_List(); /* ** Link myself in front of it. */ ptr->Next = this; Prev = ptr; Next = NULL; return(Head_Of_List()); } /*********************************************************************************************** * LinkClass::Remove -- Removes the specified object from the list. * * * * This routine will remove the specified object from the list of objects. Because of the * * previous and next pointers, it is possible to remove an object from the list without * * knowing the head of the list. To do this, just call Remove() with the parameter of * * "this". * * * * INPUT: none * * * * OUTPUT: Returns with the new head of list. * * * * WARNINGS: none * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ LinkClass * LinkClass::Remove(void) { LinkClass * head = &Head_Of_List(); LinkClass * tail = &Tail_Of_List(); if (Prev) { Prev->Next = Next; } if (Next) { Next->Prev = Prev; } Prev = 0; Next = 0; if (head==this) { if (tail==this) { return(0); } return(&tail->Head_Of_List()); } return(head); }