bluecore/engine/Utilities/Referenced.h

249 rindas
3.7 KiB
C++

#ifndef BLUECORE_REFERENCED_COUNTER_H
#define BLUECORE_REFERENCED_COUNTER_H
#include <list>
namespace BlueCore
{
class Referenced
{
public:
class DestructionListener
{
public:
virtual void onDestruction(Referenced *referenced) = 0;
};
private:
std::list<DestructionListener*> _DestructionListeners;
unsigned int _ReferenceCount;
virtual void destroyReferenced()
{
while (_DestructionListeners.begin() != _DestructionListeners.end())
{
if (_DestructionListeners.front() != 0)
_DestructionListeners.front()->onDestruction(this);
_DestructionListeners.pop_front();
}
delete this;
}
public:
inline Referenced() :
_ReferenceCount(0)
{
}
virtual inline ~Referenced()
{
}
inline void addReference()
{
_ReferenceCount += 1;
}
inline void removeReference()
{
if (_ReferenceCount > 0)
{
_ReferenceCount -= 1;
if ( 0 == _ReferenceCount)
{
destroyReferenced();
}
}
}
inline unsigned int getReferenceCount()
{
return _ReferenceCount;
}
inline void addDestructionListener(DestructionListener *listener)
{
if (listener != 0)
_DestructionListeners.push_back(listener);
}
inline void removeDestructionListener(DestructionListener *listener)
{
_DestructionListeners.remove(listener);
}
};
template<class T> class ref_ptr
{
public:
ref_ptr() :
_Referenced(0)
{
}
ref_ptr(T* referenced) :
_Referenced(referenced)
{
if (_Referenced)
_Referenced->addReference();
}
ref_ptr(const ref_ptr& op) :
_Referenced(op._Referenced)
{
if (_Referenced)
_Referenced->addReference();
}
~ref_ptr()
{
if (_Referenced)
_Referenced->removeReference();
}
T* operator ->() const
{
return _Referenced;
}
ref_ptr& operator =(T* op)
{
if (op != _Referenced)
{
if (_Referenced != 0)
_Referenced->removeReference();
_Referenced = op;
if (_Referenced)
_Referenced->addReference();
}
return *this;
}
bool operator ==(const ref_ptr& ref)
{
if (_Referenced == ref._Referenced)
return true;
else
return false;
}
bool operator == (T* ref)
{
if (_Referenced == ref)
return true;
else
return false;
}
bool valid() const
{
return (_Referenced != 0);
}
operator T*() const
{
return _Referenced;
}
T* pointer() const
{
return _Referenced;
}
private:
T* _Referenced;
};
template<class T> class weak_ptr : public Referenced::DestructionListener
{
public:
weak_ptr() :
_Referenced(0)
{
}
weak_ptr(T* referenced) :
_Referenced(referenced)
{
if (_Referenced)
_Referenced->addDestructionListener(this);
}
weak_ptr(const weak_ptr& op) :
_Referenced(op._Referenced)
{
if (_Referenced)
_Referenced->addDestructionListener(this);
}
virtual ~weak_ptr()
{
if (_Referenced)
_Referenced->removeDestructionListener(this);
}
T* operator ->() const
{
return _Referenced;
}
weak_ptr& operator =(T* op)
{
if (op != _Referenced && _Referenced != 0)
_Referenced->removeDestructionListener(this);
_Referenced = op;
_Referenced->addDestructionListener(this);
return *this;
}
bool operator ==(const weak_ptr& ref)
{
if (_Referenced == ref._Referenced)
return true;
else
return false;
}
bool valid() const
{
return (_Referenced != 0);
}
T* pointer() const
{
return _Referenced;
}
operator T*() const
{
return _Referenced;
}
void onDestruction(Referenced *referenced)
{
_Referenced = 0;
}
private:
T* _Referenced;
};
} // namespace BlueCore
#endif