Le fait d'avoir des listes locales pour chaque système augmentera l'utilisation de la mémoire pour les classes.
C'est un compromis spatio-temporel traditionnel .
Bien que l'itération à travers toutes les entités et la vérification de leurs signatures soit directement du code, cela peut devenir inefficace à mesure que votre nombre de systèmes augmente - imaginez un système spécialisé (laissez-le entrer) qui recherche son entité probablement unique parmi des milliers d'entités non liées .
Cela dit, cette approche peut toujours être suffisante en fonction de vos objectifs.
Bien que, si vous vous inquiétez de la vitesse, il existe bien sûr d'autres solutions à envisager.
Chaque système devrait-il contenir une liste locale d'entités qui l'intéressent?
Exactement. Il s'agit d'une approche standard qui devrait vous donner des performances décentes et est relativement facile à mettre en œuvre. La surcharge de mémoire est négligeable à mon avis - nous parlons de stocker des pointeurs.
Maintenant, comment maintenir ces "listes d'intérêt" peut ne pas être si évident. En ce qui concerne le conteneur de données, std::vector<entity*> targets
la classe système interne est parfaitement suffisante. Maintenant, ce que je fais, c'est ceci:
La suppression d'une entité est entièrement analogue, à la seule différence que nous supprimons si un système correspond à notre signature actuelle (ce qui signifie que l'entité était là) et ne correspond pas à la nouvelle signature (ce qui signifie que l'entité ne devrait plus être là ).
Maintenant, vous envisagez peut-être d'utiliser std :: list car la suppression du vecteur est O (n), sans mentionner que vous devrez déplacer un gros morceau de données chaque fois que vous supprimez du milieu. En fait, vous n'êtes pas obligé - puisque nous ne nous soucions pas du traitement de l'ordre à ce niveau, nous pouvons simplement appeler std :: remove et vivre avec le fait qu'à chaque suppression, nous n'avons qu'à effectuer une recherche O (n) pour notre entité à supprimer.
std :: list vous donnerait O (1) supprimer mais de l'autre côté vous avez un peu de surcharge de mémoire supplémentaire. Souvenez-vous également que la plupart du temps, vous allez traiter des entités et non les supprimer - et cela se fait sûrement plus rapidement en utilisant std :: vector.
Si vous êtes très critique en termes de performances, vous pouvez envisager un autre modèle d'accès aux données , mais dans les deux cas, vous conservez une sorte de "listes d'intérêt". N'oubliez pas que si vous conservez votre API Entity System suffisamment abstraite, cela ne devrait pas être un problème pour améliorer les méthodes de traitement des entités des systèmes si votre taux de rafraîchissement baisse à cause d'eux - donc pour l'instant, choisissez la méthode la plus facile à coder pour vous - uniquement puis profilez et améliorez si nécessaire.