2020-04-22 16:56:21 +00:00
|
|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
|
|
//
|
|
|
|
// Purpose:
|
|
|
|
//
|
|
|
|
// $NoKeywords: $
|
|
|
|
//
|
|
|
|
//=============================================================================//
|
|
|
|
#include <stdio.h>
|
2022-02-23 11:56:29 +00:00
|
|
|
#ifdef OSX
|
|
|
|
#include <malloc/malloc.h>
|
|
|
|
#else
|
2020-04-22 16:56:21 +00:00
|
|
|
#include <malloc.h>
|
2022-02-23 11:56:29 +00:00
|
|
|
#endif
|
2020-04-22 16:56:21 +00:00
|
|
|
#include "ObjectList.h"
|
|
|
|
#include "tier1/strtools.h"
|
|
|
|
|
|
|
|
//#include "port.h"
|
|
|
|
//#include "mem.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
|
|
#include <tier0/memdbgon.h>
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// Construction/Destruction
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
ObjectList::ObjectList()
|
|
|
|
{
|
|
|
|
head = tail = current = NULL;
|
|
|
|
number = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjectList::~ObjectList()
|
|
|
|
{
|
|
|
|
Clear( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ObjectList::AddHead(void * newObject)
|
|
|
|
{
|
|
|
|
// create new element
|
|
|
|
element_t * newElement = (element_t *) calloc(1, sizeof(element_t));
|
|
|
|
|
|
|
|
if (newElement == NULL )
|
|
|
|
return false; // out of memory
|
|
|
|
|
|
|
|
// insert element
|
|
|
|
newElement->object = newObject;
|
|
|
|
|
|
|
|
if (head)
|
|
|
|
{
|
|
|
|
newElement->next = head;
|
|
|
|
head->prev = newElement;
|
|
|
|
};
|
|
|
|
|
|
|
|
head = newElement;
|
|
|
|
|
|
|
|
// if list was empty set new tail
|
|
|
|
if (tail==NULL) tail = head;
|
|
|
|
|
|
|
|
number++;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void * ObjectList::RemoveHead()
|
|
|
|
{
|
|
|
|
void * retObj;
|
|
|
|
|
|
|
|
// check head is present
|
|
|
|
if (head)
|
|
|
|
{
|
|
|
|
retObj = head->object;
|
|
|
|
element_t * newHead = head->next;
|
|
|
|
if (newHead) newHead->prev = NULL;
|
|
|
|
|
|
|
|
// if only one element is in list also update tail
|
|
|
|
// if we remove this prev element
|
|
|
|
if (tail==head) tail = NULL;
|
|
|
|
|
|
|
|
free(head);
|
|
|
|
head = newHead;
|
|
|
|
|
|
|
|
number--;
|
|
|
|
|
|
|
|
} else
|
|
|
|
retObj = NULL;
|
|
|
|
|
|
|
|
return retObj;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ObjectList::AddTail(void * newObject)
|
|
|
|
{
|
|
|
|
element_t * newElement = (element_t *) calloc(1, sizeof(element_t));
|
|
|
|
|
|
|
|
if (newElement == NULL)
|
|
|
|
return false; // out of memory;
|
|
|
|
|
|
|
|
newElement->object = newObject;
|
|
|
|
|
|
|
|
if (tail)
|
|
|
|
{
|
|
|
|
newElement->prev = tail;
|
|
|
|
tail->next = newElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
tail = newElement;
|
|
|
|
|
|
|
|
// if list was empty set new head
|
|
|
|
if (head==NULL) head = tail;
|
|
|
|
|
|
|
|
number++;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void * ObjectList::RemoveTail()
|
|
|
|
{
|
|
|
|
void * retObj;
|
|
|
|
|
|
|
|
// check tail is present
|
|
|
|
if (tail)
|
|
|
|
{
|
|
|
|
retObj = tail->object;
|
|
|
|
element_t * newTail = tail->prev;
|
|
|
|
if (newTail) newTail->next = NULL;
|
|
|
|
|
|
|
|
// if only one element is in list also update tail
|
|
|
|
// if we remove this prev element
|
|
|
|
if (head==tail) head = NULL;
|
|
|
|
|
|
|
|
free(tail);
|
|
|
|
tail = newTail;
|
|
|
|
|
|
|
|
number--;
|
|
|
|
|
|
|
|
} else
|
|
|
|
retObj = NULL;
|
|
|
|
|
|
|
|
return retObj;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ObjectList::IsEmpty()
|
|
|
|
{
|
|
|
|
return ( head == NULL );
|
|
|
|
}
|
|
|
|
|
|
|
|
int ObjectList::CountElements()
|
|
|
|
{
|
|
|
|
return number;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ObjectList::Contains(void * object)
|
|
|
|
{
|
|
|
|
element_t * e = head;
|
|
|
|
|
|
|
|
while(e && e->object!=object) { e = e->next;}
|
|
|
|
|
|
|
|
if ( e )
|
|
|
|
{
|
|
|
|
current = e;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjectList::Clear( bool freeElementsMemory )
|
|
|
|
{
|
|
|
|
element_t * ne;
|
|
|
|
|
|
|
|
element_t * e = head;
|
|
|
|
while(e)
|
|
|
|
{
|
|
|
|
ne = e->next;
|
|
|
|
|
|
|
|
if ( freeElementsMemory && e->object )
|
|
|
|
free( e->object );
|
|
|
|
|
|
|
|
free(e);
|
|
|
|
e = ne;
|
|
|
|
}
|
|
|
|
|
|
|
|
head = tail = current = NULL;
|
|
|
|
number = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ObjectList::Remove( void * object )
|
|
|
|
{
|
|
|
|
element_t * e = head;
|
|
|
|
|
|
|
|
while(e && e->object!=object) { e = e->next;}
|
|
|
|
|
|
|
|
if (e!=NULL)
|
|
|
|
{
|
|
|
|
if (e->prev) e->prev->next = e->next;
|
|
|
|
if (e->next) e->next->prev = e->prev;
|
|
|
|
if (head==e) head = e->next;
|
|
|
|
if (tail==e) tail = e->prev;
|
|
|
|
if (current == e) current= e->next;
|
|
|
|
free(e);
|
|
|
|
number--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (e!=NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjectList::Init()
|
|
|
|
{
|
|
|
|
head = tail = current = NULL;
|
|
|
|
number = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void * ObjectList::GetFirst()
|
|
|
|
{
|
|
|
|
if (head)
|
|
|
|
{
|
|
|
|
current = head->next;
|
|
|
|
return head->object;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
current = NULL;
|
|
|
|
return NULL;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void * ObjectList::GetNext()
|
|
|
|
{
|
|
|
|
void * retObj = NULL;
|
|
|
|
if (current)
|
|
|
|
{
|
|
|
|
retObj = current->object;
|
|
|
|
current = current->next;
|
|
|
|
}
|
|
|
|
return retObj;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ObjectList::Add(void *newObject)
|
|
|
|
{
|
|
|
|
return AddTail( newObject );
|
|
|
|
}
|
|
|
|
|