• Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at \$59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.

Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!

### #Actualmetsfan

Posted 17 January 2013 - 08:30 AM

Hello all,

So I have this crazy idea (at least it seems crazy to me, but I kinda like crazy  ) to have a base class that all the classes in my game engine extend that manages a reference count.  The idea is to create a reference counting system that is more efficient than std::shared_ptr but also provides the safety of knowing an object won't be deleted while it's still being referenced.  Here is the WIP code I have so far (obviously it is far from complete, but it's enough for me to start testing):

BaseObject.h:

class BaseObject
{
public:
BaseObject();

// Decrements Reference Count, Deletes when it reaches zero
void Release();

std::string GetType();

// Assign a new pointer, with automatic reference count management, and return it.
static BaseObject * Apply(BaseObject *dst, BaseObject *src);

protected:
std::string mType;

private:
volatile unsigned int mRefCount;
};

BaseObject.cpp:






BaseObject::BaseObject()
{
mRefCount = 1;
}

BaseObject::~BaseObject()
{

}

{
InterlockedIncrementAcquire(&mRefCount);
}

void BaseObject::Release()
{
InterlockedDecrementAcquire(&mRefCount);

if(mRefCount == 0) {
delete this;
}
}

BaseObject * BaseObject::Apply(BaseObject *dst, BaseObject *src)
{
if(dst != src)
{
if(dst != NULL) {
dst->Release();
}

if(src != NULL) {
dst = src;
return dst;
} else {
return NULL;
}
}

return dst;
}

So as can clearly be seen, when the object is initialized, its ref count is set to 1 (meaning you must call release when you are done with it, unless you allocated on the stack or with a scoped_ptr in which case it will be destroyed when the scope ends).  Then, when you want to assign the object to another pointer, you would call apply, such as { obj1 = obj1->Apply(obj2); }

Does this make sense?  Is there any way I can improve this?  Is this whole idea crazy?  Any tips or suggestions would be extremely helpful.  Thank you.

EDIT - well found one problem already, which is if you call this->Release(), and it deletes, then no value is ever returned, since the object is now destroyed.  Perhaps it would work better if Apply was a static method (so it would be BaseObject::Apply(BaseObject *dst, BaseObject *src), with similar logic).

EDIT2 - Updated Apply to be static.

### #3metsfan

Posted 17 January 2013 - 08:29 AM

Hello all,

So I have this crazy idea (at least it seems crazy to me, but I kinda like crazy  ) to have a base class that all the classes in my game engine extend that manages a reference count.  The idea is to create a reference counting system that is more efficient than std::shared_ptr but also provides the safety of knowing an object won't be deleted while it's still being referenced.  Here is the WIP code I have so far (obviously it is far from complete, but it's enough for me to start testing):

BaseObject.h:

class BaseObject
{
public:
BaseObject();

// Decrements Reference Count, Deletes when it reaches zero
void Release();

std::string GetType();

// Assign a new pointer, with automatic reference count management, and return it.
static BaseObject * Apply(BaseObject *dst, BaseObject *src);

protected:
std::string mType;

private:
volatile unsigned int mRefCount;
};

BaseObject.cpp:

BaseObject::BaseObject()
{
mRefCount = 1;
}

{
InterlockedIncrementAcquire(&mRefCount);
}

void BaseObject::Release()
{
InterlockedDecrementAcquire(&mRefCount);

if(mRefCount == 0) {
delete this;
}
}


BaseObject * BaseObject::Apply(BaseObject *dst, BaseObject *src)
{
if(dst != src)
{
if(dst != NULL) {
dst->Release();
}

if(src != NULL) {
dst = src;
return dst;
} else {
return NULL;
}
}

return dst;
}

So as can clearly be seen, when the object is initialized, its ref count is set to 1 (meaning you must call release when you are done with it, unless you allocated on the stack or with a scoped_ptr in which case it will be destroyed when the scope ends).  Then, when you want to assign the object to another pointer, you would call apply, such as { obj1 = obj1->Apply(obj2); }

Does this make sense?  Is there any way I can improve this?  Is this whole idea crazy?  Any tips or suggestions would be extremely helpful.  Thank you.

EDIT - well found one problem already, which is if you call this->Release(), and it deletes, then no value is ever returned, since the object is now destroyed.  Perhaps it would work better if Apply was a static method (so it would be BaseObject::Apply(BaseObject *dst, BaseObject *src), with similar logic).

EDIT2 - Updated Apply to be static.

### #2metsfan

Posted 17 January 2013 - 08:06 AM

Hello all,

So I have this crazy idea (at least it seems crazy to me, but I kinda like crazy  ) to have a base class that all the classes in my game engine extend that manages a reference count.  The idea is to create a reference counting system that is more efficient than std::shared_ptr but also provides the safety of knowing an object won't be deleted while it's still being referenced.  Here is the WIP code I have so far (obviously it is far from complete, but it's enough for me to start testing):

BaseObject.h:

class BaseObject
{
public:
BaseObject();

// Decrements Reference Count, Deletes when it reaches zero
void Release();

std::string GetType();

// Assign a new pointer, with automatic reference count management, and return it.
BaseObject * Apply(BaseObject *other);

protected:
std::string mType;

private:
volatile unsigned int mRefCount;
};

BaseObject.cpp:

BaseObject::BaseObject()
{
mRefCount = 1;
}

{
InterlockedIncrementAcquire(&mRefCount);
}

void BaseObject::Release()
{
InterlockedDecrementAcquire(&mRefCount);

if(mRefCount == 0) {
delete this;
}
}

BaseObject * BaseObject::Apply(BaseObject *other)
{
if(this != other)
{
if(this != NULL) {
this->Release();
}

if(other != NULL) {
return other;
} else {
return NULL;
}
}

return this;
}

So as can clearly be seen, when the object is initialized, its ref count is set to 1 (meaning you must call release when you are done with it, unless you allocated on the stack or with a scoped_ptr in which case it will be destroyed when the scope ends).  Then, when you want to assign the object to another pointer, you would call apply, such as { obj1 = obj1->Apply(obj2); }

Does this make sense?  Is there any way I can improve this?  Is this whole idea crazy?  Any tips or suggestions would be extremely helpful.  Thank you.

EDIT - well found one problem already, which is if you call this->Release(), and it deletes, then no value is ever returned, since the object is now destroyed.  Perhaps it would work better if Apply was a static method (so it would be BaseObject::Apply(BaseObject *dst, BaseObject *src), with similar logic).

### #1metsfan

Posted 17 January 2013 - 08:01 AM

Hello all,

So I have this crazy idea (at least it seems crazy to me, but I kinda like crazy  ) to have a base class that all the classes in my game engine extend that manages a reference count.  The idea is to create a reference counting system that is more efficient than std::shared_ptr but also provides the safety of knowing an object won't be deleted while it's still being referenced.  Here is the WIP code I have so far (obviously it is far from complete, but it's enough for me to start testing):

BaseObject.h:

class BaseObject
{
public:
BaseObject();

// Decrements Reference Count, Deletes when it reaches zero
void Release();

std::string GetType();

// Assign a new pointer, with automatic reference count management, and return it.
BaseObject * Apply(BaseObject *other);

protected:
std::string mType;

private:
volatile unsigned int mRefCount;
};

BaseObject.cpp:

BaseObject::BaseObject()
{
mRefCount = 1;
}

{
InterlockedIncrementAcquire(&mRefCount);
}

void BaseObject::Release()
{
InterlockedDecrementAcquire(&mRefCount);

if(mRefCount == 0) {
delete this;
}
}

BaseObject * BaseObject::Apply(BaseObject *other)
{
if(this != other)
{
if(this != NULL) {
this->Release();
}

if(other != NULL) {
return other;
} else {
return NULL;
}
}

return this;
}

So as can clearly be seen, when the object is initialized, its ref count is set to 1 (meaning you must call release when you are done with it, unless you allocated on the stack or with a scoped_ptr in which case it will be destroyed when the scope ends).  Then, when you want to assign the object to another pointer, you would call apply, such as { obj1 = obj1->Apply(obj2); }

Does this make sense?  Is there any way I can improve this?  Is this whole idea crazy?  Any tips or suggestions would be extremely helpful.  Thank you.

PARTNERS