CrystalSpace

Public API Reference

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__

Generated for Crystal Space by doxygen 1.4.7