/*
** Command & Conquer Generals(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 .
*/
//
// list.cpp
//
#include "stdAfx.h"
#include
#include "list.h"
ListNode::ListNode ( void )
{
prev = next = this;
pri = NORMAL_PRIORITY;
item = NULL;
}
void ListNode::Append ( ListNode *new_node )
{
assert ( ! new_node->InList()); /* node is already in a list or was not initialized*/
new_node->prev = this;
new_node->next = next;
next = new_node;
new_node->next->prev = new_node;
}
void ListNode::Prepend ( ListNode *new_node )
{
assert ( !new_node->InList() ); /* node is already in a list or was not initialized*/
new_node->prev = prev;
new_node->next = this;
prev = new_node;
new_node->prev->next = new_node;
}
void ListNode::Link ( ListNode *node)
{
next = node;
node->prev = next;
}
void ListNode::Remove ( void )
{
prev->next = next;
next->prev = prev;
prev = next = this; /* so we know that the node is not in a list */
}
ListNode* ListNode::Next ( void )
{
if ( next->IsHead ( ) )
{
return NULL;
}
return next;
}
ListNode* ListNode::Prev ( void )
{
if ( prev->IsHead () )
{
return NULL;
}
return prev;
}
ListNode* ListNode::NextLoop ( void )
{
ListNode *next_node = next;
if ( next_node->IsHead ( ))
{
/* skip head node */
next_node = next_node->next;
if ( next_node->IsHead ( ))
{
return NULL; /* it is an empty list */
}
}
return next_node;
}
ListNode* ListNode::PrevLoop ( void )
{
ListNode *prev_node = prev;
if ( prev_node->IsHead ( ))
{
/* skip head node */
prev_node = prev_node->prev;
if ( prev_node->IsHead ( ))
{
return NULL; /* it is an empty list */
}
}
return prev_node;
}
void* ListNode::Item ( void )
{
assert ( !IsHead () );
return item;
}
void ListNode::SetItem ( void *new_item )
{
assert ( !IsHead () );
item = new_item ;
}
int ListNode::InList ( void )
{
return prev != this;
}
int ListNode::IsHead ( void )
{
return item == &this->item;
}
int ListNode::Priority ( void )
{
return pri;
}
void ListNode::SetPriority ( int new_pri )
{
assert ( new_pri <= HIGHEST_PRIORITY );
assert ( new_pri >= LOWEST_PRIORITY );
pri = new_pri;
}
List::List ( void )
{
SetItem ( &this->item );
}
void List::AddToTail ( ListNode *node )
{
assert ( IsHead ());
Prepend ( node );
}
void List::AddToHead ( ListNode *node )
{
assert ( IsHead ());
Append ( node );
}
void List::Add ( ListNode *new_node )
{
ListNode* node;
int pri;
assert ( IsHead ());
assert ( !new_node->InList ());
pri = new_node->Priority();
node = FirstNode ( );
while( node )
{
if (node->Priority() <= pri )
{
node->Prepend ( new_node );
return;
}
node = node->Next ();
}
Prepend ( new_node );
}
void List::Merge ( List *list )
{
ListNode *first,
*last,
*node;
assert ( IsHead ());
first = list->Next();
last = list->Prev();
if ( !first || !last )
{
return;
}
node = Prev();
node->Link ( first );
last->Link ( this );
list->Empty ();
}
int List::NumItems ( void )
{
int count = 0;
ListNode *node;
assert ( IsHead ());
node = FirstNode();
while ( node )
{
count++;
node = node->Next ();
}
return count;
}
void* List::Item ( int list_index )
{
ListNode *node;
assert ( IsHead ());
node = FirstNode();
while (list_index && node )
{
list_index--;
node = node->Next ();
}
if ( node )
{
return node->Item();
}
return NULL;
}
ListNode* List::FirstNode ( void )
{
assert ( IsHead ());
return Next ();
}
ListNode* List::LastNode ( void )
{
assert ( IsHead ());
return Prev ();
}
int List::IsEmpty ( void )
{
assert ( IsHead ());
return !InList();
}
void List::Empty ( void )
{
assert ( IsHead ());
Remove ();
}
ListNode* List::Find ( void *item )
{
ListNode *node;
node = FirstNode ();
while ( node )
{
if ( node->Item () == item )
{
return node;
}
node = node->Next ();
}
return NULL;
}