/**************************************************************************/ /* 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