modiX wrote: ↑Mon Dec 11, 2017 11:21 am
Interesting. So in the case of using a shape on more than one fixture the shape will be copied by value, not by reference. In that case I see no reason why there should not be a shape:destroy() or why the body:destroy() should not include the shapes of its fixtures. If the latter already happens, someone should update the documentation regarding this.
So in other words, if I make sure there is no hard references to the shapes, the shapes will be destroyed for me? Do I have to tell the garbage collector to start fetching things up for me?
You seem obsessed with having other people add tons of explicit documentation while there is already a large amount of documentation available as well as the original box2d docs still existing.
But alright. Let's take a step back and look and what happens and how box2d works.
In box2d. You first need a world. Your physics world. All physics objects will be located within this world.
This happens via bodies. The world has a list of bodies. It does not care for fixtures or shapes. This is the only place references to physics objects are stored. Without body there is no collision.
A shape defines the outline of your physics object. It is essentially pure data, with a few util functions for accessing that data. A shape on it's own is nothing but a bit of occupied ram. A quite tiny bit. A shape is completely ignored by the world itself.
And then we have a fixture. A fixture mounts a shape to a body as well as defines some collision resolution data (e.g. density and friction).
In a very simplified and non accurate way. The world now goes through all bodies, checks all fixtures, gets all shapes and looks if they overlap. If so, it will use the data within the fixture to resolve the collision if appropriate.
This means. As soon as you destroy the body. It does not exist in your world anymore. Once all references to it are removed, the garbage collector will shortly after notice this and clean up everything behind the scenes.
However. Maybe you don't want to destroy the whole body. Since a body can have multiple fixtures, being able to remove a single one is important. Destroying the fixture will unmount the shape from the body. And hence forward only the remaining shapes will be used for collision detection. Once all references are removed, the garbage collector will shortly after notice this and clean up everything behind the scenes.
And now shapes... shapes are nothing. Destroying a shape has to destroy the fixture. Since otherwise it points at nothing and box2d will either crash, throw an error or fix this logic error for you in the best case and destroy the fixture (I haven't looked at the code so I'm not sure which of the 3 things happens).
Destroying a shape could only possibly result in freeing up ram. A shape has no list of fixtures. So without a lot of book keeping behind the scenes, it can not possibly destroy the fixture and you are running into issues.
Like with all userdata (if implemented correctly. Which is the case in love), as soon as it goes out of scope and is collected by the garbage collector the destructor is called, the ram is freed and everything is taken care of.
There is literally no reason to ever explicitly destroy a shape. It's on the same level as wanting to explicitly destroy a number or string. Just with potential to cause issues instead of just freeing ram.
This function doesn't exist to protect you from doing bad things.
Edit: For reference. You can't destroy audio sources either. Nor any other type of userdata. love.physics is special in that regard because it might be necessary to remove things from the system immediately, even if the variable might still exist for a while until the garbage collector clears it.