TCastleScene.clear?

I have 2 tcastlescenes. I add scene2 to scene1. If I then call scene1.clear, should it free scene2? scene1 is the owner of scene2. I was under the impression scene2 would be freed when scene1 is cleared, but it appears to not be the case?! Am I missing something?

Indeed, it’s a trap. When you call TCastleSomething.Clear you remove children. However, you don’t Free the children.

What happens under the hood:

Let’s imagine you do Scene1 := TCastleScene.Create(FreeAtStop). Note that FreeAtStop thing - it’s “owner” of the scene, or in other words - object that will Free this scene if it gets freed itself. When the TCastleView calls Stop it will also call FreeAtStop.Free which in turn will free the Scene1.

Now you create Scene2 := TCastleScene.Create(Scene1); Scene1.AddChildren(Scene2);. This time Scene2 is “owned” by Scene1. So when Scene1 calls Free the Scene2 will also free. However, this will not happen when you call Scene1.Clear. It only removes Scene2 from the active children, but doesn’t free it.

So, if you want to remove AND free Scene2 you’ll need to first remove and then free it, like this:

Scene1.Remove(Scene2); // or Scene1.Clear;
FreeAndNil(Scene2);

UPDATE: In my game I have adding/removing UI buttons very often. And to avoid accumulating memory too much, I’ve made a special method ClearAndFree which does very similar to the above, just calls Remove and then Free on all children sequentially.

Actually you can just do FreeAndNil(Scene2). There’s no need to remove Scene2 from parents – no need for Scene1.Remove(Scene2), and no need for Scene1.Clear (unless Scene1 may have other children you also want to remove). Scene2 will be removed from parents automatically when it is freed, we make it automatically to avoid having ever dangling pointers in the hierarchy.

The general way of thinking about this is, that I find useful: the ownership is independent from parent-child relationship. This is true in CGE components, just like in e.g. VCL or LCL or FMX components.

  • Ownership says that owner automatically frees the owned components, when the owner gets destroyed.

  • Parent-child dictate what is visible underneath what, and the coordinate system (children are specified in coordinate system of the parent).

Having these 2 systems independent is very useful – you often want to free things at different times when they are removed from parents.

The TCastleTransform.Clear only deals with parent-child relationship, and never frees anything.

See also Castle Game Engine Overview For Unity Developers | Castle Game Engine - " What is the difference between Owner and Parent in CGE?".

P.S. That being said, I recognize that “Clear” name may be confusing here, so let me at least make it a “documented trap” :slight_smile: Added API docs:

(These are committed to a delphi-linux branch now, but shall very soon be merged to master :slight_smile: )

Thanks for the clarifications!