Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

01.06.2017, 23:11

C# MonoGame ResourceManager Fehlerbehandlung

Ich hab unten mal meine Textureverwaltungsklasse und deren Texture-Loader gepostet.
Mich stört daran, dass man ManagedResource falsch verwenden kann indem man Dispose und nicht ReleaseReference aufruft. Geht das nicht irgendwie besser?
Und die Fehlerbehandlung hab ich auch noch nicht beachtet.
In meinen Büchern wird das oft ausgeklammert um nicht vom eigentlichen Thema abzulenken. Sollte ich alle parameter mit if(irgendwas == null) dann wirf Exception zukleistern? Ich hatte auch mal was von NullObjekten gelesen (siehe TextureLoader). Ich hab das gefühl, dort ist kein guter platz für die Erzeugung des Nullobjekts.

Wie behandelt ihr diese Themen?



2

01.06.2017, 23:35

Ok, dass erste Problem habe ich gelöst in dem ich ein Interface dazwischen geschoben habe.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

02.06.2017, 09:08

Was genau macht der ResourceManager jetzt eigentlich besser als C# mit seinem internen Reference-Counter? Und wo ist der Vorteil des Managers, wenn ich z.B. eine Ressource hole, sie dann nicht mehr brauche (jetzt gibt der 'Manager' sie ja frei) und gleich darauf an einer anderen Stelle wieder brauche? Dann wird der ganze Quatsch ja trotzdem ständig geladen und wieder freigegeben.
Ich würde mir erstens überlegen, ob ich die Referenz-Zählung wegwerfe, denn das macht C# ja intern sowieso schon und zweitens, ob der Life-Cycle wirklich so gewünscht ist und nicht lieber irgendwie anders behandelt sinnvoller wäre - z.B. ein Resource-Manager pro Level oder Menü oder Game-State oder ähnliches, wo der Scope von Ressourcen wesentlich besser geregelt ist. Denn aktuell ist der gesamte Manager aus meiner Sicht unnötig und managed überhaupt gar nichts, weil man ihm ja ständig von außen sagen muss, was er zu tun hat und er dann auch nur das macht, was man bei C# ohnehin kostenlos bei Referenzen schon bekommt.

Meine Resource-Manager funktionieren z.B. so:
1) Sie haben einen Cache. Wird etwas von außen angefragt und ist nicht im Cache, wird es (unter Umständen, siehe unten) geladen und zurückgegeben.
2) Sie sind nested und scoped. Heißt ich habe einen primären Resource-Manager (oder mehrere) und für Level und Menüs habe ich ihm (oder ihnen) unterstellte Child-Manager. Fragt nun ein Level oder ein Menü etwas an, wird es vom Child-Manager zurückgegeben und gehalten.
3) Hält ein Child-Manager eine Ressource und dieselbe wird im Parent-Manager ebenfalls angefragt, wandert sie einen Scope nach oben.
4) Fragt man ein Child-Manager nach einer nicht-gecachten Ressource, fragt er andere Manager aus demselben Scope, ob sie die Resource haben und gibt dann deren zurück.
5) Fragt man ein Child-Manager nach einer nicht-gecachten Ressource, fragt er den Parent-Manager, ob er die Resource hat und gibt dann dessen zurück.
6) Man kann keine Resource explizit aus einem Manager entfernen, denn das geht niemanden etwas an
7) Der Manager gibt immer nur weak/unowned-References zurück. Wenn er eine Ressource also freigibt, ist sie weg. Niemand anders kann somit Ressourcen halten und an der Freigabe hindern oder sie freigeben, obwohl sie gebraucht wird.

Die Vorteile davon: Wird ein neues Level geladen, fragt dessen Manager andere bisherige Manager aus dem demselben Scope (also andere ResourceManager für 'Level'), ob sie die Ressource schon haben und gibt dann deren zurück. Falls nicht, lädt er sie. Wird nun ein Level aus dem Speicher geworfen, fliegt auch der dazugehörige Manager weg und alle Ressourcen, die ausschließlich in ihm geladen wurden. (so kann man z.B. neue Level laden, ohne bereits geladene Ressourcen neu laden zu müssen [mobile Games <--> Speicher! Geschwindigkeit!] und beim Entfernen eines Levels wird nur freigegeben, was wirklich niemand mehr nutzt.
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]

Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von »BlueCobold« (02.06.2017, 09:28)


4

02.06.2017, 10:14

Danke für diese ausführliche Antwort. Deine Beschreibung macht Sinn.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

5

02.06.2017, 10:49

Meine Resource-Manager funktionieren z.B. so:
1) Sie haben einen Cache. Wird etwas von außen angefragt und ist nicht im Cache, wird es (unter Umständen, siehe unten) geladen und zurückgegeben.
2) Sie sind nested und scoped. Heißt ich habe einen primären Resource-Manager (oder mehrere) und für Level und Menüs habe ich ihm (oder ihnen) unterstellte Child-Manager. Fragt nun ein Level oder ein Menü etwas an, wird es vom Child-Manager zurückgegeben und gehalten.
3) Hält ein Child-Manager eine Ressource und dieselbe wird im Parent-Manager ebenfalls angefragt, wandert sie einen Scope nach oben.
4) Fragt man ein Child-Manager nach einer nicht-gecachten Ressource, fragt er andere Manager aus demselben Scope, ob sie die Resource haben und gibt dann deren zurück.
5) Fragt man ein Child-Manager nach einer nicht-gecachten Ressource, fragt er den Parent-Manager, ob er die Resource hat und gibt dann dessen zurück.
6) Man kann keine Resource explizit aus einem Manager entfernen, denn das geht niemanden etwas an
7) Der Manager gibt immer nur weak/unowned-References zurück. Wenn er eine Ressource also freigibt, ist sie weg. Niemand anders kann somit Ressourcen halten und an der Freigabe hindern oder sie freigeben, obwohl sie gebraucht wird.

Das ist ja schon recht aufwendig. Für mich stellt sich jetzt die Frage ob dies hier an dieser Stelle überhaupt nötig ist. Klar ist das für mobile Spiele eine gute Sache und für Projekte mit vielen Ressourcen im allgemein kann das einen Performance Vorteil bringen. Den Arbeitsaufwand würde ich an dieser Stelle aber erst betreiben wenn es wirklich nötig ist. Bei einer nicht all zu großen Anzahl an Ressourcen reicht es ja aus diese einmal zu laden und zu cachen. Ob man das jetzt ein mal am Anfang macht oder erst dann wenn sie gebraucht werden ist da ja erst mal zweitrangig. Unter Umständen kann man das ganze noch auf die Spielzustände zuschneiden. Soll heißen, in jedem Spielzustand sind nur die Ressourcen vorhanden die auch dort benötigt werden. Für die meisten simpleren Zwecke ist das völlig ausreichend. Das hängt am Ende aber natürlich von der Masse der Ressourcen ab.
Um da ein wenig flexibler zu sein kann man sich vielleicht erst mal einen Pseudomanager schreiben der ein passendes Interface anbietet. Am Anfang hält man alles simpel und sobald man merkt dass man an dieser Stelle optimieren muss fängt man an das System dahinter anzupassen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

02.06.2017, 10:59

Ich wollte damit halt verdeutlichen, dass der hier vom TE vorgestellte 'Manager' kein Manager ist, weil er nichts managed und von außen komplett dirigiert wird und das vermutlich sogar durch die falschen Mittel und Wege. Ich habe damit nirgendwo gesagt oder sagen wollen, dass der Umfang seines Managers dem meiner entsprechen muss (ist traurig, das ich das jetzt explizit nochmal verdeutlichen muss).
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]

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

7

02.06.2017, 11:24

Ich habe damit nirgendwo gesagt oder sagen wollen, dass der Umfang seines Managers dem meiner entsprechen muss (ist traurig, das ich das jetzt explizit nochmal verdeutlichen muss).

Das wollte ich damit auch nicht sagen. Aber bevor er dein Konzept einfach übernimmt soll er sich halt Gedanken machen was er denn am Ende wirklich braucht. Da hast du mich einfach falsch verstanden.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige