You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
3.9 KiB
242 lines
3.9 KiB
10 months ago
|
#pragma once
|
||
|
|
||
|
#include <helper/SCriticalSection.h>
|
||
|
|
||
|
namespace SOUI
|
||
|
{
|
||
|
/**
|
||
|
* This class is used in SSharedPtr to delete a object pointer.
|
||
|
*/
|
||
|
template <class T>
|
||
|
class PtrDisposer
|
||
|
{
|
||
|
public:
|
||
|
/**
|
||
|
* Delete pointer ptr.
|
||
|
* @param ptr pointer to be deleted.
|
||
|
*/
|
||
|
virtual void dispose(T *ptr) = 0;
|
||
|
};
|
||
|
|
||
|
template <class T>
|
||
|
class SSharedCount
|
||
|
{
|
||
|
public:
|
||
|
SSharedCount(T *ptr, PtrDisposer<T> &disposer) : _ptr(ptr), _refCount(1), _cs(), _disposer(disposer)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
~SSharedCount()
|
||
|
{
|
||
|
_disposer.dispose(_ptr);
|
||
|
}
|
||
|
|
||
|
void incRefCount()
|
||
|
{
|
||
|
SAutoLock autoLock(_cs);
|
||
|
++_refCount;
|
||
|
}
|
||
|
|
||
|
void decRefCount()
|
||
|
{
|
||
|
bool shouldDelete = false;
|
||
|
|
||
|
{
|
||
|
SAutoLock autoLock(_cs);
|
||
|
|
||
|
if (_refCount > 0)
|
||
|
{
|
||
|
--_refCount;
|
||
|
}
|
||
|
|
||
|
if (_refCount == 0)
|
||
|
{
|
||
|
shouldDelete = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (shouldDelete)
|
||
|
{
|
||
|
delete this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
T *_ptr;
|
||
|
unsigned int _refCount;
|
||
|
SCriticalSection _cs;
|
||
|
PtrDisposer<T> &_disposer;
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* SharedPtr is a class to encapsulate an object pointer. When a pointer is
|
||
|
* put into SharedPtr object, the object reference count will increase. When
|
||
|
* a SharedPtr object is destructed, the object reference count will decrease.
|
||
|
* If the object reference count is decreased to 0, the object will be deleted
|
||
|
* automatically.
|
||
|
*/
|
||
|
template <class T>
|
||
|
class SSharedPtr
|
||
|
{
|
||
|
private:
|
||
|
class DefaultPtrDisposer : public PtrDisposer<T>
|
||
|
{
|
||
|
public:
|
||
|
virtual void dispose(T *ptr)
|
||
|
{
|
||
|
if (ptr)
|
||
|
{
|
||
|
delete ptr;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
/**
|
||
|
* Default constructor.
|
||
|
* @param ptr object pointer.
|
||
|
*/
|
||
|
SSharedPtr() : _ptr(NULL), _sc(new SSharedCount<T>(NULL, _kDefaultPtrDisposer))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Constructor.
|
||
|
* @param ptr object pointer.
|
||
|
*/
|
||
|
SSharedPtr(T *ptr) : _ptr(ptr), _sc(new SSharedCount<T>(ptr, _kDefaultPtrDisposer))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Constructor with disposer.
|
||
|
* @param ptr object pointer.
|
||
|
* @param disposer object disposer.
|
||
|
*/
|
||
|
SSharedPtr(T *ptr, PtrDisposer<T> &disposer) : _ptr(ptr), _sc(new SSharedCount<T>(ptr, disposer))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Copy constructor.
|
||
|
* @param obj another SharedPtr object.
|
||
|
*/
|
||
|
SSharedPtr(const SSharedPtr<T> &obj) : _ptr(obj._ptr), _sc(obj._sc)
|
||
|
{
|
||
|
obj._sc->incRefCount();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Destructor.
|
||
|
*/
|
||
|
~SSharedPtr()
|
||
|
{
|
||
|
_sc->decRefCount();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Assign. The original object reference count will be decreased, and
|
||
|
* the new object reference count will be increased.
|
||
|
* @param obj another SharedPtr object.
|
||
|
* @return self object.
|
||
|
*/
|
||
|
SSharedPtr &operator=(const SSharedPtr<T> &obj)
|
||
|
{
|
||
|
if (this != &obj)
|
||
|
{
|
||
|
obj._sc->incRefCount();
|
||
|
_sc->decRefCount();
|
||
|
_sc = obj._sc;
|
||
|
_ptr = obj._ptr;
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the object pointer.
|
||
|
* @return object pointer.
|
||
|
*/
|
||
|
const T *operator->() const
|
||
|
{
|
||
|
return _ptr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the object pointer.
|
||
|
* @return object pointer.
|
||
|
*/
|
||
|
T *operator->()
|
||
|
{
|
||
|
return _ptr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the object pointer.
|
||
|
* @return object pointer.
|
||
|
*/
|
||
|
const T *ptr() const
|
||
|
{
|
||
|
return _ptr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the object pointer.
|
||
|
* @return object pointer.
|
||
|
*/
|
||
|
T *ptr()
|
||
|
{
|
||
|
return _ptr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the object reference.
|
||
|
* @return object reference.
|
||
|
*/
|
||
|
const T &operator*() const
|
||
|
{
|
||
|
return *_ptr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the object reference.
|
||
|
* @return object reference.
|
||
|
*/
|
||
|
T &operator*()
|
||
|
{
|
||
|
return *_ptr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return if the pointer equals to another.
|
||
|
* @return true if equal.
|
||
|
*/
|
||
|
bool operator==(T *ptr) const
|
||
|
{
|
||
|
return _ptr == ptr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return if the pointer equals to another.
|
||
|
* @return true if equal.
|
||
|
*/
|
||
|
bool operator==(SSharedPtr<T> obj) const
|
||
|
{
|
||
|
return _ptr == obj._ptr;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
//static void *operator new(size_t size);
|
||
|
|
||
|
static DefaultPtrDisposer _kDefaultPtrDisposer;
|
||
|
|
||
|
T *_ptr;
|
||
|
SSharedCount<T> *_sc;
|
||
|
};
|
||
|
|
||
|
template <class T>
|
||
|
typename SSharedPtr<T>::DefaultPtrDisposer SSharedPtr<T>::_kDefaultPtrDisposer;
|
||
|
|
||
|
}
|