249 lines
3.7 KiB
C++
249 lines
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
|