When to use drop()
-
- Posts: 19
- Joined: Wed Jan 23, 2008 7:10 am
When to use drop()
I'm starting to get the hang of Irrlicht but I'm curious, when are you sopposed to use drop()? From what I'v learned you should use it as soon as you wont need something anymore, but I would just like to make shore I'm right.
When you create an object in the Irrlicht engine, calling a method which starts with 'create', an object is created, and you get a pointer to the new object. If you no longer need the object, you have to call drop(). This will destroy the object, if grab() was not called in another part of you program, because this part still needs the object. Note, that you only need to call drop() to the object, if you created it, and the method had a 'create' in it.
A simple example:
If you want to create a texture, you may want to call an imaginable method IDriver::createTexture. You call ITexture* texture = driver->createTexture(dimension2d<s32>(128, 128)); If you no longer need the texture, call texture->drop(). If you want to load a texture, you may want to call imaginable method IDriver::loadTexture. You do this like ITexture* texture = driver->loadTexture("example.jpg"); You will not have to drop the pointer to the loaded texture, because the name of the method does not start with 'create'. The texture is stored somewhere by the driver.
-
- Posts: 19
- Joined: Wed Jan 23, 2008 7:10 am
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Also, you don't have to drop() it as soon as you're done with it, you just need to be sure to do it before your final device->drop() so that everything gets cleaned up neatly.
What's more important is that once you've called drop() on an object that you shouldn't assume that it is still valid, or that it will remain so, and so you shouldn't use it again.
Some of the examples unfortunately show objects being used after a drop() call; this works because other objects still have references to the dropped() object, but it is bad practice, particularly as the examples don't verify the refcount before the drop() to ensure that it's > 1.
What's more important is that once you've called drop() on an object that you shouldn't assume that it is still valid, or that it will remain so, and so you shouldn't use it again.
Some of the examples unfortunately show objects being used after a drop() call; this works because other objects still have references to the dropped() object, but it is bad practice, particularly as the examples don't verify the refcount before the drop() to ensure that it's > 1.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
-
- Posts: 19
- Joined: Wed Jan 23, 2008 7:10 am
You guys are probably sick of looking at other peoples code but if you could take a look, did I use drop() correctly?
Code: Select all
#include <irrlicht.h>
#include <iostream>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
int main()
{
//Create Irrlicht, the driver, and the scene manager
IrrlichtDevice *device =
createDevice(EDT_DIRECT3D9, dimension2d<s32>(512, 384), 32,
false, false, false, 0);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
//Hide the mouse
device->getCursorControl()->setVisible(false);
//The walls, ground
//The ground
ISceneNode* Floor = smgr->addCubeSceneNode();
Floor->setScale(vector3df(300,1,300));
Floor->setMaterialTexture(0, driver->getTexture("../Amphitheatrum Flavium/media/Sand.bmp"));
Floor->setMaterialFlag(EMF_LIGHTING, false);
//Floor Collision
ITriangleSelector* FloorCollision = smgr->createTriangleSelectorFromBoundingBox(Floor);
Floor->setTriangleSelector(FloorCollision);
//The first wall
ISceneNode* Wall1 = smgr->addCubeSceneNode();
Wall1->setScale(vector3df(300,50,1));
Wall1->setMaterialTexture(0, driver->getTexture("../Amphitheatrum Flavium/media/Walls.bmp"));
Wall1->setMaterialFlag(EMF_LIGHTING, false);
Wall1->setPosition(vector3df(0,0,1500));
//Wall1 Collision
ITriangleSelector* Wall1Collision = smgr->createTriangleSelectorFromBoundingBox(Wall1);
Wall1->setTriangleSelector(Wall1Collision);
//The second wall
ISceneNode* Wall2 = smgr->addCubeSceneNode();
Wall2->setScale(vector3df(300,50,1));
Wall2->setMaterialTexture(0, driver->getTexture("../Amphitheatrum Flavium/media/Walls.bmp"));
Wall2->setMaterialFlag(EMF_LIGHTING, false);
Wall2->setPosition(vector3df(0,0,-1500));
//Wall2 Collision
ITriangleSelector* Wall2Collision = smgr->createTriangleSelectorFromBoundingBox(Wall2);
Wall2->setTriangleSelector(Wall2Collision);
//The third wall
ISceneNode* Wall3 = smgr->addCubeSceneNode();
Wall3->setScale(vector3df(1,50,300));
Wall3->setMaterialTexture(0, driver->getTexture("../Amphitheatrum Flavium/media/Walls.bmp"));
Wall3->setMaterialFlag(EMF_LIGHTING, false);
Wall3->setPosition(vector3df(1500,0,0));
//Wall3 Collision
ITriangleSelector* Wall3Collision = smgr->createTriangleSelectorFromBoundingBox(Wall3);
Wall3->setTriangleSelector(Wall3Collision);
//The fourth wall
ISceneNode* Wall4 = smgr->addCubeSceneNode();
Wall4->setScale(vector3df(1,50,300));
Wall4->setMaterialTexture(0, driver->getTexture("../Amphitheatrum Flavium/media/Walls.bmp"));
Wall4->setMaterialFlag(EMF_LIGHTING, false);
Wall4->setPosition(vector3df(-1500,0,0));
//Wall4 Collision
ITriangleSelector* Wall4Collision = smgr->createTriangleSelectorFromBoundingBox(Wall4);
Wall4->setTriangleSelector(Wall4Collision);
//Combine the triangle selectors into a meta selector
IMetaTriangleSelector * CollisionMeta = smgr->createMetaTriangleSelector();
CollisionMeta->addTriangleSelector(FloorCollision);
CollisionMeta->addTriangleSelector(Wall1Collision);
CollisionMeta->addTriangleSelector(Wall2Collision);
CollisionMeta->addTriangleSelector(Wall3Collision);
CollisionMeta->addTriangleSelector(Wall4Collision);
//Skybox
driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
smgr->addSkyBoxSceneNode(
driver->getTexture("../Amphitheatrum Flavium/media/irrlicht2_up.jpg"),
driver->getTexture("../Amphitheatrum Flavium/media/irrlicht2_dn.jpg"),
driver->getTexture("../Amphitheatrum Flavium/media/irrlicht2_lf.jpg"),
driver->getTexture("../Amphitheatrum Flavium/media/irrlicht2_rt.jpg"),
driver->getTexture("../Amphitheatrum Flavium/media/irrlicht2_ft.jpg"),
driver->getTexture("../Amphitheatrum Flavium/media/irrlicht2_bk.jpg"));
//The camera
ICameraSceneNode* camera =
smgr->addCameraSceneNodeFPS();
camera->setPosition(vector3df(0,50,0));
camera->setTarget(vector3df(2397*2,343*2,2700*2));
camera->setFarValue(20000.0f);
//Create response animator for the camera
ISceneNodeAnimatorCollisionResponse* CameraAnimator;
CameraAnimator = smgr->createCollisionResponseAnimator(
CollisionMeta, camera,
vector3df(10,10,10),
vector3df(0,-2,0),
vector3df(0,25,0));
camera->addAnimator(CameraAnimator);
while(device->run())
{
driver->beginScene(true, true, SColor(0, 200, 200, 200));
smgr->drawAll();
driver->endScene();
}
//Drop everything that was created
Floor->drop();
FloorCollision->drop();
Wall1->drop();
Wall1Collision->drop();
Wall2->drop();
Wall2Collision->drop();
Wall3->drop();
Wall3Collision->drop();
Wall4->drop();
Wall4Collision->drop();
CollisionMeta->drop();
CameraAnimator->drop();
device->drop();
return 0;
}
Basically objects that you get from add..() methods are dropped automatically hence you don't have to take care of'em. Objects that are created with methods that starts with create..() returns you an object with reference counter of 1 (right?) and are not automatically dropped.
A simple rule: (I think rogerborg already mentioned something like this)
Drop every object that you've created with a create...() method when you don't need it any more. Know that some parts might have grabbed that object (which raises its ref counter by one, one for each grab() call) but they will also drop it automatically.
Two advices:
1. Check this.
2. Write simple programs that grab & drop objects and debug it (or with simple printf of the ref counter) to see how its effect.
Something like that:
And ignore that unnecessary pure virtual method PrintName(), it doesn't matter for this exercise because it does the same things in both derived classes.. I should have made it just virtual..
Now run this code and write another one yourself to check this grab()/drop() concept.
A simple rule: (I think rogerborg already mentioned something like this)
Drop every object that you've created with a create...() method when you don't need it any more. Know that some parts might have grabbed that object (which raises its ref counter by one, one for each grab() call) but they will also drop it automatically.
Two advices:
1. Check this.
2. Write simple programs that grab & drop objects and debug it (or with simple printf of the ref counter) to see how its effect.
Something like that:
Code: Select all
#include "irrlicht.h"
#include "iostream"
#include "process.h" // for system("Pause");
using namespace irr;
using namespace std;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
class Human : public virtual IReferenceCounted
{
public:
Human(const char* Name) : name(Name)
{
cout << "In Human constructor" << endl;
}
~Human()
{
cout << "In Human destructor" << endl;
}
virtual void PrintName() = 0;
protected:
const char* name;
};
class Male : public Human
{
public:
Male(const char* Name) : Human(Name)
{
cout << "In Male constructor" << endl;
}
~Male()
{
cout << "In Male destructor" << endl;
}
void PrintName()
{
cout << name << endl;
}
};
class Female : public Human
{
public:
Female(const char* Name) : Human(Name)
{
cout << "In Female constructor" << endl;
}
~Female()
{
cout << "In Female destructor" << endl;
}
void PrintName()
{
cout << name << endl;
}
};
int main()
{
Human* PersonA = new Male("Mr.MasterGod");
Human* PersonB = new Female("Mrs.MasterGod");
PersonA->PrintName();
cout << PersonA->getReferenceCount() << endl;
PersonB->PrintName();
cout << PersonB->getReferenceCount() << endl;
PersonB->grab(); // needs a matching drop()
cout << "After Grabbing Mrs.MasterGod.." << endl;
PersonA->PrintName();
cout << PersonA->getReferenceCount() << endl;
PersonB->PrintName();
cout << PersonB->getReferenceCount() << endl;
PersonA->grab(); // needs a matching drop()
cout << "After Grabbing Mr.MasterGod.." << endl;
PersonA->PrintName();
cout << PersonA->getReferenceCount() << endl;
PersonB->PrintName();
cout << PersonB->getReferenceCount() << endl;
PersonA->drop(); // matching drop()
cout << "After Dropping Mr.MasterGod.." << endl;
PersonA->PrintName();
cout << PersonA->getReferenceCount() << endl;
PersonB->PrintName();
cout << PersonB->getReferenceCount() << endl;
PersonB->drop(); // matching drop()
cout << "After Dropping Mrs.MasterGod.." << endl;
PersonA->PrintName();
cout << PersonA->getReferenceCount() << endl;
PersonB->PrintName();
cout << PersonB->getReferenceCount() << endl;
// match for the new op
cout << "Dropping Mr.MasterGod, because reference couter is 1 it will be deleted" << endl;
PersonA->drop();
// match for the new op
cout << "Dropping Mrs.MasterGod, because reference couter is 1 it will be deleted" << endl;
PersonB->drop();
system("Pause");
return 0;
}
Now run this code and write another one yourself to check this grab()/drop() concept.
-
- Posts: 19
- Joined: Wed Jan 23, 2008 7:10 am