Disposing objects

mzanin

29-07-2010 05:08:22

Hello,

I have a question in regards to the order in which to dispose objects and if it is meant to be hierarchical?
Also I wish to know what the standard way of disposing Materials and Textures is?

For example at the end of my application I do this:


MaterialManager.Singleton.RemoveAll();

if (m_SceneManager != null)
{
m_SceneManager.ClearScene();
m_Root.DestroySceneManager(m_SceneManager);
}

if (m_RenderSystem != null && m_RenderWindow != null)
{
m_RenderSystem.EventOccurred -= RenderSystemListener;
m_RenderSystem.DestroyRenderWindow(m_RenderWindow.Name);
}

if (m_Root != null)
{
ResourceGroupManager.Singleton.Dispose();

m_Root.Shutdown();
m_Root.Dispose();
m_Root = null;
}


Is this really necessary or can I simply m_Root.Dispose(), and that in turn will dispose all it's children etc.?

In regards to the materials/textures, in places I do this (for example)...


m_Texture.DisposeIfNotNull();
m_Texture = null;

MaterialManager.Singleton.Remove(m_Identifier.Name);

m_SceneManager.DestroyManualObject(m_ManualObject);
m_SceneManager.DestroySceneNode(m_Node);


Will disposing/destroying the ManualObject not dispose all it's "children" (including the material and in turn the texture) anyway?
Or disposing the Material not dispose the texture as well?

Also is there any difference in calling

m_Texture.Dispose() compared to calling TextureManager.Singleton.Remove(m_Texture.Name);

Another thing I do is dispose the MaterialPtr straight after I use it... eg.


MaterialPtr materialPtr = MaterialManager.Singleton.Create(m_MaterialName, "General");
materialPtr.RemoveAllTechniques();
var technique = materialPtr.CreateTechnique();
materialPtr.Dispose();


Is this the correct way to do this?

Lastly is it necessary at the end of the program to call dispose on all the managers? For example


TextureManager.Singleton.Dispose();
MaterialManager.Singleton.Dispose();
...

Hopefully someone can clarify this for me as it's been bugging me for a while.

Beauty

29-07-2010 13:23:48

I don't know all details.

The ressources will be loaded by the RessourceManager automaticly.
When you load a mesh or create a ManualObject, you can use all ressources of the RessourceManager.
It's like a link using the material name as identifier.
So you never have to dispose them. (This is my experience.)

When you create a Material by MaterialPtr then you can set its propierties.
Just after creating you can dispose it. It will only dispose the "link" to the material.
The material will still be available by the RessourceManager and you can call it by its name.

Here is a code snippet. It creates a material and call dispose. The material is still available:

// create material (colour)
MaterialPtr moMaterial = MaterialManager.Singleton.Create("line_material", "debugger");
moMaterial.ReceiveShadows = false;
moMaterial.GetTechnique(0).SetLightingEnabled(true);
moMaterial.GetTechnique(0).GetPass(0).SetDiffuse(0, 0, 1, 0);
moMaterial.GetTechnique(0).GetPass(0).SetAmbient(0, 0, 1);
moMaterial.GetTechnique(0).GetPass(0).SetSelfIllumination(0, 0, 1);
moMaterial.Dispose(); // dispose pointer, not the material


In my application I don't call dispose for each ManualObject, SceneNode etc. - I have no problems.
This is my personal experience. Maybe they will be disposed automatically by the Mogre wrapper?

mzanin

12-08-2010 02:34:54

Thanks for the info.

One thing I did notice is that calling .Dispose on the node is not enough to remove it from the Manager (I think).
I believe that if you use any manager to create an object you should use the manager to remove the object first and THEN dispose the object.

Sound right to you?

Beauty

12-08-2010 11:38:36

I think it's no good idea to dispose something (like an entity or material) which is still in use.
When you delete a SceneNode, it's attached entities and subNodes are still alive. If you want to delete them too, you have to do it additionally.

Deleting an object you do by its manager.
You call it like this:
if (mScene.Smgr.HasSceneNode(nodeName))
mScene.Smgr.DestroySceneNode(nodeName); // delete SceneNode
if (mScene.Smgr.HasEntity(entityName))
mScene.Smgr.DestroyEntity(entityName); // delete Entity (e.g. a Mesh)

manski

19-08-2010 15:16:18

I think it's no good idea to dispose something (like an entity or material) which is still in use.

You mean "delete", right? Because, as you mentioned before, "Dispose()" only decrements the "use counter". This counter counts the number of pointers out there existing to this resource. If the counter hits zero the resource will (or may?) be deleted, as it's no longer used.

Moreover, the "Dispose()" method will be called automatically by the garbage collector. So theoretically you don't need to call "Dispose()" at all (though it doesn't hurt to call it, if you can). However, this doesn't work always due to some race conditions (as discussed on this thread at page 4 and following). I've created a patch that works for me. However, this patch patches an auto-generated source file which is not such a good idea. I've included the patch here though I has been some time since I worked on it, it currently only works for Textures (and no other resources), and I somehow screwed the line endings of "MogreRoot.h" so the whole file got included. So most likely it's not very useable but I'm attaching it in case you want to have a look at it.

Update: The stupid forum doesn't allow me attach .patch or .txt files. So if you're interested in the patch, just write me a message.

mstoyke

19-08-2010 15:47:41

Update: The stupid forum doesn't allow me attach .patch or .txt files. So if you're interested in the patch, just write me a message.

... or just put the patch or txt file into a zip archive... (hint, hint) ;)

Beauty

19-08-2010 17:46:38

Thanks for clearing up the details. I thought dispose just mean to delete something (including optional processing, e.g. close a file).

Maybe your fix can be integrated to the autowrapper?
What happens without this patch.
Possibly crashes? Or "just" blowing up the memory?

I suppose attaching a rar file works. I attached a test file.

Beauty

19-08-2010 17:57:30

as discussed on this thread at page 4
In the forum is an easy was to get a link to a special post. (This is better than just refer to a page.)
Just rightClick to the page symbol at top of the post and chose copy target link address (or similar). Then you get the right URL to your clipboard.
The URL is looking like this:
.../viewtopic.php?p=72968#p72968

Beauty

11-04-2012 12:36:41

Moreover, the "Dispose()" method will be called automatically by the garbage collector. So theoretically you don't need to call "Dispose()" at all (though it doesn't hurt to call it, if you can). However, this doesn't work always due to some race conditions (as discussed on this thread at page 4 and following). I've created a patch that works for me. However, this patch patches an auto-generated source file which is not such a good idea. I've included the patch here though I has been some time since I worked on it, it currently only works for Textures (and no other resources), and I somehow screwed the line endings of "MogreRoot.h" so the whole file got included. So most likely it's not very useable but I'm attaching it in case you want to have a look at it.

I'm very interested in your patch and want to include it to the official Mogre.
Either inside the Mogre wrapping process (if we find where to modify it)
or as patch task in our tool MogreBuilder.

It would be nice if you send it to me by e-mail: beautyod at gmx.de
(Please include the word "Mogre" to the e-mail title. So I will it, even if it's catched by the spam filter.)