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
 |