⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pool.h

📁 游戏编程精粹2第四章源码
💻 H
字号:
/* Copyright (C) John W. Ratcliff, 2001. 
 * All rights reserved worldwide.
 *
 * This software is provided "as is" without express or implied
 * warranties. You may freely copy and compile this source into
 * applications you distribute provided that the copyright text
 * below is included in the resulting source code, for example:
 * "Portions Copyright (C) John W. Ratcliff, 2001"
 */
#ifndef POOL_H

#define POOL_H


/***********************************************************************/
/** POOL        : Template class to manage a fixed pool of items for   */
/**               extremely fast allocation and deallocation.          */
/**                                                                    */
/**               Written by John W. Ratcliff jratcliff@att.net        */
/***********************************************************************/

template <class Type> class Pool
{
public:
  Pool(void)
  {
    mHead = 0;
    mFree = 0;
    mData = 0;
    mCurrent = 0;
    mFreeCount = 0;
    mUsedCount = 0;
  };

  ~Pool(void)
  {
    delete mData;
  };


  void Release(void)
  {
    mHead = 0;
    mFree = 0;
    delete mData;
    mData = 0;
    mCurrent = 0;
    mFreeCount = 0;
    mUsedCount = 0;
  };

  void Set(int maxitems)
  {
    delete mData; // delete any previous incarnation.
    mMaxItems = maxitems;
    mData = new Type[mMaxItems];
    mFree = mData;
    mHead = 0;
    for (int i=0; i<(mMaxItems-1); i++)
    {
      mData[i].SetNext( &mData[i+1] );
      if ( i == 0 )
        mData[i].SetPrevious( 0 );
      else
        mData[i].SetPrevious( &mData[i-1] );
    }

    mData[i].SetNext(0);
    mData[i].SetPrevious( &mData[i-1] );
    mCurrent = 0; // there is no current, currently. <g>
    mFreeCount = maxitems;
    mUsedCount = 0;
  };


  Type * GetNext(bool &looped)
  {

    looped = false; //default value

    if ( !mHead ) return 0; // there is no data to process.
    Type *ret;

    if ( !mCurrent )
    {
      ret = mHead;
      looped = true;
    }
    else
    {
      ret = mCurrent;
    }

    if ( ret ) mCurrent = ret->GetNext();


    return ret;
  };

  bool IsEmpty(void) const
  {
    if ( !mHead ) return true;
    return false;
  };

  int Begin(void)
  {
    mCurrent = mHead;
    return mUsedCount;
  };

  int GetUsedCount(void) const { return mUsedCount; };
  int GetFreeCount(void) const { return mFreeCount; };

  Type * GetNext(void)
  {
    if ( !mHead ) return 0; // there is no data to process.

    Type *ret;

    if ( !mCurrent )
    {
      ret = mHead;
    }
    else
    {
      ret = mCurrent;
    }

    if ( ret ) mCurrent = ret->GetNext();


    return ret;
  };

  void Release(Type *t)
  {

    if ( t == mCurrent ) mCurrent = t->GetNext();

    // first patch old linked list.. his previous now points to his next
    Type *prev = t->GetPrevious();

    if ( prev )
    {
      Type *next = t->GetNext();
      prev->SetNext( next ); // my previous now points to my next
      if ( next ) next->SetPrevious(prev);
      // list is patched!
    }
    else
    {
      Type *next = t->GetNext();
      mHead = next;
      if ( mHead ) mHead->SetPrevious(0);
    }

    Type *temp = mFree; // old head of free list.
    mFree = t; // new head of linked list.
    t->SetPrevious(0);
    t->SetNext(temp);

    mUsedCount--;
    mFreeCount++;
  };

  Type * GetFreeNoLink(void) // get free, but don't link it to the used list!!
  {
    // Free allocated items are always added to the head of the list
    if ( !mFree ) return 0;
    Type *ret = mFree;
    mFree = ret->GetNext(); // new head of free list
    mUsedCount++;
    mFreeCount--;
    ret->SetNext(0);
    ret->SetPrevious(0);
    return ret;
  };

  Type * GetFreeLink(void)
  {
    // Free allocated items are always added to the head of the list
    if ( !mFree ) return 0;
    Type *ret = mFree;
    mFree = ret->GetNext(); // new head of free list
    Type *temp = mHead; // current head of list
    mHead = ret;        // new head of list is this free one
    if ( temp ) temp->SetPrevious(ret);
    mHead->SetNext(temp);
    mHead->SetPrevious(0);
    mUsedCount++;
    mFreeCount--;
    return ret;
  };

  void AddAfter(Type *e,Type *item)
  {
    // Add 'item' after 'e'
    if ( e )
    {
      Type *eprev = e->GetPrevious();
      Type *enext = e->GetNext();
      e->SetNext(item);
      item->SetNext(enext);
      item->SetPrevious(e);
      if ( enext ) enext->SetPrevious(item);
    }
    else
    {
      mHead = item;
      item->SetPrevious(0);
      item->SetNext(0);
    }

  }

  void AddBefore(Type *e,Type *item)
  {
    // Add 'item' before 'e'
    Type *eprev = e->GetPrevious();
    Type *enext = e->GetNext();

    if ( !eprev ) 
      mHead = item;
    else
      eprev->SetNext(item);

    item->SetPrevious(eprev);
    item->SetNext(e);

    e->SetPrevious(item);

  }


private:
  int   mMaxItems;
  Type *mCurrent; // current iteration location.
  Type *mData;
  Type *mHead; // head of used list.
  Type *mFree; // head of free list.
  int   mUsedCount;
  int   mFreeCount;
};

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -