Znalazłem przyczynę wyciekających (okrutnie) instancji Node .... ale nie żebym od razu je wszystkie poprawił, co to to nie.
 |
| Wyciekające węzły. |
Kłopotem jest to, że w ramach list rozwijalnych montuję pod poszczególnymi opcjami dodatkowe informacje w ramach klas c# zwane metadata. Żeby klasy mogły trafić do takiego typowo godotowego miejsca muszą rozszerzać typ Node ponieważ przez instrukcję SetItemMetadata(index,metadata) mogę dodać tylko coś co jest widoczne w godot i rozszerza typ Variant
Poniżej przykładowa instrukcja dodania metadanych podczas wypełniania listy rozwijalnej OptionButton dla tarcz
ShieldSelect.GetOptionButton().SetItemMetadata(index, metadata);
Klasa dodana jako metadata to dane pancerza. W tym przypadku pierwszym parametrem jest definicja tarczy z jsona, Drugim parametrem jest grupa, do której ta tarcza należy.
var metadata = new ArmourMetadata(shield, shieldGroup.Key);
Ważna jest jednak definicja klasy ArmourMetadata a nie to co trzyma...
public partial class ArmourMetadata : Node <-- to te nody najczęściem mi leakują
{...pola klasy teraz nie są ważne...}
Jak widać rozszerzamy typ Node.
Jak to naprawiać
Ze względu na to, że część list rozwijalnych muszę czyścić i wypełniać na nowo per losowana postać, np. w przypadku broni gdzie chcę na liście oznaczyć, do których broni postać ma preferencyjne bonusy musze listy czyścić i wypełniać ponownie. Tworząc nowe węzły w drzewie...
Nie wystarczy wtedy przeiterować przez kolekcję dzieci dla OptionButtrona jak niżej
foreach (Node child in mentalContainer.GetChildren())
{ reszta kodu z usuwaniem dzieci }
i zrobić na poszczególnych dzieciach child.QueeFree() bo to nie zrzuca metadanych. Potrzeba oddzielnej iteracji po kolekcji metadanych i dodatkowe ich zrzucenie.
Stąd powstała metoda zrzucająca metadane zawarte pod poszczególnymi opcjami
public void ClearOptionsMetadata()
{
for (int i = optionButton.GetItemCount() - 1; i >= 0; i--)
{
//tu pobieramy metadane
Variant metadata = optionButton.GetItemMetadata(i);
if (metadata.VariantType == Variant.Type.Object)
{
Node node = metadata.As<Node>();
if (node.IsInsideTree())
{
//tu zrzucamy jeśli są wezłem w drzewie
node.QueueFree();
}
}
optionButton.RemoveItem(i);
}
}
Podejrzewam, że będę musiał wywołać tę metodę na jakimś ogólnym Dispose() dla obiektów...
Brak komentarzy:
Prześlij komentarz
Tu możesz wstawić swój komentarz