Jump to content

AddRef()/Release()


Rick
 Share

Recommended Posts

My understanding of this is that when we are passing pointers of LE objects to other LE objects we have to make sure all those objects that were passed the pointer know if the pointer is still valid or not before it uses it. So I assume inside these LE objects it calls RefCount() before using any external LE object to make sure it's > 0.

 

1) Why not just have the LE functions call AddRef() for the functions that accept pointers to other LE objects on the passed in object so we don't have to remember to do this manually? Is it because we want to give them a chance to use objects in multiple places? How often is this really done? Is it really hard to use objects for only 1 thing? It's much more common, and required in some cases, that we need to pass LE objects to other LE objects.

 

2) I think we aren't supposed to call delete on any LE pointers but just Release() which would reduce the count and if it's the last usage the count would be 0. When does LE actually delete the underlying LE resource then?

 

3) I assume calling ::Create() sets the internal ref count to 1 (or the ctor of the Entity class)?

 

4) Why not have LE objects look at the RefCount() inside the destructor and decide if it should actually delete the resources or not if the RefCount() = 0? This way we can still use the normal C++ 'delete object' instead of release.

 

ie

--

LE Code

class Entity
{
private:
Shape* _shape;
public:
void SetShape(Shape* shape)
{
_shape = shape;

// le doing it automatically for us because we know it needs to be done anyway so why make the programmer remember to do this?
shape.AddRef();
}

virtual ~Entity()
{
  if(RefCount() == 0)
  {
     // actually delete the contents of this class
  }
}

void Release()
{
// if a shape was passed into SetShap() then we know it has to be released so let's do it for the programmer
if(_shape != NULL)
_shape->Release();
}
};

Link to comment
Share on other sites

My understanding of this is that when we are passing pointers of LE objects to other LE objects we have to make sure all those objects that were passed the pointer know if the pointer is still valid or not before it uses it. So I assume inside these LE objects it calls RefCount() before using any external LE object to make sure it's > 0.

You usually will not need to ever worry about calling AddRef(). It would be an unusual case.

 

1) Why not just have the LE functions call AddRef() for the functions that accept pointers to other LE objects on the passed in object so we don't have to remember to do this manually? Is it because we want to give them a chance to use objects in multiple places? How often is this really done? Is it really hard to use objects for only 1 thing? It's much more common, and required in some cases, that we need to pass LE objects to other LE objects.

That's exactly how it's done. Commands that accept a pointer to an object for storage will increment that object's ref count, and decrement it when finished with them:

http://www.leadwerks.com/werkspace/page/documentation/_/command-reference/material/materialsettexture-r184

 

2) I think we aren't supposed to call delete on any LE pointers but just Release() which would reduce the count and if it's the last usage the count would be 0. When does LE actually delete the underlying LE resource then?

When Release() is called, if the refcount reaches 0 the object is deleted.

 

3) I assume calling ::Create() sets the internal ref count to 1 (or the ctor of the Entity class)?
All objects have a ref count of 1 when created.

 

4) Why not have LE objects look at the RefCount() inside the destructor and decide if it should actually delete the resources or not if the RefCount() = 0? This way we can still use the normal C++ 'delete object' instead of release.

If you delete the object, it is no longer a valid pointer. This can cause other objects that use that one to cause a crash when they try to access the object, since it no longer exists. The System::GCDepth thing is a way to prevent crashes if an entity is deleted inside a physics callback.

 

This is the source for Object::Release():

	unsigned long Object::Release()
{
       unsigned long result = 0;
	if (refcount>0) result = refcount-1;
       if (refcount==0) Debug::Error("Object reference count error.");
       refcount--;
       if (refcount==0)
	{
		if (System::GCDepth==0)
		{
			delete this;
		}
		else
		{
			Garbage.push_back(this);
		}
	}
       return result;
}

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...