Posiadanie lokalnych list dla każdego systemu zwiększy wykorzystanie pamięci dla klas.
To tradycyjny kompromis czasoprzestrzenny .
Podczas gdy iteracja po wszystkich obiektach i sprawdzanie ich podpisów odbywa się bezpośrednio do kodu, może stać się nieefektywna w miarę wzrostu liczby systemów - wyobraź sobie wyspecjalizowany system (niech to będzie dane wejściowe), który szuka prawdopodobnie jednego interesującego podmiotu spośród tysięcy niepowiązanych podmiotów .
To powiedziawszy, to podejście może być nadal wystarczająco dobre w zależności od twoich celów.
Chociaż, jeśli martwisz się szybkością, musisz oczywiście rozważyć inne rozwiązania.
Czy każdy system powinien zawierać lokalną listę podmiotów, którymi są zainteresowani?
Dokładnie. Jest to standardowe podejście, które powinno zapewnić przyzwoitą wydajność i jest stosunkowo łatwe do wdrożenia. Narzut pamięci jest moim zdaniem pomijalny - mówimy o przechowywaniu wskaźników.
Teraz, jak utrzymać te „listy zainteresowań”, może nie być tak oczywiste. Jeśli chodzi o kontener danych, std::vector<entity*> targets
wystarczy klasa wewnętrzna systemu. Teraz robię to:
Usuwanie bytu jest całkowicie analogiczne, z tą jedyną różnicą, którą usuwamy, jeśli system pasuje do naszego obecnego podpisu (co oznacza, że byt tam był) i nie pasuje do nowego podpisu (co oznacza, że byt nie powinien już tam być ).
Teraz możesz zastanawiać się nad użyciem std :: list, ponieważ usunięcie z wektora to O (n), nie wspominając już o tym, że będziesz musiał przesunąć dużą część danych za każdym razem, gdy usuwasz ze środka. W rzeczywistości nie musisz - ponieważ nie zależy nam na przetwarzaniu zamówienia na tym poziomie, możemy po prostu wywołać std :: remove i żyć z faktem, że przy każdym usunięciu musimy jedynie wykonać O (n) wyszukiwania naszego podmiot do usunięcia.
std :: list dałoby ci O (1) do usunięcia, ale z drugiej strony masz trochę dodatkowego narzutu pamięci. Pamiętaj również, że przez większość czasu będziesz przetwarzał byty, a nie je usuwałeś - a to z pewnością odbywa się szybciej za pomocą std :: vector.
Jeśli jesteś bardzo krytyczny pod względem wydajności, możesz rozważyć nawet inny wzorzec dostępu do danych , ale tak czy inaczej utrzymasz pewnego rodzaju „listy zainteresowań”. Pamiętaj jednak, że jeśli utrzymujesz wystarczająco abstrakcyjny interfejs API Entity System, nie powinno być problemu z poprawą metod przetwarzania encji systemowych, jeśli spadnie z tego powodu ilość klatek na sekundę - więc na razie wybierz metodę, która jest najłatwiejsza do zakodowania - tylko następnie profiluj i popraw w razie potrzeby.