/**************************************************************************/
/* file: memory.h - 1/21/96 -- Christopher J. Dickey */
/* This is a set of classes to handle memory for the mud. There's */
/* not a whole lot of fancy stuff behind them, but they do help in */
/* efficiency. Basically, we never really delete any memory unless */
/* absolutely necessary, and we keep stacks of the most used */
/* objects. */
/**************************************************************************/
#ifndef _memory_h_
#define _memory_h_
#define INITIAL_STACK_SIZE 100
#define STACK_SIZE_INCREASE 100
#include "structs.h"
#include "utils.h"
template <class T>
class stackClass
{
public:
// constructors and destructors
stackClass();
stackClass(const stackClass<T>& O);
~stackClass();
// stack routines
int Size() { return (top + 1); }
int MaxSize() { return max_size; }
void Push(T *NewItem);
T *Pop();
void PopDelete();
bool StackIsEmpty() { return (top < 0 ? 1 : 0); }
private:
// private data for the stack
int top;
int max_size;
// Precondition: objStackClass must be created already
// Postcondition: the stack will be increased by the constant
// OBJ_STACK_SIZE_INCREASE. If it's increased, TRUE is returned
// else FALSE.
bool ResizeStack();
// This is the array of objects
T **Items;
}; // end class
template <class T>
stackClass<T>::stackClass()
{
max_size = INITIAL_STACK_SIZE;
Items = new T*[max_size];
top = -1;
}
template <class T>
stackClass<T>::stackClass(const stackClass<T>& O)
{
max_size = O.max_size;
top = O.top;
for (register int Index = 0; Index <= O.top; ++Index)
Items[Index] = O.Items[Index];
}
template <class T>
stackClass<T>::~stackClass()
{
while (top >= 0)
PopDelete();
}
template <class T>
void stackClass<T>::Push(T *NewItem)
{
#ifdef DEBUG
// this makes sure no duplicate objects are pushed onto the stack
for (register int i = 0; i <= top; ++i)
if (Items[i] == NewItem)
abort();
#endif
// make sure you have room in the array
if (top < max_size - 1) {
++top;
Items[top] = NewItem;
} else { // if not, resize the array (larger), and re-Push the item
assert(ResizeStack());
Push(NewItem);
}
}
template <class T>
T *stackClass<T>::Pop()
{
if (top < 0)
return NULL;
--top;
return (Items[top + 1]);
}
template <class T>
void stackClass<T>::PopDelete()
{
if (top < 0)
return;
--top;
// we just call delete on the object since we know it's insides
// have already been cleared up when it was put on the stack
delete (Items[top + 1]);
}
template <class T>
bool stackClass<T>::ResizeStack()
{
// create a new stack array larger than the previous
T **NewItems;
NewItems = new T*[max_size + STACK_SIZE_INCREASE];
// now copy the old stack array into the new one
for (register int Index = 0; Index <= top; ++Index)
NewItems[Index] = Items[Index];
// delete the elements of the old stack
// what were you thinking, Chris? DON'T delete the elements of the stack,
// as we just passed the pointers to them above! Just get rid of the array
// itself
// delete [] *Items;
delete Items;
// point Items to the new stack now
Items = NewItems;
max_size += STACK_SIZE_INCREASE;
mudlog("Resizing Stack...", NULL, LOG_SYSLOG, TRUE);
return TRUE;
}
class memoryClass
{
private:
class stackClass<struct obj_data> *Obj;
class stackClass<struct char_data> *Ch;
class stackClass<struct room_data> *Room;
public:
// constructors and destructors
memoryClass();
~memoryClass();
memoryClass(const memoryClass& mClass);
// size operations for general info
int ObjSize() { return Obj->Size(); }
int ChSize() { return Ch->Size(); }
int RoomSize() { return Room->Size(); }
int ObjMaxSize() { return Obj->MaxSize(); }
int ChMaxSize() { return Ch->MaxSize(); }
int RoomMaxSize() { return Room->MaxSize(); }
// get routines which return objects from the different stacks
struct obj_data *GetObject();
struct char_data *GetCh();
struct room_data *GetRoom();
// delete routines which push objects onto the stacks after deallocating
// all strings and such in the object
void DeleteObject(struct obj_data *obj);
void DeleteCh(struct char_data *ch);
void DeleteRoom(struct room_data *room);
// clear routines which push objects onto the stacks after just clearing
// the variables and pointers in the objects. These will not wipe out
// the strings and other allocated vars
void ClearObject(struct obj_data *obj);
void ClearCh(struct char_data *ch);
void ClearRoom(struct room_data *room);
// clear stacks
bool ClearStacks();
};
#endif