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

CBenni::O

1x Contest-Sieger

  • »CBenni::O« ist der Autor dieses Themas

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

11

19.02.2010, 22:54

Ok, was auch immer...

Ist ja eine gute Lösung, aber ich bin offen für neue Vorgehensweisen (Danke Nexus ;) )

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

12

19.02.2010, 23:05

Zitat von »"CBenni::O"«

Nein... Ich probiers gleich mal aus...
Nein, das macht keinen Unterschied...

mfg CBenni::O

Wenn der Konstruktor der Basisklasse virtuell ist, weiß der Compiler, dass er bei jedem Aufruf (also wenn das Objekt gelöscht wird) in der vtable nachsehen muss, welchen Konstruktor er genau löschen muss und braucht deshalb nicht den Typ des Objektes.
Bei void* ist er wahrscheinlich chancenlos, da er nicht wissen kann, dass es einen virtuellen Destruktor gibt. Aber wenn du eine Basisklasse hast und einen Basisklassenzeigre löschst, wird der richtige Destruktor aufgerufen.
Lieber dumm fragen, als dumm bleiben!

unsigned long

Treue Seele

Beiträge: 140

Wohnort: Herzogenrath

Beruf: Fachinformatiker Fachrichtung Anwendungsentwicklung

  • Private Nachricht senden

13

19.02.2010, 23:09

Jonathan_Klein
Da ist ein gefährliches Teilwissen in deiner Aussage. Bitte ließ noch mal die jeweiligen Abschnitte über vtbl und virtual in More Effective C++ nach.

14

20.02.2010, 02:18

Zitat von »"CBenni::O"«

Ist ja eine gute Lösung, aber ich bin offen für neue Vorgehensweisen (Danke Nexus ;))
Freut mich, dass ich dich zu neuen Lösungen angespornt habe. :)

Hier würde ich mir zuerst einmal überlegen, wie du auf die Ressourcen zugreifen willst, und entsprechend eine oder mehrere Klassen schreiben. Denn einfach mal etwas drauf los programmieren und dann schauen, wie sich das ins Projekt integrieren lässt, scheint mir eher kontraproduktiv.

Möchtest du z.B. sowas? Dann lohnt sich wohl eher eine Klasse für jeden Ressourcentyp.

C-/C++-Quelltext

1
sf::Image* monsterImage = ImageManager["monster2"];

Oder ist dir so ein Interface lieber?

C-/C++-Quelltext

1
sf::Image* monsterImage = ResourceManager.AcquireImage("monster2");

Oder soll gar kein String als ID verwendet werden? Möchtest du auf Ressourcen anders zugreifen? Soll der Ressourcenmanager die IDs selbst erstellen und dir zuweisen? Und willst du eher mit shared_ptr als mit rohen Zeigern arbeiten, sodass der letzte automatisch freigibt, auch wenn die Ressource im Manager gar nicht mehr gespeichert sind? Oder soll der Besitz wie hier zentral geregelt sein?

Fragen über Fragen, da gibt es etliche Möglichkeiten. Da du SFML verwendest, könntest du auch einen Blick in die dort vorhandenen Ressourcenmanager werfen (auf dem Wiki gibt es drei Implementierungen, siehe hier). Wichtig finde ich, dass du nachher einfach Ressourcen verwalten kannst und dir der/die Manager so viel Arbeit wie möglich abnehmen. Überlege dir auch eine Fehlerbehandlung (wenn eine Ressource nicht initialisiert oder geladen werden kann), SFMLs LoadFromFile(), Create() etc. geben ja bool zurück. Entsprechend könntest du bei Fehlschlag Nullzeiger zurückgeben, oder Exceptions werfen, oder oder...

idontknow

unregistriert

15

20.02.2010, 10:59

Nur mal hier meine Lößung mit Templates die aber noch ungetestet /fertig ist.

Bei mir hab ich eigentlich 2 Template Klasse, einmal den Manager und einmal eine "Resource". Resource verwaltet dabei eben eine Resource und ist im Prinzip einzigartig. Dabei wird auch der Ref Counter und Release Mode gespeichert. Im großen und ganzen verwaltet Resource nur einen RefCounter und hat Rückgabewerte für ihre Attribute speichert aber auch einen Pointer auf die wirkliche Resource die man als Template parameter angibt.
Der Manager legt jetzt für jeden Dateipfad eine Resource an. Sprich ich habe eine Methode mit der ich eine Resource lade.
(Anm.: Manager ist eine Singleton Klasse, peinigt mich dafür ich finds ne tolle "Technik")

Das macht jetzt bisher wenig Sinn, aber die eigentlichen Resourcen die man verwendet bestehen im Kern aus einem Konstruktor, der eben erstmal Dateipfad erwartet. Anschließend wird im Konstruktor eine Get Methode von Manager aufgerufen, die nachschaut ob das Objekt exestiert, wenn ja wird der Ref Counter erhöht, da jetzt eine weiters Objekt abhängig von der Resource erstellt wurde, wenn nicht wird versucht die Resource zu laden und die Get Methode neu aufgerufen.

(Anm.: Oben habe ich bereits erwähnt, dass man Resourcen über eine sperate Methode laden soll, auch wenn die get Methode vom Manager selbiges bewirken sollte, hier kann aber kein Release Mode angegeben werden. Zusätzlich soll später das laden von Listen möglich sein oder das laden aus einer Datei(-liste). Daher dieser vllt unnötig wirkende kram mit Load/Get).

Analog dazu ruft der Destruktor eine Release Methode von Manager auf der den Ref Counter vermindert und je nach Release Mode das Objekt löscht/nicht löscht. Am Schluss wird automatisch aufgeräumt :D.

Als ID wird immer Dateiname/Pfad verwendet. Vermutlich werde ich vllt. dort nen gewisses Ordner Handeling einbauen, sodass man z.B. für bestimmte Sonderzeichen wie @ direkt den Data Ordner festlegt und der Dateiname entsprechend "@name.bla" heißt oder auch dass man vllt für Dateiendungen einen Pfad festsetzt, who knows. Erstmal muss ich den ganzen Kram testen bevor ich in erweitere sind nur ideen bisher.

Die Resource selber speichert eigentlich nur einen Pointer auf ein const Objekt.

Feedback wäre auch erwünscht sofern die Idee hinter meineme Manager aus dem Text ersichtlich wurde :P

edit: Aufruf wäre dann z.B. Image myImg("blabla.jpg") oder Image* MyImg = new Image("blabla.jpg");

edit2: Momentan ist der mir bekannte Nachteil, eben, dass das verändern einzelner Pixel auf einem Image auswirkungen auf alle Images hat, hab mich aber noch nivht genau damit beschäftigt und weiß noch nocht ob/inwieweit ich es überhaupt lößen werde.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

16

20.02.2010, 12:11

Also ich benutze so etwas ähnliches, wie David_pb vorgeschlagen hat.

Meine Frage ist eher für was brauchst deu den Resourcenmanager? - Also was soll der denn machen?

Ich habe so etwas eigentlich nur, damit ich Lost Device gescheit handlen kann. Ansonsten hätte ich so etwas wahrscheinlich gar nicht gebraucht. (zumindest nicht für alle Typen).

idontknow

unregistriert

17

20.02.2010, 12:15

Ich benutz ihn um Resourcen nicht doppelt zu laden also das ist die Grundidee. Außerdem bruach ich mich dan niocht ums aufräumen kümmern xD

CBenni::O

1x Contest-Sieger

  • »CBenni::O« ist der Autor dieses Themas

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

18

20.02.2010, 12:55

Zitat von »"idontknow"«

Ich benutz ihn um Resourcen nicht doppelt zu laden also das ist die Grundidee. Außerdem bruach ich mich dan niocht ums aufräumen kümmern xD


Genau das ist meine intention.

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

Faule Socke

Community-Fossil

Beiträge: 1 915

Wohnort: Schreibtischstuhl

  • Private Nachricht senden

19

20.02.2010, 15:32

Designtechnisch die schönste Lösung wäre es, eine Oberklasse für Resourcen zu machen. Alle anderen Resourcenklassen erben dann davon. Der Destructor der Parentklasse sollte virtual sein. Für dich hat das ganze den Vorteil, dass du auch allgemeine Operationen die bei jeder Resource gleich aussehen nur einmal zu implementieren brauchst.

Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Resource
{
private:
    std::string m_Name;

protected:
    virtual void BackgroundLoadingThread(std::istream &str) = 0;

public:
    Resource(const std::string &name);
    virtual ~Resource();

    // Erstellt einen Thread (BackgroundLoadingThread) der im Hintergrund die Daten läd.

    // Lässt sich auch gut mit boost.thread realisieren, falls du das einbauen willst

    virtual void StartLoading(std::istream &str);
};

class ImageResource : public Resource
{
private:
    void BackgroundLoadingThread(std::istream &str)
    {
        // hier entsprechend die bilddaten laden...

    }
};


Das ist nur ein grobes Beispiel, wie man es machen könnte, mit Sicherheit kein schlechter Ansatz.

Socke

CBenni::O

1x Contest-Sieger

  • »CBenni::O« ist der Autor dieses Themas

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

20

20.02.2010, 15:35

Danke!

So wollte ich es machen... Bin grad dabei :)

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

Werbeanzeige