added everything
This commit is contained in:
306
engine/core/llist.h
Executable file
306
engine/core/llist.h
Executable file
@@ -0,0 +1,306 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef LLIST_H
|
||||
#define LLIST_H
|
||||
|
||||
//***************************************************************************************
|
||||
// Linked List
|
||||
//***************************************************************************************
|
||||
// This template has an overhead of size LListNode for each entry in the linked list -
|
||||
// be aware of this for very large linked lists.
|
||||
//
|
||||
// This template has no destructor! You must explicitly call free() if you want the
|
||||
// contents of the list to be destroyed.
|
||||
//
|
||||
//
|
||||
// WARNING - this template has not been thoroughly tested so there may be bugs in it!
|
||||
//
|
||||
// -Bramage
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// LListNode template data node
|
||||
//---------------------------------------------------------------------------------------
|
||||
template <class T> class LListNode
|
||||
{
|
||||
public:
|
||||
LListNode<T> * Next;
|
||||
LListNode<T> * Prev;
|
||||
T * Data;
|
||||
|
||||
LListNode()
|
||||
{
|
||||
Next = NULL;
|
||||
Prev = NULL;
|
||||
Data = NULL;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// LList template
|
||||
//---------------------------------------------------------------------------------------
|
||||
template <class T> class LList
|
||||
{
|
||||
protected:
|
||||
LListNode< T > *first_entry;
|
||||
LListNode< T > *last_entry;
|
||||
int cnt;
|
||||
|
||||
public:
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Constructor initializes empty list
|
||||
//---------------------------------------------------------------------------------------
|
||||
LList()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Reset list to empty state by abandoning contents
|
||||
//---------------------------------------------------------------------------------------
|
||||
void reset(void)
|
||||
{
|
||||
first_entry = NULL;
|
||||
last_entry = NULL;
|
||||
cnt = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Return entry count
|
||||
//---------------------------------------------------------------------------------------
|
||||
int size(void) const
|
||||
{
|
||||
return cnt;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Return first list entry (NULL if list empty)
|
||||
//---------------------------------------------------------------------------------------
|
||||
T *first(void) const
|
||||
{
|
||||
if( first_entry ){
|
||||
return first_entry->Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Return last list entry (NULL if list empty)
|
||||
//---------------------------------------------------------------------------------------
|
||||
T *last(void) const
|
||||
{
|
||||
if( last_entry )
|
||||
{
|
||||
return last_entry->Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Returns next entry - returns first entry if current == NULL
|
||||
//---------------------------------------------------------------------------------------
|
||||
T *next( T* current )
|
||||
{
|
||||
if( current == NULL )
|
||||
{
|
||||
return first();
|
||||
}
|
||||
|
||||
LListNode<T> *next = findNode( current )->Next;
|
||||
if( next )
|
||||
{
|
||||
return next->Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Returns prev entry - returns last entry if current == NULL
|
||||
//---------------------------------------------------------------------------------------
|
||||
T *prev( T *current )
|
||||
{
|
||||
if( current == NULL )
|
||||
{
|
||||
return last();
|
||||
}
|
||||
|
||||
LListNode<T> *prev = findNode( current )->Prev;
|
||||
if( prev )
|
||||
{
|
||||
return prev->Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Link new item into list before specified entry
|
||||
// If specified entry==NULL, insert at end of list
|
||||
//---------------------------------------------------------------------------------------
|
||||
T *link(T *entry, T *next = NULL)
|
||||
{
|
||||
LListNode<T> *prevNode = NULL;
|
||||
LListNode<T> *nextNode = findNode( next );
|
||||
LListNode<T> *newNode = new LListNode<T>;
|
||||
|
||||
newNode->Data = entry;
|
||||
|
||||
if( nextNode == NULL)
|
||||
{
|
||||
prevNode = last_entry;
|
||||
last_entry = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevNode = nextNode->Prev;
|
||||
nextNode->Prev = newNode;
|
||||
}
|
||||
|
||||
if( prevNode == NULL )
|
||||
{
|
||||
first_entry = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevNode->Next = newNode;
|
||||
}
|
||||
|
||||
newNode->Next = nextNode;
|
||||
newNode->Prev = prevNode;
|
||||
|
||||
++cnt;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Link new item into list before specified entry
|
||||
// If specified entry==NULL, insert at end of list
|
||||
//---------------------------------------------------------------------------------------
|
||||
T *link(T &entry, T *next = NULL)
|
||||
{
|
||||
T *newEntry = new T;
|
||||
*newEntry = entry;
|
||||
|
||||
return link( newEntry, next );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Unlink item from list (without destroying it)
|
||||
//---------------------------------------------------------------------------------------
|
||||
void unlink(T *entry)
|
||||
{
|
||||
LListNode<T> *entryNode = findNode( entry );
|
||||
if( !entryNode ) return;
|
||||
|
||||
|
||||
if( entryNode->Prev == NULL )
|
||||
{
|
||||
first_entry = entryNode->Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
entryNode->Prev->Next = entryNode->Next;
|
||||
}
|
||||
|
||||
if( entryNode->Next == NULL )
|
||||
{
|
||||
last_entry = entryNode->Prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
entryNode->Next->Prev = entryNode->Prev;
|
||||
}
|
||||
|
||||
delete entryNode;
|
||||
|
||||
--cnt;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Allocate entry and insert before specified entry
|
||||
// If specified entry==NULL, insert at end of list
|
||||
//---------------------------------------------------------------------------------------
|
||||
T * alloc( T *next = NULL )
|
||||
{
|
||||
T *entry = new T;
|
||||
|
||||
if( entry == NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return link( entry, next );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Unlink item from list and destroy it
|
||||
//---------------------------------------------------------------------------------------
|
||||
void free(T *entry)
|
||||
{
|
||||
unlink(entry);
|
||||
delete entry;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Unlink and destroy all list items
|
||||
//---------------------------------------------------------------------------------------
|
||||
void free(void)
|
||||
{
|
||||
LListNode<T> *node = NULL;
|
||||
|
||||
while( (node = iterate( node ) )!=NULL )
|
||||
{
|
||||
LListNode<T> *nodeToKill = node;
|
||||
node = node->Prev;
|
||||
free( nodeToKill->Data );
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Find node
|
||||
//---------------------------------------------------------------------------------------
|
||||
LListNode<T> *findNode( T *entry )
|
||||
{
|
||||
LListNode<T> *it = NULL;
|
||||
while( (it = iterate( it ) )!=NULL )
|
||||
{
|
||||
if( it->Data == entry )
|
||||
{
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Returns the next node in list
|
||||
//---------------------------------------------------------------------------------------
|
||||
LListNode<T> *iterate( LListNode<T> *entry = NULL )
|
||||
{
|
||||
if( entry == NULL ) return first_entry;
|
||||
return entry->Next;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user