First : TCastleTransformend.Exists:= false;
Secound : TCastleTransform.Update(const SecondsPassed: Single; var RemoveMe: TRemoveType); RemoveMe := rtRemove;
First = Second?
procedure TTowerManager.ClearAllTower;
var
i : Integer;
Tower : TTower;
begin
for i:= FTowerList.Count - 1 downto 0 do
begin
Tower := FTowerList.Items[i];
if Assigned(Tower) then
begin
if Tower.Exists then
begin
Tower.Exists := False; //need to TCastleViewport.Items.Remove(Tower) ?
end;
FreeAndNil(Tower);
end;
end;
end;
What is TTower ? how do you create them? If you pass an owner to constructor Create (I assume TTower is descendant of TCastleTransform), then Owner will be responsible for their Freeing. If you create them manually and do not pass Owner, but instead store in some List (FTowerList) then you need manually control what you do.
Items object of viewport is not responsible for freeing, it is about being a parent to them and showing them inside a viewport.
Admittedly I’m also not clear about the question:) You’re posting pieces of code or pseudo-code, and they only show parts of the code, it is not clear where is the problem / where is the question
What are you actually trying to do? Provide more description what is your ultimate goal, so we don’t have XY problem and we don’t guess If something is not working for you? Provide a compete testcase where things fail to compile / work.
Some information:
Setting Exists to false means that the component remains in the tree (e.g. in Viewport.Items, if that’s where it was added), but behaves as if it wasn’t there. So it will not be rendered (visible), will not collide etc., but is still on Viewport.Items, so it’s easy to make it active again.
Removing from Viewport.Items means that the component is not part of the viewport anymore (and setting Exists to false is not necessary in this case). So it will not be rendered (visible), will not collide etc.
Independently of above, you need to free the component at some time. Freeing it → makes AD 1 and AD 2 unnecessary, freed component is automatically removed from the viewport .
Note: I didn’t review your code completely, but I understand your question is fixed. Cool!
Some notes from scanning your code:
Doing Self.Exists:= False, FScene.Exists:= False before FNeedFree := True; seems unnecessary. If you will soon free this instance (which also frees FScene), then it doesn’t matter what will be their Exists value. (unless they get rendered for 1 frame with invalid state?)
This looks dangerous:
This looks wriong – you are freeing the instance of Self, but this Update is running inside a loop that iterates over components, and your component is part of that list. This is a problem – by freeing yourself, you decrease the loop count, and undefined things (crashes, missing calls to other updates) may happen.
The RemoveMe parameter was introduced to Update as one way to avoid this mistake. Instead of Self.Free, do Remove := rtRemove. I realize that you maybe had some issues with this (judging from your first post in this thread), then we have to explore then and fix – simply doing Self.Free is really dangerous, even if it seems to work. See TCastleTransform.Update docs.