Accoppiamento sistema componente entità

3

Ultimamente ho lavorato su un piccolo progetto personale che è fondamentalmente un sistema di Entity Component System con sistemi aggiornati.

Anche se ho un'idea abbastanza precisa del modo in cui il framework dovrebbe funzionare, a causa della mancanza di esperienza, ho problemi a mantenere tutto disaccoppiato.

Alcuni dettagli sul framework:

Ogni entità è definita dai suoi componenti.

I sistemi sono responsabili della modifica effettiva delle entità modificandone i componenti.

Al fine di migliorare la località di riferimento, invece di mantenere ciascun componente nell'entità appropriata, tutti i componenti sono memorizzati in vettori omogenei e ogni entità mantiene un elenco di indici per ciascun vettore.

Poiché ogni sistema modifica componenti specifici, dovrebbe mantenere un elenco solo delle entità con i componenti corrispondenti.

Il modo in cui mi sono occupato di tutto questo fino ad ora era avere un ComponentManager, un EntityManager e un SystemManager. Queste classi tuttavia hanno un accoppiamento molto stretto l'una con l'altra. EntitManager deve avere accesso a ComponentManager per gestire la dimensione degli elenchi di indici e la mappatura di ciascun tipo di componente. Ha anche bisogno di accedere per aggiungere effettivamente i componenti nel vettore appropriato. Un altro accoppiamento è tra EntityManager e SystemManager. Ogni volta che un'entità viene creata, deve essere aggiunta all'elenco dei Sistemi appropriati.

Un bus di eventi generici sembra aiutare ma non sono sicuro di come implementarlo senza renderlo globale.

Come posso migliorare questo design rimuovendo l'accoppiamento pur mantenendo la funzionalità del sistema?

    
posta Veritas 27.08.2014 - 14:04
fonte

2 risposte

3

How do I improve this design by removing coupling while still maintaining the system's functionality?

Non entri molto nella tua funzionalità, quindi farò qualche ipotesi e ripercorrere gli approcci generali:

  • Sistema - > Componente - tu dici che il Sistema funziona solo con componenti specifici (ad esempio, un sistema di fisica che modifica le velocità), allora perché il sistema si preoccupa delle entità? Il sistema dovrebbe essere libero di lavorare con i componenti in relativo isolamento.
  • Entity - > Componente - tu dici che esiste una sorta di elenco di indici tra l'entità e il suo componente. Questo mi sembra strano. Le entità dovrebbero avere riferimenti ai loro componenti (o viceversa) - anche se è sottile come una chiave esterna. Utilizzando gli indici, stai esponendo un dettaglio di implementazione da ComponentManager che sta danneggiando il tuo accoppiamento.
  • Entity - > Sistema - di nuovo, se i sistemi funzionano con componenti, non ci dovrebbe essere nessun legame qui. Viene creata un'entità, che sa quali componenti creare (o viceversa, i componenti sono costruiti e quindi aggregati / dipendenti risolti dall'entità) - indipendentemente dal sistema che li manipola.

Personalmente, il design che ho visto funziona bene perché l'entità è uno strato molto, molto sottile che aggrega i componenti, agendo come un contesto in modo che i componenti possano essere piacevoli l'uno con l'altro. Il mondo esterno può quindi interrogare e agire sull'interfaccia pubblica dei componenti.

    
risposta data 27.08.2014 - 17:49
fonte
2

Da quello che posso capire, hai qualcosa di simile a questo:

EtuttoquestostrettoaccoppiamentotraquestiManagersèstrettamenteperscopidiottimizzazione(usandogliindiciperridurreicostisulladimensionediunpuntatorementresiottieneunafacilelocalizzazionespazialeusandounvettore,ades.)

Inquestocaso,suggeriròqualcosadibizzarro.

L'ideaèdiotteneretuttociòchetiservedaunoggettounpo'piùmonoliticoEcsManagercheconsolidituttequestepreoccupazioni.QuestopotrebbesembrareunaviolazioneborderlinediSRP,maquandosihannoquestiprogettidimanagercosìstrettamenteaccoppiati,potrebbesemplificarel'implementazionepraticaeprogettareunpo'piùdi3classichesonostrettamenteaccoppiatetraloro.

Ineffettiquestoèquellochehaipermeconquestitremanagercosìstrettamenteaccoppiati.Voglionodiventareunmanagerperdominarlitutti.PensochepossiamofarcelaperchéleesigenzediunquadroECSnonavrannorequisitidiversi:ciòdicuihabisognounECSèbencompreso.

Potrestiancoramantenerequesti"subgestori" se questo semplifica l'implementazione di EcsManager un po ', anche se potrebbe essere ancora più semplice se hai fatto questo:

AgeneraleventbuswouldappeartohelpbutIamnotsurehowtoimplementitwithoutmakingitglobal.

Perquestaparte,pensocheaiuterebbesial'efficienzachelasemplicitàausaresolounapprocciopigro.Adesempio,quandonuoveentitàvengonoaggiunteaunsistema,nuovicomponentiaun'entitàonuovitipidicomponentidiinteressevengonoaggiuntiaunsistema,èsufficientecontrassegnareisistemirilevanticome"sporchi". Quindi, quando si arriva a un punto in cui i sistemi vengono elaborati, se sono sporchi, possono recuperare l'ultimo elenco di entità contenenti i componenti interessati al sistema, e magari con gli indici alle entità corrispondenti ordinate al volo (miglioreranno località spaziale).

Il tuo EcsManager memorizza in realtà tutti i dati reali e carnosi associati al framework ECS. Le tue classi Entity e System e Component quindi si trasformano in maniglie per comodità.

Penso che questo sia l'approccio più semplice dato il tipo di design che si sta creando, e anche rendere un po 'più semplice il raggiungimento della sicurezza e dell'efficienza dei thread (anche se l'efficienza del thread è difficile qui).

    
risposta data 08.01.2016 - 04:57
fonte