[Orxonox-commit 1161] r5882 - in code/branches/core5: data/levels src/libraries/core src/modules/objects/eventsystem
landauf at orxonox.net
landauf at orxonox.net
Mon Oct 5 21:57:05 CEST 2009
Author: landauf
Date: 2009-10-05 21:57:05 +0200 (Mon, 05 Oct 2009)
New Revision: 5882
Added:
code/branches/core5/data/levels/events.oxw
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:
Again some changes in the event-system:
- Added "mainstate" event-state to BaseObject. It leads to the state which was defined with the mainstate attribute in XML.
- Support event-forwarding to the mainstate of event-listeners.
- The "targets" subsection of the EventDispatcher now supports all kinds of objects (not just EventTargets).
- EventTarget now works in all places of the XML-file, not just in the "targets" section of EventDispatcher.
Added a sample XML-file which explains several aspects of the event-system.
Added: code/branches/core5/data/levels/events.oxw
===================================================================
--- code/branches/core5/data/levels/events.oxw (rev 0)
+++ code/branches/core5/data/levels/events.oxw 2009-10-05 19:57:05 UTC (rev 5882)
@@ -0,0 +1,187 @@
+<?lua
+ include("hudtemplates3.oxo")
+ include("stats.oxo")
+ include("templates/spaceship_assff.oxt")
+ include("templates/spaceship_H2.oxt")
+?>
+
+<Level
+ name = "Event testing"
+ description = "A simple level to test the event-system (with comments)"
+>
+ <Scene
+ ambientlight = "0.5, 0.5, 0.5"
+ skybox = "Orxonox/skypanoramagen1"
+ >
+ <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+ <SpawnPoint position="0,-100,0" lookat="0,0,0" roll=180 spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+ <Billboard position=" 300,100, 0" material="Examples/Flare" colour="1.0, 0.0, 0.0" />
+ <Billboard position=" 200,100, 0" material="Examples/Flare" colour="1.0, 0.5, 0.0" />
+ <Billboard position=" 200,100,100" material="Examples/Flare" colour="1.0, 0.5, 0.0" />
+ <Billboard position=" 100,100, 0" material="Examples/Flare" colour="1.0, 1.0, 0.0" />
+ <Billboard position=" 0,100, 0" material="Examples/Flare" colour="0.0, 1.0, 0.0" />
+ <Billboard position="-100,100, 0" material="Examples/Flare" colour="0.0, 1.0, 1.0" />
+ <Billboard position="-100,100,100" material="Examples/Flare" colour="0.0, 1.0, 1.0" />
+ <Billboard position="-200,100, 0" material="Examples/Flare" colour="0.0, 0.0, 1.0" />
+ <Billboard position="-300,100, 0" material="Examples/Flare" colour="1.0, 0.0, 1.0" />
+
+
+ <!--
+ Note:
+ All following examples use only one subobject (in nested layouts). But of course you can add more
+ objects. They will all follow the same rules (depending on the example receive, send or pipe events).
+
+ Some examples address objects by name. Those methods always address ALL objects with this name, no
+ matter where they are in the XML-file (before or after the addressing object). Of course this also
+ works with all amounts of objects from zero to infinity. In the examples I used two objects each.
+ -->
+
+
+ <!-- red -->
+ <!--
+ Standard:
+ Direct event-connection between an event-listener (Billboard) and an event source (DistanceTrigger).
+ Every fired event of the source is mapped to the "visibility" state of the listener.
+
+ This is a 1:1 mapping between event-listener and event-source.
+ -->
+ <Billboard position="300,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0>
+ <events>
+ <visibility>
+ <DistanceTrigger position="300,100,0" distance=25 target="ControllableEntity" />
+ </visibility>
+ </events>
+ </Billboard>
+
+
+ <!-- orange -->
+ <!--
+ EventListener:
+ The EventListener object forwards all events from objects, whose names equal the "event" attribute
+ of the EventListener, to the enclosing object (Billboard).
+ In this case, both triggers have the name "trigger2" and thus both triggers send events to the Billboard.
+
+ The EventListener provides an 1:n mapping between one listener and multiple event-sources.
+ -->
+ <Billboard position="200,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0>
+ <events>
+ <visibility>
+ <EventListener event="trigger2" />
+ </visibility>
+ </events>
+ </Billboard>
+ <DistanceTrigger name="trigger2" position="200,100,0" distance=25 target="ControllableEntity" />
+ <DistanceTrigger name="trigger2" position="200,100,100" distance=25 target="ControllableEntity" />
+
+
+ <!-- yellow -->
+ <!--
+ EventTarget:
+ The EventTarget object forwards the events, received from objects whithin the "events" subsection,
+ to all objects whose names equal the "name" attribute.
+ In this case, the EventTarget forwards the event from the DistanceTrigger to all listeners with
+ name "bb3".
+
+ The EventTarget provides an n:1 mapping between several listeners and one event-source.
+ -->
+ <Billboard name="bb3" position="100,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+ <Billboard name="bb3" position="100,150,100" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+ <EventTarget name="bb3">
+ <events>
+ <visibility>
+ <DistanceTrigger position="100,100,0" distance=25 target="ControllableEntity" />
+ </visibility>
+ </events>
+ </EventTarget>
+
+
+ <!-- green -->
+ <!--
+ EventDispatcher:
+ The EventDispatcher catches events from objects in its "events" subsection. Those events are forwared
+ to all objects in the "targets" subsection. The EventDispatcher resembles the EventTarget, but
+ doesn't address objects with the "name" attribute. It rather places them directly inside the "targets"
+ subsection.
+ In this case, the EventDispatcher receives events from the DistanceTrigger and forwards those events
+ to the Billboard object.
+
+ The EventDispatcher provides an n:1 mapping between several targets (listeners) and one event source.
+ -->
+ <EventDispatcher>
+ <targets>
+ <Billboard position="0,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+ </targets>
+ <events>
+ <visibility>
+ <DistanceTrigger position="0,100,0" distance=25 target="ControllableEntity" />
+ </visibility>
+ </events>
+ </EventDispatcher>
+
+
+ <!-- turquoise -->
+ <!--
+ Combination:
+ By combinding the above three classes, namely EventDispatcher, EventTarget and EventListener, you can
+ extract the event logic completely from the actual objects (Billboards and DistanceTriggers).
+ In this case, both triggers (whith names "trigger5") send events to both Billboards (with names "bb5").
+
+ This combination allows an n:n mapping between event-listeners and event-sources.
+ -->
+ <Billboard name="bb5" position="-100,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+ <Billboard name="bb5" position="-100,150,100" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+ <DistanceTrigger name="trigger5" position="-100,100,0" distance=25 target="ControllableEntity" />
+ <DistanceTrigger name="trigger5" position="-100,100,100" distance=25 target="ControllableEntity" />
+ <EventDispatcher>
+ <targets>
+ <EventTarget name="bb5" />
+ </targets>
+ <events>
+ <visibility>
+ <EventListener event="trigger5" />
+ </visibility>
+ </events>
+ </EventDispatcher>
+
+
+ <!-- blue -->
+ Mainstate:
+ Apart from the standard states (like activity and visibility), each object can have a mainstate.
+ You can define the mainstate with an xml-attribute: mainstate="state". "state" must be one of the
+ supported boolean states of the object. If the mainstate is set (by default that's not the case),
+ you can send events to the "mainstate" state. This allows you to hide the actually affected state
+ in the event-listener, while the event-source just sends events.
+ Note that this example is exactly like the standard case, but the event is sent to the main-state,
+ which in turn is set to "visibility".
+ <!--
+ -->
+ <Billboard position="-200,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 mainstate="visibility">
+ <events>
+ <mainstate>
+ <DistanceTrigger position="-200,100,0" distance=25 target="ControllableEntity" />
+ </mainstate>
+ </events>
+ </Billboard>
+
+
+ <!-- violet -->
+ <!--
+ Event forwarding:
+ As a consequence of the mainstate, events can also be sent without any explicit declaration of
+ the targets state. This allows us to forward events from an event-source directly to a bunch of
+ event-listeners. The events are automatically piped into the mainstate. Therefore the listeners
+ have to declare their main-state.
+ In this example, the DistanceTrigger forwards the events to the Billboards main-state (visibility).
+ This does the same like the example above, but instead of piping events backwards from the source
+ into the mainstate of the listener, we're forwarding the event implicitly to the mainstate.
+ -->
+ <DistanceTrigger position="-300,100,0" distance=25 target="ControllableEntity">
+ <eventlisteners>
+ <Billboard position="-300,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 mainstate="visibility" />
+ </eventlisteners>
+ </DistanceTrigger>
+
+ </Scene>
+</Level>
Modified: code/branches/core5/src/libraries/core/BaseObject.cc
===================================================================
--- code/branches/core5/src/libraries/core/BaseObject.cc 2009-10-05 16:28:21 UTC (rev 5881)
+++ code/branches/core5/src/libraries/core/BaseObject.cc 2009-10-05 19:57:05 UTC (rev 5882)
@@ -117,12 +117,13 @@
XMLPortParam(BaseObject, "mainstate", setMainStateName, getMainStateName, xmlelement, mode);
XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*);
+ XMLPortObject(BaseObject, BaseObject, "eventlisteners", addEventListener, getEventListener, xmlelement, mode);
Element* events = 0;
if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject)
events = xmlelement.FirstChildElement("events", false);
else if (mode == XMLPort::SaveObject)
- ;
+ {}
if (events)
this->XMLEventPort(*events, mode);
}
@@ -136,6 +137,7 @@
{
XMLPortEventState(BaseObject, BaseObject, "activity", setActive, xmlelement, mode);
XMLPortEventState(BaseObject, BaseObject, "visibility", setVisible, xmlelement, mode);
+ XMLPortEventState(BaseObject, BaseObject, "mainstate", setMainState, xmlelement, mode);
this->bRegisteredEventStates_ = true;
}
@@ -241,6 +243,30 @@
return 0;
}
+ /**
+ @brief Adds an object which listens to the events of this object.
+ */
+ void BaseObject::addEventListener(BaseObject* listener)
+ {
+ this->eventListenersXML_.insert(listener);
+ listener->addEventSource(this, "mainstate");
+ }
+
+ /**
+ @brief Returns an event listener with a given index.
+ */
+ BaseObject* BaseObject::getEventListener(unsigned int index) const
+ {
+ unsigned int i = 0;
+ for (std::set<BaseObject*>::const_iterator it = this->eventListenersXML_.begin(); it != this->eventListenersXML_.end(); ++it)
+ {
+ if (i == index)
+ return *it;
+ ++i;
+ }
+ return 0;
+ }
+
void BaseObject::addEventState(const std::string& name, EventState* state)
{
std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name);
Modified: code/branches/core5/src/libraries/core/BaseObject.h
===================================================================
--- code/branches/core5/src/libraries/core/BaseObject.h 2009-10-05 16:28:21 UTC (rev 5881)
+++ code/branches/core5/src/libraries/core/BaseObject.h 2009-10-05 19:57:05 UTC (rev 5882)
@@ -156,6 +156,9 @@
void addEventSource(BaseObject* source, const std::string& state);
void removeEventSource(BaseObject* source);
BaseObject* getEventSource(unsigned int index, const std::string& state) const;
+
+ void addEventListener(BaseObject* listener);
+ BaseObject* getEventListener(unsigned int index) const;
void fireEvent();
void fireEvent(bool activate);
@@ -207,6 +210,7 @@
std::map<BaseObject*, std::string> eventSources_; //!< List of objects which send events to this object, mapped to the state which they affect
std::set<BaseObject*> eventListeners_; //!< List of objects which listen to the events of this object
+ std::set<BaseObject*> eventListenersXML_; //!< List of objects which listen to the events of this object through the "eventlisteners" subsection in XML
std::map<std::string, EventState*> eventStates_; //!< Maps the name of the event states to their helper objects
bool bRegisteredEventStates_; //!< Becomes true after the object registered its event states (with XMLEventPort)
};
Modified: code/branches/core5/src/modules/objects/eventsystem/EventDispatcher.cc
===================================================================
--- code/branches/core5/src/modules/objects/eventsystem/EventDispatcher.cc 2009-10-05 16:28:21 UTC (rev 5881)
+++ code/branches/core5/src/modules/objects/eventsystem/EventDispatcher.cc 2009-10-05 19:57:05 UTC (rev 5882)
@@ -53,13 +53,13 @@
{
SUPER(EventDispatcher, XMLPort, xmlelement, mode);
- XMLPortObject(EventDispatcher, EventTarget, "targets", addTarget, getTarget, xmlelement, mode);
+ XMLPortObject(EventDispatcher, BaseObject, "targets", addTarget, getTarget, xmlelement, mode);
}
void EventDispatcher::processEvent(Event& event)
{
for (std::list<EventTarget*>::iterator it = this->targets_.begin(); it != this->targets_.end(); ++it)
- (*it)->fireEvent(event);
+ (*it)->processEvent(event);
}
void EventDispatcher::addTarget(EventTarget* target)
Modified: code/branches/core5/src/modules/objects/eventsystem/EventTarget.cc
===================================================================
--- code/branches/core5/src/modules/objects/eventsystem/EventTarget.cc 2009-10-05 16:28:21 UTC (rev 5881)
+++ code/branches/core5/src/modules/objects/eventsystem/EventTarget.cc 2009-10-05 19:57:05 UTC (rev 5882)
@@ -41,6 +41,11 @@
EventTarget::~EventTarget()
{
}
+
+ void EventTarget::processEvent(Event& event)
+ {
+ this->fireEvent(event);
+ }
void EventTarget::changedName()
{
Modified: code/branches/core5/src/modules/objects/eventsystem/EventTarget.h
===================================================================
--- code/branches/core5/src/modules/objects/eventsystem/EventTarget.h 2009-10-05 16:28:21 UTC (rev 5881)
+++ code/branches/core5/src/modules/objects/eventsystem/EventTarget.h 2009-10-05 19:57:05 UTC (rev 5882)
@@ -41,6 +41,8 @@
public:
EventTarget(BaseObject* creator);
virtual ~EventTarget();
+
+ virtual void processEvent(Event& event);
virtual void changedName();
More information about the Orxonox-commit
mailing list