Sign in to follow this  

Enginuity, Part II

This topic is 4490 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, ive been reading the enginuity part II article (http://www.gamedev.net/reference/articles/article1954.asp) and im wondering about the smart pointer section. Surely the point of a smart pointer is that when the reference count gets to zero, it automatically calls delete on itself? The way the enginuity guide suggests is having to call CollectGarbage() every time you want to free up some dangling memory. Wouldnt it be better to change the following:
// Enginuity
   ~CMMPointer()
   {
      if(obj)obj->Release();
   }

... to ...
// Change to...
   ~CMMPointer()
   {
      if(obj)obj->Release();

      if (obj->GetRefCount() <= 0)
        delete obj;
   }

Thanks,

Share this post


Link to post
Share on other sites
It's been a while since I looked at Enginuity, but I'm fairly sure that the object itself deletes, or does whatever it does inside the Release function.



void IMMObject::Release()
{
--refCount;
if(refCount<=0)
{
liveObjects.remove(this);
deadObjects.push_back(this);
}
}





This is the code from the article, and as you see, the object itself decides whether its refCount is 0, and adds itself to the deadList.

Its one of the points of OO. If you need to manipulate the data of an object, the object should have a function that does it.

Share this post


Link to post
Share on other sites
Yeah, the MMObject isnt responsible for deleting itself though, because its just a memory managed object, its not a smart pointer. but adding itself to the list of dead objects doesnt actually delete itself, it just adds it to a list of memory which hasnt been cleaned.

So i was thinking rather than having a list of dead objects, then having to call CollectGarbage, it would be better to just delete the pointer when the reference count gets to zero?

Share this post


Link to post
Share on other sites
Is the outcome defined if you do "delete this"?
edit: misread your post and bad memory
I would guess that the coder/designer thought that doing release on a object should eventually kill it and not count it's reference down.

Perhaps another way of doing it would be that the IMMObject destructor removes itself from the dead object list. Might be a bit harder to do(iterating and removing from the same list) but it would (as I see it) satisfy both sollutions...

Share this post


Link to post
Share on other sites
I think the point of the deadlist is that the deletion of 'dead' objects can be controlled by the user. For example, a managed particle class would mean lots of objects are deleted when they're released, potentially causing a framerate hit as all the deletions are processed. The 'CollectGarbage' method allows users to call 'delete' whenever they want, perhaps when there's not much happening in the game. However, the current system DOES suffer issues with this; entering a loop and deleting hundreds of objects per frame is costly, especially with the aforementioned particle system example. The system could be enhanced to take a 'WorkUnits' parameter, allowing the user to control how many objects are deleted in a single sweep (allowing small collections often without freezing the app). I'd also implement a freelist/block allocation scheme, so a list of each type of object is maintained and data isn't actually deleted, more like pushed onto a 'removed' stack to be reused when 'new' is called, thus avoiding a memory allocation and deletion altogether.

If you want to quickly acheive your goals, you could use boost::shared_ptr instead, which will automatically delete objects when hte internal refcount is zero - plus it's non-intrusive, unlike the Enginuity version.

Share this post


Link to post
Share on other sites
I always thought it was perfectly legal, its just a strange thing todo. Heres a quote from a quick result in google:

Quote:

http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.15

As long as you're careful, it's OK for an object to commit suicide (delete this).

Here's how I define "careful":

You must be absolutely 100% positive sure that this object was allocated via new (not by new[], nor by placement new, nor a local object on the stack, nor a global, nor a member of another object; but by plain ordinary new).
You must be absolutely 100% positive sure that your member function will be the last member function invoked on this object.
You must be absolutely 100% positive sure that the rest of your member function (after the delete this line) doesn't touch any piece of this object (including calling any other member functions or touching any data members).
You must be absolutely 100% positive sure that no one even touches the this pointer itself after the delete this line. In other words, you must not examine it, compare it with another pointer, compare it with NULL, print it, cast it, do anything with it.
Naturally the usual caveats apply in cases where your this pointer is a pointer to a base class when you don't have a virtual destructor.

Share this post


Link to post
Share on other sites
Quote:
Original post by evolutional
plus it's non-intrusive, unlike the Enginuity version.


how do you mean?

I was thinking about building in an option for the MMObject class, so that it can either have a list of dead objects or it could automatically free them.

Share this post


Link to post
Share on other sites
Quote:
Original post by Skute
Quote:
Original post by evolutional
plus it's non-intrusive, unlike the Enginuity version.


how do you mean?


With boost::shared_ptr, you do not need to base any of your classes on it to take advantage of smart pointers. With the enginuity version, all of your garbage collected classes need to be based on the IMMObject class.

Share this post


Link to post
Share on other sites
I'm too slow, this time I'm writing in notepad and updating explorer :)

Particle systems (and other intesive (runtime) allocation/deallocation) should IMHO use a internal deadlist and not rely on a global one. Personaly I think it's bad design if the particle manager goes around in the garbage collector.

I see, it may be legal to commit suicide, but I don't like it :)

Share this post


Link to post
Share on other sites
So do you all think it would be better to have 2 types of pointer:

a) A smart pointer that deletes itself when needed
and
b) A garbage collected pointer that can be deleted whenever is convenient

?

Share this post


Link to post
Share on other sites

This topic is 4490 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this