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 // hack: work around problems caused by #defining 'new'
00034 #if defined(CS_EXTENSIVE_MEMDEBUG) || defined(CS_MEMORY_TRACKER)
00035 # undef new
00036 #endif
00037 #include <new>
00038 
00039 #define SCF_DECLARE_IBASE_POOLED_DECL(Class, parentClass)\
00040   Class Pool                                            \
00041   {                                                     \
00042     struct PoolEntry;                                   \
00043     PoolEntry* pool;                                    \
00044     PoolEntry* allocedEntries;                          \
00045   public:                                               \
00046     Pool ();                                            \
00047     ~Pool ();                                           \
00048     parentClass* Alloc ();                              \
00049     void Recycle (parentClass* instance);               \
00050   };                                                    \
00051   friend class Pool;                                    \
00052   Pool* scfPool;                                        \
00053   SCF_DECLARE_IBASE
00054 
00075 #define SCF_DECLARE_IBASE_POOLED(parentClass) \
00076   SCF_DECLARE_IBASE_POOLED_DECL(class, parentClass)
00077 
00081 #define SCF_DECLARE_IBASE_POOLED_EXTERN(Extern, parentClass) \
00082   SCF_DECLARE_IBASE_POOLED_DECL(class Extern, parentClass)
00083 
00088 #define SCF_CONSTRUCT_IBASE_POOLED(Pool)                \
00089   SCF_CONSTRUCT_IBASE(0);                               \
00090   scfPool = (Pool)
00091 
00092 #define SCF_IMPLEMENT_IBASE_POOL_HELPERS(parentClass)   \
00093   struct parentClass::Pool::PoolEntry                   \
00094   {                                                     \
00095     parentClass instance;                               \
00096     PoolEntry* next;                                    \
00097   };
00098 
00102 #define SCF_IMPLEMENT_IBASE_POOL_CTOR(Class)            \
00103 Class::Pool::Pool ()                                    \
00104 {                                                       \
00105   pool = 0;                                             \
00106   allocedEntries = 0;                                   \
00107 }
00108 
00112 #define SCF_IMPLEMENT_IBASE_POOL_DTOR(Class)            \
00113 Class::Pool::~Pool ()                                   \
00114 {                                                       \
00115   while (pool != 0)                                     \
00116   {                                                     \
00117     PoolEntry* n = pool->next;                          \
00118     free (pool);                                        \
00119     pool = n;                                           \
00120   }                                                     \
00121   CS_ASSERT_MSG ("not all SCF-pooled instances released",\
00122     allocedEntries == 0);                               \
00123 }
00124 
00128 #define SCF_IMPLEMENT_IBASE_POOL_ALLOC(Class)           \
00129 Class* Class::Pool::Alloc ()                            \
00130 {                                                       \
00131   PoolEntry* newEntry;                                  \
00132   if (pool != 0)                                        \
00133   {                                                     \
00134     newEntry = pool;                                    \
00135     pool = pool->next;                                  \
00136   }                                                     \
00137   else                                                  \
00138   {                                                     \
00139     newEntry = (PoolEntry*)malloc (sizeof (PoolEntry)); \
00140   }                                                     \
00141   Class* newInst = &newEntry->instance;                 \
00142   new (newInst) Class (this);                           \
00143   newEntry->next = allocedEntries;                      \
00144   allocedEntries = newEntry;                            \
00145   return newInst;                                       \
00146 }
00147 
00151 #define SCF_IMPLEMENT_IBASE_POOL_RECYCLE(Class)         \
00152 void Class::Pool::Recycle (Class* instance)             \
00153 {                                                       \
00154   PoolEntry* prev = 0;                                  \
00155   PoolEntry* entry = allocedEntries;                    \
00156   while (&entry->instance != instance)                  \
00157   {                                                     \
00158     prev = entry;                                       \
00159     entry = entry->next;                                \
00160   }                                                     \
00161   if (prev != 0)                                        \
00162     prev->next = entry->next;                           \
00163   else                                                  \
00164     allocedEntries = entry->next;                       \
00165   instance->~Class();                                   \
00166   entry->next = pool;                                   \
00167   pool = entry;                                         \
00168 }
00169 
00173 #define SCF_IMPLEMENT_IBASE_POOL(Class)                 \
00174   SCF_IMPLEMENT_IBASE_POOL_CTOR(Class)                  \
00175   SCF_IMPLEMENT_IBASE_POOL_DTOR(Class)                  \
00176   SCF_IMPLEMENT_IBASE_POOL_ALLOC(Class)                 \
00177   SCF_IMPLEMENT_IBASE_POOL_RECYCLE(Class)
00178 
00182 #define SCF_IMPLEMENT_IBASE_INCREF_POOLED(Class)        \
00183 void Class::IncRef ()                                   \
00184 {                                                       \
00185   scfRefCount++;                                        \
00186 }
00187 
00191 #define SCF_IMPLEMENT_IBASE_DECREF_POOLED(Class)        \
00192 void Class::DecRef ()                                   \
00193 {                                                       \
00194   if (scfRefCount == 1)                                 \
00195   {                                                     \
00196     scfPool->Recycle (this);                            \
00197     return;                                             \
00198   }                                                     \
00199   scfRefCount--;                                        \
00200 }
00201 
00205 #define SCF_IMPLEMENT_IBASE_POOLED(Class)               \
00206   SCF_IMPLEMENT_IBASE_POOL_HELPERS(Class)               \
00207   SCF_IMPLEMENT_IBASE_POOL(Class)                       \
00208   SCF_IMPLEMENT_IBASE_INCREF_POOLED(Class)              \
00209   SCF_IMPLEMENT_IBASE_DECREF_POOLED(Class)              \
00210   SCF_IMPLEMENT_IBASE_GETREFCOUNT(Class)                \
00211   SCF_IMPLEMENT_IBASE_REFOWNER(Class)                   \
00212   SCF_IMPLEMENT_IBASE_REMOVE_REF_OWNERS(Class)          \
00213   SCF_IMPLEMENT_IBASE_QUERY(Class)
00214 
00217 #endif // __CS_UTIL_POOLEDSCFCLASS_H__

Generated for Crystal Space by doxygen 1.4.6