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, typename Allocator = CS::Memory::AllocatorMalloc>
00061 class scfImplementationPooled : public Super
00062 {
00063   typedef typename Super::scfClassType scfClassType;
00064 public:
00065   typedef scfImplementationPooled<Super, Allocator> scfPooledImplementationType;
00066 
00067   class Pool
00068   {
00069     friend class scfImplementationPooled<Super, Allocator>;
00070     struct Entry
00071     {
00072       Entry* next;
00073     };
00074     CS::Memory::AllocatorPointerWrapper<Entry, Allocator> pool;
00075     size_t allocedEntries;
00076   public:
00077     Pool () : pool ((Entry*)0), allocedEntries (0) 
00078     {
00079     }
00080     Pool (const Allocator& alloc) : pool (alloc, 0), allocedEntries (0) 
00081     {
00082     }
00083     ~Pool () 
00084     {
00085       while (pool.p != 0)
00086       {
00087         Entry* n = pool.p->next;
00088         pool.Free (pool.p);
00089         pool.p = n;
00090       }
00091       CS_ASSERT_MSG ("not all SCF-pooled instances released",
00092         allocedEntries == 0);
00093     }
00094   };
00095 protected:
00097   Pool* scfPool;
00098 public:
00100   inline void* operator new (size_t n, Pool& p)
00101   { 
00102     typedef typename Pool::Entry PoolEntry;
00103     CS_ASSERT_MSG ("Alloc size mismatches class size expected for pooled "
00104       "allocation", n == sizeof (scfClassType));
00105     PoolEntry* newEntry;
00106     if (p.pool.p != 0)
00107     {
00108       newEntry = p.pool.p;
00109       p.pool.p = p.pool.p->next;
00110     }
00111     else
00112     {
00113       newEntry = static_cast<PoolEntry*> (p.pool.Alloc (n));
00114     }
00115     p.allocedEntries++;
00116     scfClassType* newInst = reinterpret_cast<scfClassType*> (newEntry);
00117     /* A bit nasty: set scfPool member of the (still unconstructed!) 
00118      * instance... */
00119     static_cast<scfPooledImplementationType*> (newInst)->scfPool = &p;
00120     return newInst;
00121   }
00122 
00124 
00125   inline void operator delete (void* instance, Pool& p) 
00126   {
00127     typedef typename Pool::Entry PoolEntry;
00128     PoolEntry* entry = static_cast<PoolEntry*> (instance);
00129     entry->next = p.pool.p;
00130     p.pool.p = entry;
00131     p.allocedEntries--;
00132   }
00133   inline void operator delete (void* instance) 
00134   {
00135     scfClassType* object = static_cast<scfClassType*> (instance);
00136     Pool& p = *(static_cast<scfImplementationPooled*> (object)->scfPool);
00137     scfImplementationPooled::operator delete (object, p);
00138   }
00140 
00142   void DecRef ()
00143   {
00144     csRefTrackerAccess::TrackDecRef (this->scfObject, this->scfRefCount);
00145     this->scfRefCount--;
00146     if (this->scfRefCount == 0)
00147     {
00148       delete this->scfObject;
00149     }
00150   }
00151 
00153 
00156   scfImplementationPooled (scfClassType* object) : 
00157     Super (object) {}
00158   template<typename A>
00159   scfImplementationPooled (scfClassType* object, A a) : 
00160     Super (object, a) {}
00161   template<typename A, typename B>
00162   scfImplementationPooled (scfClassType* object, A a, B b) : 
00163     Super (object, a, b) {}
00164   template<typename A, typename B, typename C>
00165   scfImplementationPooled (scfClassType* object, A a, B b, C c) : 
00166     Super (object, a, b, c) {}
00167   template<typename A, typename B, typename C, typename D>
00168   scfImplementationPooled (scfClassType* object, A a, B b, C c, D d) : 
00169     Super (object, a, b, c, d) {}
00170   template<typename A, typename B, typename C, typename D, typename E>
00171   scfImplementationPooled (scfClassType* object, A a, B b, C c, D d, E e) : 
00172     Super (object, a, b, c, d, e) {}
00174 };
00175 
00178 #include "csutil/custom_new_enable.h"
00179 
00180 #endif // __CS_UTIL_POOLEDSCFCLASS_H__

Generated for Crystal Space 1.2.1 by doxygen 1.5.3