Crystal Space: csutil/pooledscfclass.h Source File (Crystal Space Public API Reference)

| ## Public API Reference

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# csutil/pooledscfclass.h

Go to the documentation of this file.

    00001 /*
    00002     Copyright (C) 2004 by Jorrit Tyberghein
    00003               (C) 2004 by Frank Richter
    00004
    00005     This library is free software; you can redistribute it and/or
    00006     modify it under the terms of the GNU Library General Public
    00007     License as published by the Free Software Foundation; either
    00008     version 2 of the License, or (at your option) any later version.
    00009
    00010     This library is distributed in the hope that it will be useful,
    00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013     Library General Public License for more details.
    00014
    00015     You should have received a copy of the GNU Library General Public
    00016     License along with this library; if not, write to the Free
    00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00018 */
    00019
    00020 #ifndef __CS_UTIL_POOLEDSCFCLASS_H__
    00021 #define __CS_UTIL_POOLEDSCFCLASS_H__
    00022
    00031 #include "csutil/scf.h"
    00032
    00033 #include "csutil/custom_new_disable.h"
    00034
    00060 template<typename Super>
    00061 class scfImplementationPooled : public Super
    00062 {
    00063   typedef typename Super::scfClassType scfClassType;
    00064 public:
    00065   typedef scfImplementationPooled<Super> scfPooledImplementationType;
    00066
    00067   class Pool
    00068   {
    00069     friend class scfImplementationPooled<Super>;
    00070     struct Entry
    00071     {
    00072       Entry* next;
    00073     };
    00074     Entry* pool;
    00075     size_t allocedEntries;
    00076   #ifdef CS_MEMORY_TRACKER
    00077     csMemTrackerInfo* mti;
    00078   #endif
    00079   public:
    00080     Pool () : pool (0), allocedEntries (0)
    00081     {
    00082   #ifdef CS_MEMORY_TRACKER
    00083       mti = 0;
    00084   #endif
    00085     }
    00086     ~Pool ()
    00087     {
    00088       while (pool != 0)
    00089       {
    00090         Entry* n = pool->next;
    00091         cs_free (pool);
    00092       #ifdef CS_MEMORY_TRACKER
    00093         mtiUpdateAmount (mti, -1,
    00094           -int(sizeof (scfClassType) + sizeof (Entry)));
    00095       #endif
    00096         pool = n;
    00097       }
    00098       CS_ASSERT_MSG ("not all SCF-pooled instances released",
    00099         allocedEntries == 0);
    00100     }
    00101   };
    00102 protected:
    00104   Pool* scfPool;
    00105 public:
    00107   inline void* operator new (size_t n, Pool& p)
    00108   {
    00109     typedef typename Pool::Entry PoolEntry;
    00110     CS_ASSERT_MSG ("Alloc size mismatches class size expected for pooled "
    00111       "allocation", n == sizeof (scfClassType));
    00112     PoolEntry* newEntry;
    00113     if (p.pool != 0)
    00114     {
    00115       newEntry = p.pool;
    00116       p.pool = p.pool->next;
    00117     }
    00118     else
    00119     {
    00120       newEntry = static_cast<PoolEntry*> (cs_malloc (n));
    00121     #ifdef CS_MEMORY_TRACKER
    00122       if (p.mti == 0)
    00123       {
    00124         p.mti = mtiRegisterAlloc (n, typeid (Pool).name());
    00125       }
    00126       else
    00127         mtiUpdateAmount (p.mti, 1, (int)n);
    00128     #endif
    00129     }
    00130     p.allocedEntries++;
    00131     scfClassType* newInst = reinterpret_cast<scfClassType*> (newEntry);
    00132     /* A bit nasty: set scfPool member of the (still unconstructed!)
    00133      * instance... */
    00134     static_cast<scfPooledImplementationType*> (newInst)->scfPool = &p;
    00135     return newInst;
    00136   }
    00137
    00139
    00140   inline void operator delete (void* instance, Pool& p)
    00141   {
    00142     typedef typename Pool::Entry PoolEntry;
    00143     PoolEntry* entry = static_cast<PoolEntry*> (instance);
    00144     entry->next = p.pool;
    00145     p.pool = entry;
    00146     p.allocedEntries--;
    00147   }
    00148   inline void operator delete (void* instance)
    00149   {
    00150     scfClassType* object = static_cast<scfClassType*> (instance);
    00151     Pool& p = *(static_cast<scfImplementationPooled*> (object)->scfPool);
    00152     scfImplementationPooled::operator delete (object, p);
    00153   }
    00155
    00157   void DecRef ()
    00158   {
    00159     if (this->scfRefCount == 1)
    00160     {
    00161       delete this->scfObject;
    00162       return;
    00163     }
    00164     this->scfRefCount--;
    00165   }
    00166
    00168
    00171   scfImplementationPooled (scfClassType* object) :
    00172     Super (object) {}
    00173   template<typename A>
    00174   scfImplementationPooled (scfClassType* object, A a) :
    00175     Super (object, a) {}
    00176   template<typename A, typename B>
    00177   scfImplementationPooled (scfClassType* object, A a, B b) :
    00178     Super (object, a, b) {}
    00179   template<typename A, typename B, typename C>
    00180   scfImplementationPooled (scfClassType* object, A a, B b, C c) :
    00181     Super (object, a, b, c) {}
    00182   template<typename A, typename B, typename C, typename D>
    00183   scfImplementationPooled (scfClassType* object, A a, B b, C c, D d) :
    00184     Super (object, a, b, c, d) {}
    00185   template<typename A, typename B, typename C, typename D, typename E>
    00186   scfImplementationPooled (scfClassType* object, A a, B b, C c, D d, E e) :
    00187     Super (object, a, b, c, d, e) {}
    00189 };
    00190
    00193 #include "csutil/custom_new_enable.h"
    00194
    00195 #endif // __CS_UTIL_POOLEDSCFCLASS_H__