Confused about the use of "Drop" in Collision tuto

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
mqrk
Posts: 16
Joined: Mon Dec 10, 2007 5:55 am

Confused about the use of "Drop" in Collision tuto

Post by mqrk »

First the selector is initialized:

Code: Select all

scene::ITriangleSelector* selector = 0;
	
	if (q3node)
	{		
		q3node->setPosition(core::vector3df(-1350,-130,-1400));

		selector = smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0), q3node, 128);
		q3node->setTriangleSelector(selector);
	}
Then it is used to add collision response to the camera:

Code: Select all

	if (selector)
	{
		scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
			selector, camera, core::vector3df(30,50,30),
			core::vector3df(0,-1,0), 
			core::vector3df(0,50,0));
Then it is dropped:

Code: Select all

		selector->drop();
		camera->addAnimator(anim);
		anim->drop();
	}
Then it is used again without being reinitialized:

Code: Select all

if (smgr->getSceneCollisionManager()->getCollisionPoint(
			line, selector, intersection, tri))
		{
Why does this work? Is one of the functions selector is passed to grabbing it? If so, is this well-defined behavior or was this a mistake? Or am I misunderstanding how drop is used?
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

You are correct, and the example is wrong. You should never assume that an object is valid after you drop() it. In fact, it's better to get into the habit of 0ing any pointer that you drop() to force yourself to not do this.

What happens in this example is:

The selector is created with a ref count of 1.
When it's added to the q3node, the node grabs a reference and increases it to 2.
The collision response animator also grabs a reference and increases it to 3.
The drop() reduces it to 2, so it's still valid when it's used in getCollisionPoint().
The remaining references are dropped() when the scene is deleted during cleanup.

However, that's fortunate coincidence. If anything went wrong during the grab()s, then the drop() would cause the selector to delete itself. It's not even safe to call getReferenceCount() on it after it's been dropped, as you may be checking garbage.

Good spot, and please feel free to submit patches to remove this horror from the example code - which should promote best practice, not just "Oh, it works for me"! ;)
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

right, if the reference counter is droped to 0 then the data is not deleted, it's just given free to delete, so in the example the last usage in fact uses an invalid memory address, but it can use it because the memory was not realy deleted and still avilable... ;)

I didn't test it but probably it would not work if you create a new selector right after the last drop, because this memory might be overwitten then...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Post Reply