AwakeMUD-0.51Beta/area/
AwakeMUD-0.51Beta/doc/
AwakeMUD-0.51Beta/lib/
AwakeMUD-0.51Beta/lib/etc/
AwakeMUD-0.51Beta/lib/fixer_data/
AwakeMUD-0.51Beta/lib/misc/
AwakeMUD-0.51Beta/lib/plrobjs/
AwakeMUD-0.51Beta/lib/plrobjs/A-E/
AwakeMUD-0.51Beta/lib/plrobjs/K-O/
AwakeMUD-0.51Beta/lib/plrobjs/U-Z/
AwakeMUD-0.51Beta/lib/plrspells/A-E/
AwakeMUD-0.51Beta/lib/plrtext/A-E/
AwakeMUD-0.51Beta/lib/world/
AwakeMUD-0.51Beta/lib/world/mob/
AwakeMUD-0.51Beta/lib/world/obj/
AwakeMUD-0.51Beta/lib/world/qst/
AwakeMUD-0.51Beta/lib/world/shp/
AwakeMUD-0.51Beta/lib/world/wld/
AwakeMUD-0.51Beta/lib/world/zon/
/**************************************************************************/
/*  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