le système d'entités me fait grandement penser au duck typing
C'est du duck typing dynamique si on veut.
Je suis d'accord avec toi sur le principe mais, désolé, je ne le vois pas dans ton implémentation.
C'est tout à fait vrai !
Je ne sais pas ce qu'il en est avec la norme du C++11 mais à ma connaissance rien ne garantie que les données d'une map soient stockées de manière linaire.
Tout à fait, mais ici, l'idée de la map, c'est de retrouver le composant en ayant l'entité, pas de stocker le composant. La manière de stocker le composant est laissée à l'utilisateur.
Si c'était le cas, le système ne parcoure pas dans l'ordre des composants mais dans celui des entités. Pour un exemple simple, il se peut que le parcours des composants se fasse dans l'ordre, mais dans un cas concret avec surpression/ajout d'entités, il y a de fortes chances que ça soit pas le cas. Qui plus est, ça casse quand même le cache vu que tu recharges ton conteneur des entités pour passer à la suivante.
Oui, l'ordre des entités n'est pas le même que l'ordre des composants. Mais globalement, actuellement, avec un set ordonné, l'ordre des entités sera l'ordre des composants (tant qu'on n'a pas détruit une entité). Si je prend un set non ordonné, là ça va poser des problèmes. J'avais trouvé un très bon article qui parlait de ce problème et qui proposait une solution (assez complexe) mais je n'ai pas réussi à remettre la main dessus au moment d'écrire l'article. Dès que je le retrouve, je le mets ici.
Tu parles de Boost.Pool dans ton tuto, c'est une bonne solution pour éviter les allocations dynamiques mais je pense que c'est à la bibliothèque de gérer ce problème de mémoire et de garantir que la mémoire est alignée. (Ce point là est discutable, je l'accorde)
Perso, je préfère laisser l'utilisateur faire ce qu'il a envie. S'il doit régler un problème de mémoire, il aura la main dessus. Et si jamais il n'y a pas de problème, et bien pas besoin de solution.
Dans ton exemples tu pourrais réunir les composants Coords et Look en un seul. À ce moment, le système Render peut parcourir directement les composants "GraphicalInfo" de manière linéaire sans passer par les entités. Par contre je n'ai pas de solution évidente pour ce qui est des systèmes "transverses" du type Graphics et Physics: vu que tu travailles sur deux composants en même temps, tu es obligé de passer par les entités. (Peut être que la littérature sur le sujet apporte une solution)
Ce cas où un système va traiter plusieurs composants est assez courant je pense. Après, rien n'empêche d'optimiser pour le cas où un système s'occupe d'un unique composant. Mais du coup, on retombe sur le problème d'avant : si c'est la bibliothèque qui alloue, c'est ok, sinon c'est foutu pour l'optimisation. Et puis le deuxième problème, c'est qu'il faut l'entité associée au composant et si tu parcoures les composants tels quels, tu auras du mal à savoir quelle est l'entité correspondante.
On peut voir le système d'entités/composants comme un système qui associe à un même nom (l'entité) différentes valeurs (les composants) selon "l'espace" dans lequel on regarde (les types des composants). La map dans ton Store (ou le deuxième vecteur dans ma proposition d'implémentation) étant le traducteur entre l'espace commun et les espaces spécifiques.
Oui, si je comprends bien ce que tu dis, c'est bien ça. Et je ne pense pas qu'il y ait une solution unique. J'en propose une, qui est sans doute très imparfaite mais qui m'ira bien jusqu'à ce que j'ai des problèmes de perfs. Et vu la machine sur laquelle je code, je pense que je les verrai assez vite les problèmes de perfs s'il y en a.
Qui plus est le code est propre et il y a de la doc.
[^] # Re: Duck typing et implementation
Posté par rewind (Mastodon) . En réponse à la dépêche Je crée mon jeu vidéo E01 : les systèmes à entités. Évalué à 3.
C'est du duck typing dynamique si on veut.
C'est tout à fait vrai !
Tout à fait, mais ici, l'idée de la map, c'est de retrouver le composant en ayant l'entité, pas de stocker le composant. La manière de stocker le composant est laissée à l'utilisateur.
Oui, l'ordre des entités n'est pas le même que l'ordre des composants. Mais globalement, actuellement, avec un set ordonné, l'ordre des entités sera l'ordre des composants (tant qu'on n'a pas détruit une entité). Si je prend un set non ordonné, là ça va poser des problèmes. J'avais trouvé un très bon article qui parlait de ce problème et qui proposait une solution (assez complexe) mais je n'ai pas réussi à remettre la main dessus au moment d'écrire l'article. Dès que je le retrouve, je le mets ici.
Perso, je préfère laisser l'utilisateur faire ce qu'il a envie. S'il doit régler un problème de mémoire, il aura la main dessus. Et si jamais il n'y a pas de problème, et bien pas besoin de solution.
Ce cas où un système va traiter plusieurs composants est assez courant je pense. Après, rien n'empêche d'optimiser pour le cas où un système s'occupe d'un unique composant. Mais du coup, on retombe sur le problème d'avant : si c'est la bibliothèque qui alloue, c'est ok, sinon c'est foutu pour l'optimisation. Et puis le deuxième problème, c'est qu'il faut l'entité associée au composant et si tu parcoures les composants tels quels, tu auras du mal à savoir quelle est l'entité correspondante.
Oui, si je comprends bien ce que tu dis, c'est bien ça. Et je ne pense pas qu'il y ait une solution unique. J'en propose une, qui est sans doute très imparfaite mais qui m'ira bien jusqu'à ce que j'ai des problèmes de perfs. Et vu la machine sur laquelle je code, je pense que je les verrai assez vite les problèmes de perfs s'il y en a.
J'ai fait des efforts ;)