Bestehende Klassen verändern, ohne die sourcen zu verändern?



  • Wie sieht die genaue Deklaration der Objekt Klasse aus?



  • problem wäre dann jedoch, wenn die engine einen pointer oder eine referenz auf ein engineobjekt zurück gibt.
    dann brauchst du noch einen copy construktor

    class MyEngineObjekt : public EngineObjekt
      {
        public:
            MyEngineObjekt(){}
            MyEngineObjekt(const EngineObjekt & eo) : EngineObjekt(eo) {}
            MyEngineObjekt(const EngineObjekt *peo) : EngineObjekt(*peo) {}
           ~MyEngineObjekt(){ //EngineObjekt::~EngineObjekt() zur not }
         // void do_foo() ist schon da weil die Klasse das geerbt hat von der anderen
         void do_foobar(){} // das ist deine eigene Erweiterung 
      };
    

    dann brauch die EngineObjekt aber auch nen eigenen kopyconstructor, sonst wirds schwierig



  • Das ist die definition:

    class NEOENGINE_API SceneNode : public virtual UpdateEntity, public virtual RenderEntity, public HierarchyNode<SceneNode>
    {
    	public:
    
    		DefineVisitable();
    
    	protected:
    
    		/*! Scene entity contained in this node */
    		SceneEntity                                  *m_pkEntity;
    
    		/*! Bounding volume for subtree rooted at this node */
    		BoundingVolume                               *m_pkBoundingVolume;
    
    		/*! Flag indicating bounding volume needs remerging */
    		bool                                          m_bNeedVolumeUpdate;
    
    		/*! Internal flag for indicating we should ignore requests for volume update */
    		bool                                          m_bIgnoreVolumeUpdate;
    
    		/*! Update callbacks */
    		std::vector< SceneNodeCallback* >             m_vpkCallbacks;
    
    		/**
    		* Updates world SRT data cache
    		* \return                                     true if world cache data was updated, false if not
    		*/
    		virtual bool                                  UpdateWorld();
    
    		/**
    		* Updates bounding volume for subtree rooted at this node
    		* \return                                     true if any bounding volume was updated, false if not
    		*/
    		virtual bool                                  UpdateVolume();
    
    		/**
    		* Used to get this as correct type
    		* \return                                     This node
    		*/
    		inline virtual SceneNode                     *Get();
    
    	public:
    
    		/*! Room we are attached to */
    		Room                                         *m_pkRoom;
    
    		/*! Flag indicating parent node should ignore this node when calculating bounding volume */
    		bool                                          m_bIgnoreVolume;
    
    		/**
    		* Create named, attached node. Will initially have same world position as parent
    		* (i.e zero relative rotation and translation, no scaling)
    		* \param rstrName                             Node name
    		* \param pkParent                             Parent node
    		* \param eVolume                              Desired bounding volume type (default axis-aligned box)
    		*/
    		                                              SceneNode( const HashString &rstrName = "", SceneNode *pkParent = 0, BoundingVolume::BOUNDINGVOLUMETYPE eVolume = BoundingVolume::BV_AABB );
    
    		/**
    		* Create node from reference object
    		* \param rkNode                               Reference node object to copy
    		* \param bDuplicateChildren                   Duplicate child nodes if true
    		*/
    		                                              SceneNode( SceneNode &rkNode, bool bDuplicateChildren = true );
    
    		/**
    		* Deallocates child nodes and detaches from parent
    		*/
    		virtual                                      ~SceneNode();
    
    		/**
    		* Set world udpate flag. If flag is set, a call to any of the
    		* GetWorldScaling, GetWorldRotation, GetWorldTranslation will
    		* cause world cache data to be updated. Optionally recurses on
    		* all child nodes (default).
    		* \param bRecurse                             Recurse on children
    		*/
    		inline virtual void                           NotifyUpdate( bool bRecurse = true );
    
    		/**
    		* Set bounding volume udpate flag. If flag is set, a call to any of the
    		* GetBoundingVolume will cause volume to be remerged from child nodes and entity.
    		* Optionally recurses on parent (default).
    		* \param bRecurse                             Recurse on parent
    		*/
    		inline virtual void                           NotifyVolumeUpdate( bool bRecurse = true );
    
    		/**
    		* If node is active, update node and any child nodes. Also calls
    		* Update on the entity object, if any.
    		* \param fDeltaTime                           Delta time passed
    		*/
    		virtual void                                  Update( float fDeltaTime );
    
    		/**
    		* If node is active, render entity (if any) and any child nodes.
    		* \param pkFrustum                            Current view frustum
    		* \param bForce                               Force rendering even if rendered already this frame (default false)
    		* \return                                     true if we were rendered, false if not (already rendered and not forced)
    		*/
    		virtual bool                                  Render( Frustum *pkFrustum = 0, bool bForce = false );
    
    		/**
    		* Get bounding volume
    		* \return                                     Bounding volume for entire subtree rooted at this node
    		*/
    		inline BoundingVolume                        *GetBoundingVolume();
    
    		/**
    		* Set bounding volume object. Bounding volume transformation should be in world coordinate system
    		* \param pkVolume                             Bounding volume
    		*/
    		void                                          SetBoundingVolume( BoundingVolume *pkVolume );
    
    		/**
    		* Get scene entity attached to this node	
    		* \return                                     Scene entity object pointer
    		*/
    		inline SceneEntity                           *GetEntity();
    
    		/**
    		* Attach new scene entity to this node. If flag set, Will delete
    		* previous entity (if any)
    		* \param pkEntity                             New scene entity object
    		* \param bDeleteOld                           if true, delete old entity object
    		*/
    		void                                          SetEntity( SceneEntity *pkEntity, bool bDeleteOld = true );
    
    		/**
    		* Debug output. Print hierarchy of nodes
    		* \param uiLevel                              Current recursion level
    		*/
    		void                                          PrintHierarchy( unsigned int uiLevel = 0 );
    
    		/**
    		* Duplicate node, child nodes and optionally entities
    		* \return                                     New node that is exact duplicate of this node
    		*/
    		virtual SceneNode                            *Duplicate();
    
    		/**
    		* Also traverse the entitiy
    		* \param rkVisitor                            Visitor to apply to each node
    		*/
    		virtual void                                  TraverseNode( BaseVisitor &rkVisitor );
    
    		/**
    		* Intersection test with unknown object type
    		* \param pkObj                                Bounding volume object to test for intersection with
    		* \param pkContactSet                         Contact set object receiving collision contact data, 0 if not needed
    		* \return                                     true if volumes intersect, false if not
    		*/
    		virtual bool                                  Intersection( BoundingVolume *pkObj, ContactSet *pkContactSet = 0 );
    
    		/**
    		* Intersection test with ray
    		* \param rkRay                                Ray
    		* \param pkContactSet                         Contact set object receiving collision contact data, 0 if not needed
    		* \return                                     true if volumes intersect, false if not
    		*/
    		virtual bool                                  Intersection( const Ray &rkRay, ContactSet *pkContactSet = 0 );
    
    		/**
    		* Add callback
    		* \param pkCallback                           Callback object
    		*/
    		void                                          AddCallback( SceneNodeCallback *pkCallback );
    
    		/**
    		* Remove callback
    		* \param pkCallback                           Callback object
    		*/
    		void                                          RemoveCallback( SceneNodeCallback *pkCallback );
    

    eViLiSSiMo: das geht leider nicht. Die änderung muss direkt an dem objekt erfolgen, das auch die engine benutzt.

    Ich will folgendes machen:

    - Ein Frame wird gerendert
    - Ich hole mir von der engine den vektor mit allen objekten
    - Ich lese die vertikale geschwindigkeit des objektes aus und mache damit meine "gravitations-bewegungen" für das objekt
    - Ich schreibe die momentane vertikale geschwindigkeit wieder in das objekt.
    - Der nächste Frame wird gerendert
    - Das spiel beginnt wieder von vorne

    Während dieser ganzen zeit werden aber alle änderungen direkt an den objekten in der engine gemacht (mit zeigern). Sprich: Die Engine ist quasi meine "datenbank" wo ich mein neues attribut lese und schreibe.
    Die objekte "extern" zu verwalten ist quasi unmöglich, da ich jedes mal schauen muss, ob meine objekte, die ich im spiel habe auch noch in der engine vorhanden sind oder neue hinzu gekommen sind.



  • dann würde ich es anders machen;

    schreib einfach ne eigene Klasse und gib dieser Klasse eine Membervariable vom Typ SceneNode.
    desweiteren sollte die klassen folgende operatoren haben

    operator SceneNode &() { return m_scenenode; }
    operator SceneNode *() { return &m_scenenode; }
    

    ok so?



  • ich werde es mal versuchen, danke

    ist es auch möglich, dieser klasse einen vektor von scenenodes zu geben, welcher durch das fehlende attribut erweitert wird?



  • 1. Warum kannst du nicht einfach die betreffende Klasse ändern? Du hast doch die Engine in Source, oder?

    2. Die Engine scheint das Visitor Pattern zu implementieren. Vielleicht lässt sich was damit machen.

    3. Du hast keine Kontrolle über die Erzeugung der Objekte?

    4. Kannst nicht eine Map oder ähnliches halten, die jedem Objekt deine Daten zuordnet?



  • Um die sache noch einmal etwas genauer zu machen: hier die funktion um die es eigendlich geht:
    inline const std::vector< SceneNode* > &Room::GetChildren();

    Diese funktion gibt mir die objekte zurück. nur fehlt mir bei genau diesen objekten ein attribut, was ich brauch. (die vertikale geschwindigkeit)

    Ponto: Die engine steht unter der MPL, sprich, ich habe zwar den code, aber ich muss alle änderungen an der engine veröfentlichen, daher möchte ich so wenig wie möglich (am besten gar nichts) an dem code der engine verändern.



  • FloFri schrieb:

    Ponto: Die engine steht unter der MPL, sprich, ich habe zwar den code, aber ich muss alle änderungen an der engine veröfentlichen, daher möchte ich so wenig wie möglich (am besten gar nichts) an dem code der engine verändern.

    ja; aber nur wenn du dein programm auch public machst
    und genau dann, würde ich einfach die geänderte engine in ein paket packen und auf deiner projektseite zum download anbieten und gut ist



  • Wo du recht hast, hast du recht.

    Währe aber trotsdem interessant gewesen zu sehen, ob so etwas möglich ist 🙂



  • FloFri schrieb:

    ist es auch möglich, dieser klasse einen vektor von scenenodes zu geben, welcher durch das fehlende attribut erweitert wird?

    ja; zb ala

    void DeinObject::SetChildren(const std::vector< SceneNode* > & childs);
    //oder
    DeinObject & DeinObject::operator=(const std::vector< SceneNode* > & childs);
    


  • Noch eine letzte Frage (habe leider eben gemerkt, das das abändern des headers die engine abstürzen lässt 😕 ):

    wenn ich folgende klasse habe:

    class MyEngineObjekt : public EngineObjekt
    

    kann ich ja folgendes machen:

    EngineObjekt meinobj = new EngineObjekt;
    MyEngineObjekt meinobj2 = meinobj;
    

    Geht dann auch das hier:

    const std::vector< EngineObjekt > vmeinobj;
    const std::vector< MyEngineObjekt > vmeinobj2 = vmeinobj;
    

    ???



  • nur wenn
    MyEngineObjekt
    einen Kopykonstruktur hat, der ein Object vom Type EngineObjekt hat


Anmelden zum Antworten