Organisation von Spielobjekten
-
Sowas hier:
frameAnimation_.reset( new vis::BlendAnimation< vis::Linear, unsigned char >( std::bind( &Edit::SetFrameAlpha, this, std::placeholders::_1 ), 0.2f, 50, GetFrameAlpha(), 255 ) ); frameAnimation_->Start();
frameAnimation_ speichert ein "Handle" auf die Animation.
Und die Animation sagt folgendes: Rufe Edit::SetFrameAlpha mit dem linear interpolierten char-Parameter von GetFrameAlpha() bis 255 auf, mit einem Intervall von 50ms über die Zeit von 0.2 Sekunden.So schreibt man halt den interessanten Code, der aus der Zeit den aktuellen Wert berechnet nur einmal und kann so ziemlich alles animieren. Für einen 3D-Renderloop bräuchte man natürlich das Inkrement usw. nicht und könnte eine einfache Liste dieser "Animatoren" vorhalten, die in der Animationsphase aufgerufen werden.
Naja, vielleicht ist das auch alles Grütze, aber hat bei mir ganz gut gefunktionockelt.
-
Ethon schrieb:
Nach meinen ersten Eindrücken ein heftiger Komplexitäts- und Performanceoverhead für relativ wenig. Oder täusche ich mich da?
Jain. Es wird immer besser, je komplexer dein Spiel wird. So wie ein vector z.B. auch schneller als list ist, obwohl du dauernd in der Mitte Elemente einfügst/entfernst, wenn du nur 6 kleine Elemente in dem Ding hast. Aber es skaliert eben nicht, genau so wie Vererbung hier nicht skaliert. Und das gilt sowohl für Performance (irgendwann wird dann nämlich zwangsweise virtual inheritance benötigt), als auch für die Programmkomplexität, weil Vererbung nun mal sehr stark bindet.
Jetzt ist natürlich die Frage: Lohnt sich das denn auch für so ein 2D-Spiel? Ich würde sagen, performancemäßig sicher, selbst wenn du etwas verlieren solltest weil du nur 3 Objekte auf dem Bildschirm hast, merkt man das nicht. Was die Komplexität angeht: Kommt darauf an wie Komplex dein Spiel werden soll. Je mehr lustige Sachen du einbaust, desdo mehr wirst du Vererbung hassen.
-
Ethon schrieb:
Ernsthafte Frage: Tu ich das?
Naja, also ich hab das
Ethon schrieb:
Also die Hierachie ist bis jetzt: GameObject -> PhysicalObject.
Zuerst wollte ich einen neuen Objekttyp AnimatedObject einbauen lassen, andererseits möchte ich vlt auch mal animierte Objekte ohne physikalische Eigenschaften und es wäre ziemlich unsauber leere/dummy Physikeigenschaften verpassen zu müssen.so interpretiert, dass du eben entweder dein PhysicalObject von GameObject abgeleitet hast oder umgekehrt, wobei PhysicalObject logisches Verhalten kapselt und GameObject bzw. AnimatedObject graphische Repräsentation. Durch die Ableitungsbeziehung sagst du nun aber, dass entweder ein PhysicalObject auch ein GameObject ist, oder umgekehrt...
-
dot schrieb:
Ethon schrieb:
Ernsthafte Frage: Tu ich das?
Naja, also ich hab das
Ethon schrieb:
Also die Hierachie ist bis jetzt: GameObject -> PhysicalObject.
Zuerst wollte ich einen neuen Objekttyp AnimatedObject einbauen lassen, andererseits möchte ich vlt auch mal animierte Objekte ohne physikalische Eigenschaften und es wäre ziemlich unsauber leere/dummy Physikeigenschaften verpassen zu müssen.so interpretiert, dass du eben entweder dein PhysicalObject von GameObject abgeleitet hast oder umgekehrt, wobei PhysicalObject logisches Verhalten kapselt und GameObject bzw. AnimatedObject graphische Repräsentation. Durch die Ableitungsbeziehung sagst du nun aber, dass entweder ein PhysicalObject auch ein GameObject ist, oder umgekehrt...
Also, ich hab bis jetzt nie die Physik als logischen Part genommen (weil bis jetzt der Physikteil nur Synchronisierung zwischen realem Objekt und dem Objekt in der Physikengine war). Wohl ein Denkfehler.
Am besten haue ich mal das kommentierte Interface raus, wie es im Moment aussieht (habe den Animator in die GameObject Klasse gesteckt, imho ist es da nicht falsch), bitte sagen wenn ich hier Mist entwerfe.
//////////////////////////////////////////////////////////// /// Represents a visible object which lives inside a world. //////////////////////////////////////////////////////////// class GameObject { private: TexturePtr m_texture; sf::Sprite m_sprite; std::shared_ptr<Animator> m_animator; bool m_runAnimation; public: //////////////////////////////////////////////////////////// /// Constructs a visible game object. /// /// \param texture : The default texture of the object, can be null. /// \param animator : The animator to animate the object, can be null. //////////////////////////////////////////////////////////// GameObject(TexturePtr texture, std::shared_ptr<Animator> animator); //////////////////////////////////////////////////////////// /// Destructor. /// //////////////////////////////////////////////////////////// virtual ~GameObject(); //////////////////////////////////////////////////////////// /// Places the game object at a world position. /// /// \param x : The x coordinate. /// \param y : The y coordinate. //////////////////////////////////////////////////////////// virtual void placeAt(float x, float y); //////////////////////////////////////////////////////////// /// Returns the game object's world position in pixels. /// /// \return : The world position. //////////////////////////////////////////////////////////// virtual sf::Vector2f getPosition() const; //////////////////////////////////////////////////////////// /// Rotates the game object. /// /// \param angle : The world rotation angle in degrees. //////////////////////////////////////////////////////////// virtual void rotate(float angle); //////////////////////////////////////////////////////////// /// Returns the game object's world rotation in degrees. /// /// \return : The world rotation. //////////////////////////////////////////////////////////// virtual float getRotation() const; //////////////////////////////////////////////////////////// /// Starts an animation which is known by the animator. /// /// \param name : The name of the animation. //////////////////////////////////////////////////////////// virtual void startAnimation(std::string const& name); //////////////////////////////////////////////////////////// /// Stops any animation and restores the original appearance. /// //////////////////////////////////////////////////////////// virtual void endAnimation(); //////////////////////////////////////////////////////////// /// Stops any animation but only resets the animation without /// restoring original appearance. /// //////////////////////////////////////////////////////////// virtual void stopAnimation(); //////////////////////////////////////////////////////////// /// Draws the game object to a RenderTarget. /// /// \param target : The RenderTarget to draw to. //////////////////////////////////////////////////////////// virtual void drawTo(sf::RenderTarget& target); //////////////////////////////////////////////////////////// /// Updates the state of the game object. /// //////////////////////////////////////////////////////////// virtual void update(); };
PhysicalObject überschreibt nun in erster Linie Funktionen, die mit der Physikengine synchronisiert werden müssen, zb.
void Synthetic::PhysicalObject::placeAt(float x, float y) { // Move the game object. GameObject::placeAt(x, y); // Inform the body. b2Vec2 newPosition(x / ::getPixelPerMeter(), y / ::getPixelPerMeter()); m_body->SetTransform(newPosition, m_body->GetAngle()); }
cooky451 schrieb:
Jain. Es wird immer besser, je komplexer dein Spiel wird. So wie ein vector z.B. auch schneller als list ist, obwohl du dauernd in der Mitte Elemente einfügst/entfernst, wenn du nur 6 kleine Elemente in dem Ding hast. Aber es skaliert eben nicht, genau so wie Vererbung hier nicht skaliert. Und das gilt sowohl für Performance (irgendwann wird dann nämlich zwangsweise virtual inheritance benötigt), als auch für die Programmkomplexität, weil Vererbung nun mal sehr stark bindet.
Jetzt ist natürlich die Frage: Lohnt sich das denn auch für so ein 2D-Spiel? Ich würde sagen, performancemäßig sicher, selbst wenn du etwas verlieren solltest weil du nur 3 Objekte auf dem Bildschirm hast, merkt man das nicht. Was die Komplexität angeht: Kommt darauf an wie Komplex dein Spiel werden soll. Je mehr lustige Sachen du einbaust, desdo mehr wirst du Vererbung hassen.Wird irgendwo ein konkreter Ansatz erklärt? Die Grundidee dass ein Entity erstmal komplett leer ist und echt jedes Feature (selbst Position etc) erstmal hineingestopft werden muss finde ich doof.
Decimad schrieb:
Sowas hier:
frameAnimation_.reset( new vis::BlendAnimation< vis::Linear, unsigned char >( std::bind( &Edit::SetFrameAlpha, this, std::placeholders::_1 ), 0.2f, 50, GetFrameAlpha(), 255 ) ); frameAnimation_->Start();
frameAnimation_ speichert ein "Handle" auf die Animation.
Und die Animation sagt folgendes: Rufe Edit::SetFrameAlpha mit dem linear interpolierten char-Parameter von GetFrameAlpha() bis 255 auf, mit einem Intervall von 50ms über die Zeit von 0.2 Sekunden.So schreibt man halt den interessanten Code, der aus der Zeit den aktuellen Wert berechnet nur einmal und kann so ziemlich alles animieren. Für einen 3D-Renderloop bräuchte man natürlich das Inkrement usw. nicht und könnte eine einfache Liste dieser "Animatoren" vorhalten, die in der Animationsphase aufgerufen werden.
Naja, vielleicht ist das auch alles Grütze, aber hat bei mir ganz gut gefunktionockelt.
OKay, danke, jetzt versteh ichs.
Ich lass es mir mal durch den Kopf gehen, aber da ich das Spiel mit anderen basteln möchte die nicht ganz so fit in C++ sind versuche ich das Interface simpel zu halten, dh. ich muss abwägen ob der Komplexitätsoverhead die bessere Dynamik wert ist.
-
Vielleicht wirfst Du einmal einen Blick in den Source von Doom3. JC ist auch nicht so der Anhänger modernster C++-Techniken und das vielleicht auch mit gutem Grund. Das trifft bestimmt Deinen Geschmack.
-
Ethon schrieb:
Wird irgendwo ein konkreter Ansatz erklärt?
Ansätze? Ja. Konkretere Implementierungen? Selten. Und ich selbst kenne leider auch noch keine bei der ich denken würde "ja, das ist es". Besser als Vererbung sind aber wohl die meisten. Zudem gibt es sehr, sehr viele Interpretationen der Grundidee.
Ethon schrieb:
Die Grundidee dass ein Entity erstmal komplett leer ist und echt jedes Feature (selbst Position etc) erstmal hineingestopft werden muss finde ich doof.
Das ist aber eben gerade das Tolle an der Idee. Wir sehen doch sogar bei dir schon, dass du anfängst ein Gottobjekt zu bauen. Ist jedes Objekt sichtbar? Nein. Hat jedes sichtbare Objekt eine Textur? Nein. Ein Sprite? Nein. Ist jedes Objekt mit Textur animiert? Nein. Und das wird, wie gesagt, immer schlimmer je mehr Features deine Objekte bekommen. Abgesehen davon: Für jedes Objekt die Textur im Speicher halten? Keine gute Idee würde ich sagen.
-
cooky451 schrieb:
Ist jedes Objekt sichtbar? Nein. Hat jedes sichtbare Objekt eine Textur? Nein. Ein Sprite? Nein. Ist jedes Objekt mit Textur animiert? Nein. Und das wird, wie gesagt, immer schlimmer je mehr Features deine Objekte bekommen. Abgesehen davon: Für jedes Objekt die Textur im Speicher halten? Keine gute Idee würde ich sagen.
Zusätzlich: Wieso sollte PhysicalObject von GameObject erben und wieso genau std::shared_ptr?
-
Das einzig schlimme an der hier gerade auftretenden Situation ist, dass man sich an solcherlei Fragen so lange aufreiben kann (auf verschiedensten Erfahrungsleveln), dass man in dieser Zeit auch mit Gottesobjekten etwas schönes hinbekommt, Erfahrung sammelt, die Anforderungen besser kennen lernt, usw. Man kann das Gefühl einfach nicht kurz in einem Forenpost zusammenfassen, das entsteht, wenn man eine kleine Änderung hier oder dort im Verhalten haben will und auf einmal das ganze Kartenhaus zusammenbricht oder das Projekt anfängt, auf der Stelle zu treten. Und wenn es für alles eine Patentlösung gäbe, die man aus dem Lehrbuch mal fix nach zehn Regeln runterfummelt, dann wären entsprechende Produke in der Lizenz auch nicht so teuer.
-
Und eine zweite Anmerkung:
Wenn jemand mit dem Ziel, ein bestimmtes Spiel umzusetzen, anfängt eine flexible Engine zu programmieren, so wird das Spiel in 99% der Fälle nie auch nur ansatzweise fertig. Das kann schlecht sein oder auch nicht, hauptsache es macht Spaß und man bereut die Zeit anschließend nicht.
-
Und noch eine dritte Bemerkung:
Wenn man irgendwann feststellt, dass man so ziemlich überall die Basisklassenfertigkeit überschreibt oder die Basisklassenfertigkeit mehrfach flexibilisiert, dann ist das ein gutes Indiz dafür, dass die Fertigkeit nicht in die Basisklasse gehörte.@dot: Ich lese im OP einen Pfeil von GameObject in Richtung PhysicalObject... Bedeutet das nach UML nicht, dass GameObject von PhysicalObject ableitet?
-
keine angst vor der editierfunktion
-
Decimad schrieb:
@dot: Ich lese im OP einen Pfeil von GameObject in Richtung PhysicalObject... Bedeutet das nach UML nicht, dass GameObject von PhysicalObject ableitet?
Ja, in UML, ich seh dort aber kein UML.
Aber gut, der Gedanke ist mir auch gekommen, für die Argumentation ist es aber irrelevant in welche Richtung die Ableitungsbeziehung genau läuft und die Variante schien mir rein intuitiv naheliegender.
-
dot schrieb:
cooky451 schrieb:
Ist jedes Objekt sichtbar? Nein. Hat jedes sichtbare Objekt eine Textur? Nein. Ein Sprite? Nein. Ist jedes Objekt mit Textur animiert? Nein. Und das wird, wie gesagt, immer schlimmer je mehr Features deine Objekte bekommen. Abgesehen davon: Für jedes Objekt die Textur im Speicher halten? Keine gute Idee würde ich sagen.
Zusätzlich: Wieso sollte PhysicalObject von GameObject erben und wieso genau std::shared_ptr?
Abgesehen davon: Für jedes Objekt die Textur im Speicher halten? Keine gute Idee würde ich sagen.
Ist doch ein klassischer Fall von shared Ownership. Eine Textur bzw ein Animator wird von mehreren Objekten geteilt. Ich verwalte zwar beide auch zentral, aber die Lebensdauer von Texturen/Animatoren an die Objekte zu binden erscheint mir als die richtige Lösung.
Und warum sollte PhysicalObject nicht von GameObject erben? Ein PhysicalObject ist immerhin auch ein GameObject, nur dass es parallel dazu noch in der "Physicsworld" lebt.
Decimad schrieb:
Das einzig schlimme an der hier gerade auftretenden Situation ist, dass man sich an solcherlei Fragen so lange aufreiben kann (auf verschiedensten Erfahrungsleveln), dass man in dieser Zeit auch mit Gottesobjekten etwas schönes hinbekommt, Erfahrung sammelt, die Anforderungen besser kennen lernt, usw. Man kann das Gefühl einfach nicht kurz in einem Forenpost zusammenfassen, das entsteht, wenn man eine kleine Änderung hier oder dort im Verhalten haben will und auf einmal das ganze Kartenhaus zusammenbricht oder das Projekt anfängt, auf der Stelle zu treten. Und wenn es für alles eine Patentlösung gäbe, die man aus dem Lehrbuch mal fix nach zehn Regeln runterfummelt, dann wären entsprechende Produke in der Lizenz auch nicht so teuer.
Ach, ich habe Zeit mir Gedanken zu machen weil der X-Server von Fedora17 nen Bug hat und der Patch noch nicht in den Repos ist ... und wegen dem Bug funktioniert SFML im Moment nicht. :p
Ansonsten gehe ich ja recht pragmatisch vor, nur das it den Objekten soll optimal umgesetzt sein.Vielleicht wirfst Du einmal einen Blick in den Source von Doom3. JC ist auch nicht so der Anhänger modernster C++-Techniken und das vielleicht auch mit gutem Grund. Das trifft bestimmt Deinen Geschmack.
Gute Idee, danke!
Das ist aber eben gerade das Tolle an der Idee. Wir sehen doch sogar bei dir schon, dass du anfängst ein Gottobjekt zu bauen. Ist jedes Objekt sichtbar? Nein. Hat jedes sichtbare Objekt eine Textur? Nein. Ein Sprite? Nein. Ist jedes Objekt mit Textur animiert?
Naja, meiner Meinung ist ein GameObject eigentlich immer etwas, das ich auch auf dem Bildschirm sehe. Von daher hat es immer Texture/Sprite. Den Animator dahin zu packen war eine Kurzschlussreaktion, aber ich fand/finde es nicht falsch die Teile, die mit der Darstellung des Objektes zu tun haben, auch zusammen zu haben.
-
Ethon schrieb:
dot schrieb:
cooky451 schrieb:
Ist jedes Objekt sichtbar? Nein. Hat jedes sichtbare Objekt eine Textur? Nein. Ein Sprite? Nein. Ist jedes Objekt mit Textur animiert? Nein. Und das wird, wie gesagt, immer schlimmer je mehr Features deine Objekte bekommen. Abgesehen davon: Für jedes Objekt die Textur im Speicher halten? Keine gute Idee würde ich sagen.
Zusätzlich: Wieso sollte PhysicalObject von GameObject erben und wieso genau std::shared_ptr?
Abgesehen davon: Für jedes Objekt die Textur im Speicher halten? Keine gute Idee würde ich sagen.
Ist doch ein klassischer Fall von shared Ownership. Eine Textur bzw ein Animator wird von mehreren Objekten geteilt. Ich verwalte zwar beide auch zentral, aber die Lebensdauer von Texturen/Animatoren an die Objekte zu binden erscheint mir als die richtige Lösung.
Mehrere Objekte verwenden die selbe Textur bzw. den selben Animator. Das wäre unter Umständen vielleicht eine notwendige, aber ganz sicher keine hinreichende Bedingung für shared Ownership.
Überleg dir nochmal, ob dir das tatsächlich als die richtige Lösung, oder nicht doch nur als die einfache Lösung erscheint...
Hint: Wieso genau sollte bei der Zerstörung eines GameObject auch dessen Textur oder Animator zerstört werden?
Ethon schrieb:
Und warum sollte PhysicalObject nicht von GameObject erben? Ein PhysicalObject ist immerhin auch ein GameObject, nur dass es parallel dazu noch in der "Physicsworld" lebt.
Ist jedes PhysicalObject wirklich auch ein GameObject? Wo genau kommt jetzt das AnimatedObject ins Spiel? Dein initiales Problem zeigt doch, dass deine Konzepte GameObject, PhysicalObject und AnimatedObject irgendwie im Widerspruch zueinander stehen...
Ethon schrieb:
Das ist aber eben gerade das Tolle an der Idee. Wir sehen doch sogar bei dir schon, dass du anfängst ein Gottobjekt zu bauen. Ist jedes Objekt sichtbar? Nein. Hat jedes sichtbare Objekt eine Textur? Nein. Ein Sprite? Nein. Ist jedes Objekt mit Textur animiert?
Naja, meiner Meinung ist ein GameObject eigentlich immer etwas, das ich auch auf dem Bildschirm sehe. Von daher hat es immer Texture/Sprite. Den Animator dahin zu packen war eine Kurzschlussreaktion, aber ich fand/finde es nicht falsch die Teile, die mit der Darstellung des Objektes zu tun haben, auch zusammen zu haben.
eigentlich immer oder immer?
Stell dir einfach folgende Frage: Ist es für das Konzept eines GameObject wesentlich, dass jedes GameObject immer aus einer Texture bzw. eine Sprite besteht? Wenn die Antwort nich klipp und klar "Ja" lautet, dann sind Texture bzw. Sprite dort fehl am Platz.
-
@Ethon Und schon bist du bei PhysicalObject und AnimatedObject, aber der gute Tom kann leider beides und tadaa, virtual inheritance.
-
dot schrieb:
Mehrere Objekte verwenden die selbe Textur bzw. den selben Animator. Das wäre unter Umständen vielleicht eine notwendige, aber ganz sicher keine hinreichende Bedingung für shared Ownership.
Überleg dir nochmal, ob dir das tatsächlich als die richtige Lösung, oder nicht doch nur als die einfache Lösung erscheint...
Hint: Wieso genau sollte bei der Zerstörung eines GameObject auch dessen Textur oder Animator zerstört werden?
Naja, da ich mir offen halten will etwas Programmiertes auch mal auf einem Smartphone oä. mit wenig RAM laufen zu lassen, versuche ich im vorhinein die Möglichkeit offen zu halten oft ungenutzte Resourcen freizugeben.
So wie es jetzt ist kann ich meinen ganzen Texturencache bzw einzelne Texturenklassen mit einer einzigen Zeile Code freigeben ohne dass es irgendwo dangling ponter gibt. Würde ich normale Referenzen auf das geladene Texturobjekt haben, müsste ich beim Löschen jeder Textur aus dem Cache eine Garantie geben, dass sie nirgendwo sonst verwendet wird. Und da nicht nur die Spielobjekte die Texturen verwenden ist das unglaublich umständlich und gewinnen würde ich dabei auch nichts. (shared_ptr ist in diesem Kontext ja praktisch kostenlos)Deswegen gefällt mir die Logik: Ist eine Textur nicht mehr im Cache und wird sie von keinem Objekt mehr verwendet => Ab in die Tonne damit.
....
Ansonsten bin ich durch diesen Blogpost ( http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ ) mittlerweile auch der Meinung dass soetwas eine recht sinnvolle Sache ist. Vor allem gefällt mir die Idee dass so der Renderer sehr leicht austauschbar ist.
Jetzt heißt es brainstormen wie ich das einigermaßen performant und mit möglichst wenig dynamisch angefordertem Speicher hinbekomme.
-
Ethon schrieb:
Naja, da ich mir offen halten will etwas Programmiertes auch mal auf einem Smartphone oä. mit wenig RAM laufen zu lassen, versuche ich im vorhinein die Möglichkeit offen zu halten oft ungenutzte Resourcen freizugeben.
Wenn du das willst, machst du dir mit std::shard_ptr das Leben schwer, denn:
Ethon schrieb:
So wie es jetzt ist kann ich meinen ganzen Texturencache bzw einzelne Texturenklassen mit einer einzigen Zeile Code freigeben [...]
Nope, kannst du nicht. Deine Ressource wird erst freigegeben, wenn der letzte shared_ptr darauf zerstört wird...
Ethon schrieb:
[...] ohne dass es irgendwo dangling ponter gibt.
Wie genau funktioniert das? Wenn du deinen "Texturenchace" "freigibst", sind die Texturen immer noch alle da, du weißt lediglich nicht mehr wirklich, dass sie da sind. Wenn dann einer kommt und eine Textur, die eigentlich noch da wäre, anfordert, dann lädst du sie gleich noch ein zweites Mal. Man könnte drüber Diskutieren, ob da nicht gerade eine völlig neue Art zu Leaken entdeckt hast, shared_ptr macht's möglich...
Ethon schrieb:
Würde ich normale Referenzen auf das geladene Texturobjekt haben, müsste ich beim Löschen jeder Textur aus dem Cache eine Garantie geben, dass sie nirgendwo sonst verwendet wird.
Jap, oder mit anderen Worten: Du müsstest dafür sorgen, dass Texturen erst aus dem Cache verschwinden, wenn sie nirgendwo mehr verwendet werden. Mit shared_ptr dagegen, müsstest du genau das Gleiche tun...
Shared Ownership führt schnell zu einem extrem komplizierten, undurchsichtigen, unvorhersehbaren und nur schwer beherrschbaren System...
-
Okay, danke, ich verstehe. Ich denke ein Smartpointer, der mir verrät wie viele Referenzen existieren, wäre die Lösung? Dann könnte ich im Cache auf das Löschen verzichten falls der größer 1 ist ...
Hab mal ein bischen Grundlegend herumgespielt, hier mal heruntergebrochen wie ich das mit dem Entitysystem umsetzen würde ... okay, oder hab ich da etwas falsch verstanden?
struct Component { inline virtual std::type_index id() { return std::type_index(typeid(*this)); } }; struct Position : public Component { static std::type_index const ID = std::type_index(typeid(Position)); float x, y; }; Component* findComponent(std::type_index const& component) { auto result = components.find(component); if(result == components.end()) return nullptr; return result->second; } void MovementSystem::move() { for(Entity : entities) { Component* component = findComponentInEntity(entity, Position.ID); if(component) doStuff(static_cast<Position*>(component)); } }
-
Ich habe das bei mir so geregelt, dass der shared_ptr einen deleter bekommt, der die Ressource beim Manager austrägt und der Manager hat nur einen weak_ptr auf die Ressource. So bestimmen die Clients über die Lebenszeit, aber wenn die Ressource "lebt", kann der Manager drankommen.