Component Based Design



  • Nachdem ich etwa 700 Artikel über Component Based Design gelesen habe, wollte ich mich dann mal selbst an das Grundmodell machen. Sollte ja eigentlich schnell gehen, die Arbeit liegt dann ja erst in den Komponenten selbst - nicht in dem System. Kurz nach den ersten paar Zeilen Code haben sich mir allerdings einige Fragen gestellt, auf die ich nicht wirklich eine Antwort finden konnte. Das mag auch damit zusammenhängen, dass in diesen Artikeln nie wirklich Code gezeigt wurde. (Etwas schlechter Pseudocode mit Glück.)
    Könnte mir jemand mal zeigen wie man so ein System aufzieht in C++? Insbesondere frage ich mich: Wie speichere ich den Typ einer Komponente? Muss ich das überhaupt? Machen zwei Komponenten vom gleichen Typ Sinn? Wie kommunizieren Komponenten untereinander? Wie kommuniziert das System mit der Außenwelt und umgekehrt? (Input, Rendering.)



  • Das gehört beim CBD nicht dazu. CBD ist ja nur eine Idee bzw. ein Pattern, keine Implementierung. Wär ja ziemlich unflexibel, wenn man da gleich festlegen würde, wie die Komponenten miteinander kommunizieren usw. Darum musst du dich immer noch selber kümmern und selber entscheiden, wie du das löst.



  • Dann suche ich eben nicht mehr die, sondern nur noch eine gute Lösung.



  • Es gibt wie immer viele Möglichkeiten... Du könntest die Kommunikation z.B. über Messages oder Events lösen. Du musst das Gesamtkonzept durchdenken und schauen, welche Methode am ehesten passt und dir zusagt. Die Aussage, dass du dich nach dem CBD richten willst ist noch kein Kriterium für die die interne Kommunikation. Jede etablierte Methode wäre legitim.



  • Könnte ich dann mal ein Codebeispiel für eine etablierte Methode sehen?


  • Mod

    ich glaube da ist einiges ein implementierungsdetails drinnen.



  • Danke für den Link, dort findet man tatsächlich ein bisschen Code, aber wie die Komponenten jetzt kommunizieren sehe ich nicht? Wie requestet zB eine Physik Komponente die der anderen Objekte?


  • Mod

    Tricky aspect: components that share data or otherwise communicate 2 options:

    • 1. Select one to own the data, other references
      through owner by resolving handle
      -1. E.g. ShotActions call into Shot to notify of
      events
    • 2. Scatter-gather idiom
      -1. PU update stages gather inputs for &
      scatter outputs from SPU processes
      -2. Involves copying
      -3. Better for async processing

    1. ist also dass die components sich das ziel raussuchen und dann auf die daten schreibend zugreifen, quasi Manager.Resolve<CDoor>(ID)->Open(true);

    2. ist dass komponenten beim initialisieren shared data anlegen, beim updated schreiben alle ihre daten an die shared objekte und dann gibt es eine art 'post update' bei dem alle ihre daten rauslesen.

    ersteres ist schoen einfach im single thread betrieb zu implementieren, da ja nur ein thread durchlaeuft und seriel (sozusagen garantiert 'atomic') nacheinander die states umwandelt, dabei kann man von ueberall auf alles zugreifen.

    zweites ist sehr schoen parallelisierbar, jedes objekt kann sein update als 'job' ins jobsystem einfuegen und wird unabhaengig abgearbeitet, der state von den objekten wird waehrend dieses abarbeitens nicht veraendert, dadurch ist die sache stabil, dafuer schreiben alle die zukunfts-states in die shared objekte. wenn alle updates durch sind, werden nochmal alle objekte ins jobsystem fuer ein post-update eingefuegt und lesen sich neue moegliche states aus den shared objekten.

    hab mit beiden gearbeitet und finde beides recht 'lustig' 🙂
    1. da kann es so komplexe dependencies mit zwischen-states geben, das wirklich komisch bugs entstehen. eine komponente kann state A abfragen, ruft dann was auf und ueber 5ecken wird state A veraendert, dann kommt der aufruf zurueck und man moechte weiterarbeiten mit der annahme dass state A noch gleich ist, ist er aber nicht und es passieren die komischten dinge.
    2. kann viel latenz haben. wenn du dir z.B. einen graphen vorstellst ueber den man logik scripted. jedes 'update' schreibt jede node ihren state an eine shared 'wire' und jedes 'post-update' lesen die nodes ihren input. schwubs bastelt dir ein scripte was mit 100nodes und bei z.b. 25update/s dauert es 4sekunden wenn ein player eine tuer aufmachen will 😃



  • Und wie bekommen die Komponenten dann die Referenzen der anderen Komponenten bei Variante 1?
    Gibt es zu der pdf eigentlich auch noch ein Video?



  • Komposer schrieb:

    Und wie bekommen die Komponenten dann die Referenzen der anderen Komponenten bei Variante 1?

    ...Manager.Resolve<CDoor>(ID)...



  • Hast du diesen Stackoverflow-Post schon gesehen?

    Das Artemis-Framework soll auch so ein Design implementieren, hab ich mir aber noch nicht genau angeschaut.


Anmelden zum Antworten