CnC_Remastered_Collection/REDALERT/LINK.CPP

399 lines
24 KiB
C++

//
// 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);
}