Du bist nicht angemeldet.

Werbeanzeige

21

02.01.2015, 23:18

Plane ich zumindest für Audio-Dateien wie Hintergrundstücke. Zum Start des Spiels werden einige Konfigurationsdateien geladen, die den Managern alle Ressourcen bekanntmachen. Die instanziieren dann alle Ressourcen, und setzen deren internen Status auf "Nicht Geladen". Wenn nun eine Ressource angefordert wird, so wird eine Methode aufgerufen, mit der sich die Ressource selbst lädt, dann ihren Status auf "Geladen" setzt, und dann die Kontrolle zurückgibt. Das heißt also, dass die Ressourcen irgendeinen Weg brauchen, um auf unterliegende Ressourcen zuzugreifen.

Sacaldur

Community-Fossil

Beiträge: 2 332

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

22

03.01.2015, 02:53

Für das Laden der Ressourcen sind ja die Manager verantwortlich und auch wenn das Laden asynchron durchgeführt werden soll, bleibt das eine Aufgabe der Manager und sollte von diesen durchgeführt werden. Genauso sollten bei einem Asynchronen Laden die Manager dafür sorgen, dass interessierte Stellen über Statusänderungen informiert werden.
Und es wurde bereits geschrieben: das Material sollte keine Referenz auf irgendwelche Manager haben.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

23

03.01.2015, 12:17

Ein Material lädt sich dann selbst aus einer Datei und setzt seinen internen Status auf "Geladen". Während es sich also lädt, muss es Zugriff auf die beiden anderen Manager bekommen, um die entsprechenden Sahder / Texturen zu laden.

Ich versuche erstmal zu rekonstrukieren wie ich das Laden deiner Ressourcen verstehe:
  1. Dein MaterialManager liefert dir auf Anfrage eine Material-Instanz. Zu dem Zeitpunkt ist die Instanz noch nicht vollständig geladen.
  2. (Vermutlich) asynchron sollen Shader, Textures und andere Ressourcen für das Material geladen und ihm zur Verfügung gestellt werden.
  3. Wenn du dein Material verwendest, sollen (hoffentlich alle) notwendigen Ressorucen dafür bereitstehen.
Soweit richtig? Ansonsten darfst du den Rest meines Posts de facto ignorieren :D:D

Dann würde ich
  • dem MaterialManager Referenzen auf ShaderManager, TextureManager etc. geben.
  • Außerdem könnte sich der MaterialManager jedes von ihm erzeugte und noch nicht fertig geladene Material merken, so dass er (z.B. asynchron) es vervollständigen/fertigladen kann. (Das entspricht, wie ich gerade sehe, Sacaldur's Aussage - die ich hiermit unterstütze^^)
Dann stellt sich natürlich die Frage, wie du das Material vervollständigst. Wie BlueCobold schon sagte: friend ist keine wirklich elegante Lösung. Die andere Möglichkeit wäre allerdnigs eine öffentliche Signatur im Sinne mymaterial.setTexture(mytex). Ob das schön ist, ist sicherlich Ansichtssache. Ich würde die öffentliche API empfehlen.

Ich hoffe es war irgendwie hilfreich :P

LG Glocke

BlueCobold

Community-Fossil

Beiträge: 10 890

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

24

03.01.2015, 12:32

Was spricht denn dagegen das Material vernünftig mit Konstruktor und Textur/Shader als Parameter zu initialisieren? Aus meiner Sicht doch gar nichts. Ein Material, was nicht geladen ist, ist de facto nutzlos. Also wozu überhaupt eine Instanz auf ein unvollständiges Material haben? Dessen Komponenten zur Laufzeit entfernen und neu laden zu können macht ebenfalls wenig Sinn. Denn auch da hätte man zwischenzeitlich wieder ein vollkommen nutzloses Material. Da kann man es genauso gut auch komplett wegwerfen und ein neues nehmen, sobald man es braucht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

TrommlBomml

Community-Fossil

Beiträge: 2 143

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

25

03.01.2015, 13:37

Wobei man durchaus zugeben muss, dass aus der Sicht der einzelnen Komponenten sehr sauber ist, wenn sie Ihren Kontext im Konstruktor erhalten, dass aber die öffentlichen Schnittstellen doch ziemlich fett werden lassen kann. Ressourcen sollen zentral irgendwo gehalten werden, damit sie gecached werden können, braucht man also ein Objekt, welches sich das merkt. Singleton ist furchtbar, sehe ich genauso, aber jedes "Pupsobjekt" bis in die tiefen des Spiels durchzureichen finde ich auch nicht gerade toll. Letztendlich sieht dass dann immer so aus. Letztendlich kann ich dadurch beide Seiten verstehen.

Mittlerweile bin ich eher auf der Schiene DependencyInjection-Frameworks zu benutzen, die Kontextabhängig sozusagen "Services" anbieten. Ist zwar meiner Meinung nach auch nur ein kompromiss aus Singleton und Austauschbarkeit - man muss ja nur ein Interface dazwischen hängen - aber funktioniert prima.

Und BlueCobold (ich will immer noch ein T schreiben, Grr!!!) hat natürlcih recht, lieber Objekt richtig initialiseren. Wenn man Asynchronität oder ähnliches haben möchte, dann sollte das auch in einem Interface untergebracht werden bzw. die Objekte über Events erzeugt werden. Halbfertige Objekte sind immer doof.

BlueCobold

Community-Fossil

Beiträge: 10 890

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

26

03.01.2015, 14:16

Mittlerweile bin ich eher auf der Schiene DependencyInjection-Frameworks zu benutzen, die Kontextabhängig sozusagen "Services" anbieten. Ist zwar meiner Meinung nach auch nur ein kompromiss aus Singleton und Austauschbarkeit - man muss ja nur ein Interface dazwischen hängen - aber funktioniert prima.
Eigentlich sind sie überhaupt kein Kompromiss aus Singleton und irgendwas, denn das Singleton kommt bei den Instanzen nicht vor. Maximal bei der Fabrik des Injection-Frameworks, was aber total Wurst wäre. Solche Frameworks sind gut, verschleiern aber auch gern Abhängigkeiten und da ist es dann ziemlich böse, wenn erst zur Laufzeit gewisse Klassen nicht gefunden werden. Für die Austauschbarkeit der verwendeten Implementierungen sind sie allerdings recht hübsch und man kann damit auch prima testen, indem der Test zentral eine Implementierung gegen einen Mock tauscht. Aber ich schweife ab... ;)
Kern ist: Faulheit sollte nie ein Grund sein irgendwelche Abhängigkeiten nicht kenntlich zu machen oder notwendige Parameter nicht weiterzugeben. Wenn sie über zig Schichten hindurchgereicht werden, sollte man überlegen, ob man nicht einen Fehler in seinem Design hat und Dinge an falschen Stellen initialisiert (oder eben nicht initialisiert).
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

27

03.01.2015, 16:15

Danke erstmal für eure Ideen und Meinungen zu dem Thema.

Die Singletons habe ich jetzt rausgeschmissen, ihr habt mich überzeugt, dass diese nicht zu sondernlich gutem Code führen. Was den Material-Manager betrifft, so will ich es ähnlich zu Glockes Vorschlag lösen, dass also der Material Manager Zeiger auf den Shader- und Texture-Manager besitzt, und in einem Post-Processing-Step die Shader und Texturen für die jeweiligen Materialien einsetzt. Der Grund, wieso Ressourcen auf "Geladen" bzw. "Nicht geladen" gesetzt werden, und nicht nach erfolgreichem Laden erstellt werden, ist folgender: Ich möchte ein System bauen, das es mir erlaubt, Ressourcen einer Spielwelt, die zwar noch existieren, aber nie benutzt werden (bspw. gerät ein Gegner weit aus dem Sichtfeld) trotzdem entladen zu können, aber sie im Notfall ohne viel Aufwand wieder Laden zu können (bspw. Gegner wird teleportiert). Wenn ein Actor jetzt aber ein Sprite, ein Material, eine Animation, und evtl. noch weiteres besitzt, will ich ihm nicht jeweils den passenden Manager + den Identifier der Ressource übergeben, sondern ich will ein Objekt haben, dem ich einfach sagen kann: "Hier, ich brauche dich wieder, also lade dich bitte." Und bisher hatte ich mit dieser Umsetzung keine großen Probleme.

Auf jeden Fall möchte ich mich nochmal bedanken für den Hinweis mit den Singletons. In meinem Code findet sich jetzt kein einziger mehr :)

Liebe Grüße,
~ EuadeLuxe ~

28

03.01.2015, 19:27

Ich möchte ein System bauen, das es mir erlaubt, Ressourcen einer Spielwelt, die zwar noch existieren, aber nie benutzt werden (bspw. gerät ein Gegner weit aus dem Sichtfeld) trotzdem entladen zu können, aber sie im Notfall ohne viel Aufwand wieder Laden zu können (bspw. Gegner wird teleportiert). Wenn ein Actor jetzt aber ein Sprite, ein Material, eine Animation, und evtl. noch weiteres besitzt, will ich ihm nicht jeweils den passenden Manager + den Identifier der Ressource übergeben, sondern ich will ein Objekt haben, dem ich einfach sagen kann: "Hier, ich brauche dich wieder, also lade dich bitte." Und bisher hatte ich mit dieser Umsetzung keine großen Probleme.


Der einzige Aufwand einer Ressource ist das Laden. Dein Konzept macht den Manager komplett überflüssig. Wenn Ressourcen sich selbst laden können und du von außen unload/load aufrufst hast du keinen Manager mehr, denn ein Manager managed den Lebenszyklus.
Selbst wenn du asynchron lädst hast du keinen Vorteil davon. Lazy Init ist gut, wenn man in Webanwendungen auf Datenbanken oder Netzwerkressourcen zugreift, aber in Spielen ist das ziemlich kontraproduktiv kann zu z.B. Framedrops führen.
Was du eigentlich willst ist die Ressourcen im Manager zu cachen, also z.B mit einen MostyRecentlyUsed Cache.

Zitat von »Chad Fowlder«

Leider hat die Software-Branche viele flache Spezialisten hervorgebracht, die die Bezeichnung Spezialist nur als Entschuldigung dafür verwenden, nur eine Sache zu kennen.

Werbeanzeige