[Orxonox-commit 1166] r5887 - in code/branches/core5/src: libraries/core modules/objects/eventsystem

landauf at orxonox.net landauf at orxonox.net
Tue Oct 6 04:51:08 CEST 2009


Author: landauf
Date: 2009-10-06 04:51:08 +0200 (Tue, 06 Oct 2009)
New Revision: 5887

Modified:
   code/branches/core5/src/libraries/core/BaseObject.cc
   code/branches/core5/src/libraries/core/BaseObject.h
   code/branches/core5/src/modules/objects/eventsystem/EventDispatcher.cc
   code/branches/core5/src/modules/objects/eventsystem/EventTarget.cc
   code/branches/core5/src/modules/objects/eventsystem/EventTarget.h
Log:
Fixed an issue with the new event-system: even states which weren't declared are not loaded. While this is normally fine, it is a problem in EventDispatcher and EventTarget which have to pipe events to other objects and therefore have to support any state, not just the native ones.

Modified: code/branches/core5/src/libraries/core/BaseObject.cc
===================================================================
--- code/branches/core5/src/libraries/core/BaseObject.cc	2009-10-06 00:14:46 UTC (rev 5886)
+++ code/branches/core5/src/libraries/core/BaseObject.cc	2009-10-06 02:51:08 UTC (rev 5887)
@@ -244,7 +244,7 @@
     }
 
     /**
-        @brief Adds an object which listens to the events of this object.
+        @brief Adds an object which listens to the events of this object. The events are sent to the other objects mainstate.
     */
     void BaseObject::addEventListener(BaseObject* listener)
     {
@@ -267,6 +267,11 @@
         return 0;
     }
 
+    /**
+        @brief Adds a new event-state to the object. Event-states are states which can be changed by events.
+        @param name  The name of the event
+        @param state The object containing information about the event-state
+    */
     void BaseObject::addEventState(const std::string& name, EventState* state)
     {
         std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name);
@@ -279,6 +284,9 @@
         this->eventStates_[name] = state;
     }
 
+    /**
+        @brief Returns the event-state with the given name.
+    */
     EventState* BaseObject::getEventState(const std::string& name) const
     {
         std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name);
@@ -405,4 +413,49 @@
             this->XMLEventPort(xmlelement, XMLPort::NOP);
         }
     }
+    
+    /**
+        @brief Manually loads all event states, even if the class doesn't officially support them. This is needed by some classes like @ref EventDispatcher or @ref EventTarget.
+    */
+    void BaseObject::loadAllEventStates(Element& xmlelement, XMLPort::Mode mode, BaseObject* object, Identifier* identifier)
+    {
+        Element* events = xmlelement.FirstChildElement("events", false);
+        if (events)
+        {
+            // get the list of all states present
+            std::list<std::string> eventnames;
+            if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject)
+            {
+                for (ticpp::Iterator<ticpp::Element> child = events->FirstChildElement(false); child != child.end(); child++)
+                    eventnames.push_back(child->Value());
+            }
+            else if (mode == XMLPort::SaveObject)
+            {
+            }
+
+            // iterate through all states and get the event sources
+            for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it)
+            {
+                std::string statename = (*it);
+
+                // if the event state is already known, continue with the next state
+                orxonox::EventState* eventstate = object->getEventState(statename);
+                if (eventstate)
+                    continue;
+
+                XMLPortClassObjectContainer<BaseObject, BaseObject>* container = (XMLPortClassObjectContainer<BaseObject, BaseObject>*)(identifier->getXMLPortObjectContainer(statename));
+                if (!container)
+                {
+                    ExecutorMember<BaseObject>* setfunctor = createExecutor(createFunctor(&BaseObject::addEventSource), std::string( "BaseObject" ) + "::" + "addEventSource" + "(" + statename + ")");
+                    ExecutorMember<BaseObject>* getfunctor = createExecutor(createFunctor(&BaseObject::getEventSource), std::string( "BaseObject" ) + "::" + "getEventSource" + "(" + statename + ")");
+                    setfunctor->setDefaultValue(1, statename);
+                    getfunctor->setDefaultValue(1, statename);
+
+                    container = new XMLPortClassObjectContainer<BaseObject, BaseObject>(statename, identifier, setfunctor, getfunctor, false, true);
+                    identifier->addXMLPortObjectContainer(statename, container);
+                }
+                container->port(object, *events, mode);
+            }
+        }
+    }
 }

Modified: code/branches/core5/src/libraries/core/BaseObject.h
===================================================================
--- code/branches/core5/src/libraries/core/BaseObject.h	2009-10-06 00:14:46 UTC (rev 5886)
+++ code/branches/core5/src/libraries/core/BaseObject.h	2009-10-06 02:51:08 UTC (rev 5887)
@@ -171,15 +171,10 @@
             inline void setLoaderIndentation(const std::string& indentation) { this->loaderIndentation_ = indentation; }
             /** @brief Returns the indentation of the debug output in the Loader. @return The indentation */
             inline const std::string& getLoaderIndentation() const { return this->loaderIndentation_; }
+            
+            static void loadAllEventStates(Element& xmlelement, XMLPort::Mode mode, BaseObject* object, Identifier* identifier);
 
         protected:
-            /** @brief Adds an object which listens to the events of this object. */
-            inline void registerEventListener(BaseObject* object)
-                { this->eventListeners_.insert(object); }
-            /** @brief Removes an event listener from this object. */
-            inline void unregisterEventListener(BaseObject* object)
-                { this->eventListeners_.erase(object); }
-
             void addEventState(const std::string& name, EventState* container);
             EventState* getEventState(const std::string& name) const;
 
@@ -191,6 +186,13 @@
             Functor*    mainStateFunctor_;
 
         private:
+            /** @brief Adds an object which listens to the events of this object. */
+            inline void registerEventListener(BaseObject* object)
+                { this->eventListeners_.insert(object); }
+            /** @brief Removes an event listener from this object. */
+            inline void unregisterEventListener(BaseObject* object)
+                { this->eventListeners_.erase(object); }
+
             void setXMLName(const std::string& name);
             Template* getTemplate(unsigned int index) const;
             void registerEventStates();

Modified: code/branches/core5/src/modules/objects/eventsystem/EventDispatcher.cc
===================================================================
--- code/branches/core5/src/modules/objects/eventsystem/EventDispatcher.cc	2009-10-06 00:14:46 UTC (rev 5886)
+++ code/branches/core5/src/modules/objects/eventsystem/EventDispatcher.cc	2009-10-06 02:51:08 UTC (rev 5887)
@@ -53,6 +53,9 @@
         SUPER(EventDispatcher, XMLPort, xmlelement, mode);
 
         XMLPortObject(EventDispatcher, BaseObject, "targets", addTarget, getTarget, xmlelement, mode);
+
+        // since we need event sources mapped to any state, we have to parse XML by ourselves
+        this->loadAllEventStates(xmlelement, mode, this, Class(EventDispatcher));
     }
 
     void EventDispatcher::processEvent(Event& event)

Modified: code/branches/core5/src/modules/objects/eventsystem/EventTarget.cc
===================================================================
--- code/branches/core5/src/modules/objects/eventsystem/EventTarget.cc	2009-10-06 00:14:46 UTC (rev 5886)
+++ code/branches/core5/src/modules/objects/eventsystem/EventTarget.cc	2009-10-06 02:51:08 UTC (rev 5887)
@@ -28,6 +28,7 @@
 
 #include "EventTarget.h"
 #include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
 
 namespace orxonox
 {
@@ -42,6 +43,14 @@
     {
     }
     
+    void EventTarget::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EventTarget, XMLPort, xmlelement, mode);
+
+        // since we need event sources mapped to any state, we have to parse XML by ourselves
+        this->loadAllEventStates(xmlelement, mode, this, Class(EventTarget));
+    }
+
     void EventTarget::processEvent(Event& event)
     {
         this->fireEvent(event);

Modified: code/branches/core5/src/modules/objects/eventsystem/EventTarget.h
===================================================================
--- code/branches/core5/src/modules/objects/eventsystem/EventTarget.h	2009-10-06 00:14:46 UTC (rev 5886)
+++ code/branches/core5/src/modules/objects/eventsystem/EventTarget.h	2009-10-06 02:51:08 UTC (rev 5887)
@@ -42,6 +42,8 @@
             EventTarget(BaseObject* creator);
             virtual ~EventTarget();
             
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            
             virtual void processEvent(Event& event);
 
             virtual void changedName();




More information about the Orxonox-commit mailing list