#ifndef CMN_MEMORY_H
#define CMN_MEMORY_H
#include
#include
#include "garbage_collector.h"
#include "logger.h"
#define DEBUG_MEMPTR
template
class mem_ptr
{
private:
static std::map m_mapActive;
T* m_tObj;
void addRef(void);
void remRef(int bForceDelete = false);
public:
mem_ptr() : m_tObj(NULL) {};
mem_ptr(T* tObj) : m_tObj(tObj)
{
addRef();
}
mem_ptr(const mem_ptr &p) : m_tObj(p.m_tObj)
{
addRef();
}
~mem_ptr()
{
remRef(true); // Force the delete to clean up anything not sent to the garbage collector
}
inline void release(void)
{
*this = NULL;
#ifdef DEBUG_MEMPTR
CLogger::Write(COMMENT, "Object of type %s was released.", typeid(m_tObj).name());
#endif
}
inline bool isValid() const
{return (m_tObj!=0);}
inline T* operator =(T *o);
inline T* operator =(const mem_ptr &p);
inline operator T*() const {return m_tObj;}
inline bool operator !() {return !(m_tObj);}
inline bool operator ==(const mem_ptr &p) const
{return (m_tObj==p.m_tObj);}
inline bool operator ==(const T* o) const
{return (m_tObj==o);}
inline T* operator ->() const
{return m_tObj;}
};
template
std::map mem_ptr::m_mapActive;
template
void mem_ptr::addRef(void)
{
if( !m_tObj ) return;
m_mapActive[m_tObj]++;
#ifdef DEBUG_MEMPTR
CLogger::Write(COMMENT, "Reference increased on object of type %s. Reference count is now %d", typeid(m_tObj).name(), m_mapActive[m_tObj]);
#endif
}
template
void mem_ptr::remRef(int bForceDelete)
{
if ( !m_tObj ) return;
m_mapActive[m_tObj]--;
#ifdef DEBUG_MEMPTR
CLogger::Write(COMMENT, "Reference decreased on object of type %s. Reference count is now %d", typeid(m_tObj).name(), m_mapActive[m_tObj]);
#endif
if( m_mapActive[m_tObj] <= 0 )
{
m_mapActive.erase(m_tObj);
#ifdef DEBUG_MEMPTR
CLogger::Write(COMMENT, "Object of type %s was removed from the active list", typeid(m_tObj).name());
#endif
/* If the delete is forced, then
the object is destroyed immediately
otherwise, it is sent to the GarbageCollector
for a one time cleaup with the other objects. */
if (bForceDelete)
{
delete m_tObj;
m_tObj = 0;
#ifdef DEBUG_MEMPTR
CLogger::Write(WARNING, "Object of type %s was killed by mem_ptr::remRef()", typeid(m_tObj).name());
#endif
} else {
GarbageCollector::Recycle(m_tObj);
#ifdef DEBUG_MEMPTR
CLogger::Write(COMMENT, "Object of type %s was sent to the Garbage Collector", typeid(m_tObj).name());
#endif
}
}
}
template
inline T* mem_ptr::operator =(T *o)
{
remRef();
m_tObj=o;
addRef();
return m_tObj;
}
template
inline T* mem_ptr::operator =(const mem_ptr &p)
{
remRef();
m_tObj=p.m_tObj;
addRef();
return m_tObj;
}
#endif