[Orxonox-commit 1158] r5879 - in code/branches/core5/src: libraries/core modules/objects modules/objects/triggers modules/questsystem orxonox/graphics orxonox/overlays orxonox/worldentities
landauf at orxonox.net
landauf at orxonox.net
Mon Oct 5 17:02:26 CEST 2009
Author: landauf
Date: 2009-10-05 17:02:25 +0200 (Mon, 05 Oct 2009)
New Revision: 5879
Modified:
code/branches/core5/src/libraries/core/BaseObject.cc
code/branches/core5/src/libraries/core/BaseObject.h
code/branches/core5/src/libraries/core/CorePrereqs.h
code/branches/core5/src/libraries/core/Event.cc
code/branches/core5/src/libraries/core/Event.h
code/branches/core5/src/libraries/core/EventIncludes.h
code/branches/core5/src/libraries/core/Identifier.cc
code/branches/core5/src/libraries/core/Identifier.h
code/branches/core5/src/libraries/core/OrxonoxClass.h
code/branches/core5/src/libraries/core/Super.h
code/branches/core5/src/libraries/core/XMLPort.h
code/branches/core5/src/modules/objects/Attacher.cc
code/branches/core5/src/modules/objects/triggers/EventTrigger.cc
code/branches/core5/src/modules/objects/triggers/EventTrigger.h
code/branches/core5/src/modules/questsystem/QuestEffectBeacon.cc
code/branches/core5/src/modules/questsystem/QuestEffectBeacon.h
code/branches/core5/src/orxonox/graphics/ParticleSpawner.cc
code/branches/core5/src/orxonox/graphics/ParticleSpawner.h
code/branches/core5/src/orxonox/overlays/OrxonoxOverlay.h
code/branches/core5/src/orxonox/worldentities/WorldEntity.cc
Log:
More changes in the event-system: processEvent() is now locally executed in BaseObject. The event states (like activity, visibility, ...) are now defined in XMLEventPort, a function which closely resembles XMLPort. This function is used to define event states and to parse event sources from XML.
Connected the main-state directly with the event-system. After a state was declared as the "main state", the Functor from the corresponding EventState-object is used to call the function. This reduces the redundancy of declaring event-states and main-states separately. Of course only boolean event-states (like activity or visibility) can be used as main-state, while memoryless states (like spawn in ParticleSpawner) and individual states which need the triggering object (like execute in QuestEffectBeacon) won't work.
Modified: code/branches/core5/src/libraries/core/BaseObject.cc
===================================================================
--- code/branches/core5/src/libraries/core/BaseObject.cc 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/BaseObject.cc 2009-10-05 15:02:25 UTC (rev 5879)
@@ -62,11 +62,11 @@
this->bActive_ = true;
this->bVisible_ = true;
this->oldGametype_ = 0;
+ this->bRegisteredEventStates_ = false;
this->lastLoadedXMLElement_ = 0;
- this->functorSetMainState_ = 0;
- this->functorGetMainState_ = 0;
+ this->mainStateFunctor_ = 0;
this->setCreator(creator);
if (this->creator_)
@@ -99,13 +99,8 @@
for (std::set<BaseObject*>::const_iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); )
(*(it++))->removeEventSource(this);
- for (std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.begin(); it != this->eventContainers_.end(); ++it)
+ for (std::map<std::string, EventState*>::const_iterator it = this->eventStates_.begin(); it != this->eventStates_.end(); ++it)
delete it->second;
-
- if (this->functorSetMainState_)
- delete this->functorSetMainState_;
- if (this->functorGetMainState_)
- delete this->functorGetMainState_;
}
}
@@ -113,7 +108,6 @@
@brief XML loading and saving.
@param xmlelement The XML-element
@param loading Loading (true) or saving (false)
- @return The XML-element
*/
void BaseObject::XMLPort(Element& xmlelement, XMLPort::Mode mode)
{
@@ -123,42 +117,27 @@
XMLPortParam(BaseObject, "mainstate", setMainStateName, getMainStateName, xmlelement, mode);
XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*);
-
- Element* events = xmlelement.FirstChildElement("events", false);
-
+
+ Element* events = 0;
+ if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject)
+ events = xmlelement.FirstChildElement("events", false);
+ else if (mode == XMLPort::SaveObject)
+ ;
if (events)
- {
- std::list<std::string> eventnames;
+ this->XMLEventPort(*events, mode);
+ }
- 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)
- {
- for (std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->getIdentifier()->getXMLPortEventMapBegin(); it != this->getIdentifier()->getXMLPortEventMapEnd(); ++it)
- eventnames.push_back(it->first);
- }
-
- for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it)
- {
- std::string sectionname = (*it);
- ExecutorMember<BaseObject>* loadexecutor = createExecutor(createFunctor(&BaseObject::addEventSource), std::string( "BaseObject" ) + "::" + "addEventSource");
- ExecutorMember<BaseObject>* saveexecutor = createExecutor(createFunctor(&BaseObject::getEventSource), std::string( "BaseObject" ) + "::" + "getEventSource");
- loadexecutor->setDefaultValue(1, sectionname);
- saveexecutor->setDefaultValue(1, sectionname);
-
- XMLPortClassObjectContainer<BaseObject, BaseObject>* container = 0;
- container = static_cast<XMLPortClassObjectContainer<BaseObject, BaseObject>*>(this->getIdentifier()->getXMLPortEventContainer(sectionname));
- if (!container)
- {
- container = new XMLPortClassObjectContainer<BaseObject, BaseObject>(sectionname, this->getIdentifier(), loadexecutor, saveexecutor, false, true);
- this->getIdentifier()->addXMLPortEventContainer(sectionname, container);
- }
- container->port(this, *events, mode);
- }
- }
+ /**
+ @brief Defines the possible event states of this object and parses eventsources from an XML file.
+ @param xmlelement The XML-element
+ @param loading Loading (true) or saving (false)
+ */
+ void BaseObject::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+ {
+ XMLPortEventState(BaseObject, BaseObject, "activity", setActive, xmlelement, mode);
+ XMLPortEventState(BaseObject, BaseObject, "visibility", setVisible, xmlelement, mode);
+
+ this->bRegisteredEventStates_ = true;
}
/**
@@ -262,22 +241,22 @@
return 0;
}
- void BaseObject::addEventContainer(const std::string& sectionname, EventContainer* container)
+ void BaseObject::addEventState(const std::string& name, EventState* state)
{
- std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
- if (it != this->eventContainers_.end())
+ std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name);
+ if (it != this->eventStates_.end())
{
- COUT(2) << "Warning: Overwriting EventContainer in class " << this->getIdentifier()->getName() << "." << std::endl;
+ COUT(2) << "Warning: Overwriting EventState in class " << this->getIdentifier()->getName() << "." << std::endl;
delete (it->second);
}
- this->eventContainers_[sectionname] = container;
+ this->eventStates_[name] = state;
}
- EventContainer* BaseObject::getEventContainer(const std::string& sectionname) const
+ EventState* BaseObject::getEventState(const std::string& name) const
{
- std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
- if (it != this->eventContainers_.end())
+ std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name);
+ if (it != this->eventStates_.end())
return ((*it).second);
else
return 0;
@@ -301,7 +280,7 @@
}
/**
- @brief Fires an event which activates or deactivates a state with agiven originator (the object which sends the event).
+ @brief Fires an event which activates or deactivates a state with agiven originator (the object which triggered the event).
*/
void BaseObject::fireEvent(bool activate, BaseObject* originator)
{
@@ -309,7 +288,7 @@
for (std::set<BaseObject*>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
{
- event.sectionname_ = (*it)->eventSources_[this];
+ event.statename_ = (*it)->eventSources_[this];
(*it)->processEvent(event);
}
}
@@ -323,52 +302,63 @@
(*it)->processEvent(event);
}
+ /**
+ @brief Processing an event by calling the right main state.
+ @param event The event struct which contains the information about the event
+ */
void BaseObject::processEvent(Event& event)
{
- ORXONOX_SET_EVENT(BaseObject, "activity", setActive, event);
- ORXONOX_SET_EVENT(BaseObject, "visibility", setVisible, event);
+ this->registerEventStates();
+
+ std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(event.statename_);
+ if (it != this->eventStates_.end())
+ it->second->process(event, this);
+ else if (event.statename_ != "")
+ COUT(2) << "Warning: \"" << event.statename_ << "\" is not a valid state in object \"" << this->getName() << "\" of class " << this->getIdentifier()->getName() << "." << std::endl;
+ else
+ COUT(2) << "Warning: Event with invalid source sent to object \"" << this->getName() << "\" of class " << this->getIdentifier()->getName() << "." << std::endl;
}
- void BaseObject::setMainStateName(const std::string& name)
- {
- if (this->mainStateName_ != name)
- {
- this->mainStateName_ = name;
- if (this->functorSetMainState_)
- delete this->functorSetMainState_;
- if (this->functorGetMainState_)
- delete this->functorGetMainState_;
- this->changedMainState();
- if (!this->functorSetMainState_)
- COUT(2) << "Warning: \"" << name << "\" is not a valid MainState." << std::endl;
- }
- }
-
+ /**
+ @brief Sets the main state of the object to a given boolean value.
+
+ Note: The main state of an object can be set with the @ref setMainStateName function.
+ It's part of the eventsystem and used for event forwarding (when the target object can't specify a specific state,
+ the main state is used by default).
+ */
void BaseObject::setMainState(bool state)
{
- if (this->functorSetMainState_)
- (*this->functorSetMainState_)(state);
+ if (this->mainStateFunctor_)
+ (*this->mainStateFunctor_)(state);
else
COUT(2) << "Warning: No MainState defined in object \"" << this->getName() << "\" (" << this->getIdentifier()->getName() << ")" << std::endl;
}
- bool BaseObject::getMainState() const
+ /**
+ @brief This function gets called if the main state name of the object changes.
+ */
+ void BaseObject::changedMainStateName()
{
- if (this->functorGetMainState_)
- {
- (*this->functorGetMainState_)();
- return this->functorGetMainState_->getReturnvalue();
- }
+ this->registerEventStates();
+
+ this->mainStateFunctor_ = 0;
+
+ std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(this->mainStateName_);
+ if (it != this->eventStates_.end() && it->second->getFunctor() && it->second->getFunctor()->getParamCount() == 1)
+ this->mainStateFunctor_ = it->second->getFunctor();
else
+ COUT(2) << "Warning: \"" << this->mainStateName_ << "\" is not a valid MainState." << std::endl;
+ }
+
+ /**
+ @brief Calls XMLEventPort with an empty XML-element to register the event states if necessary.
+ */
+ void BaseObject::registerEventStates()
+ {
+ if (!this->bRegisteredEventStates_)
{
- COUT(2) << "Warning: No MainState defined in object \"" << this->getName() << "\" (" << this->getIdentifier()->getName() << ")" << std::endl;
- return false;
+ Element xmlelement;
+ this->XMLEventPort(xmlelement, XMLPort::NOP);
}
}
-
- void BaseObject::changedMainState()
- {
- SetMainState(BaseObject, "activity", setActive, isActive);
- SetMainState(BaseObject, "visibility", setVisible, isVisible);
- }
}
Modified: code/branches/core5/src/libraries/core/BaseObject.h
===================================================================
--- code/branches/core5/src/libraries/core/BaseObject.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/BaseObject.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -36,14 +36,6 @@
#ifndef _BaseObject_H__
#define _BaseObject_H__
-#define SetMainState(classname, statename, setfunction, getfunction) \
- if (this->getMainStateName() == statename) \
- { \
- this->functorSetMainState_ = createFunctor(&classname::setfunction, this); \
- this->functorGetMainState_ = createFunctor(&classname::getfunction, this); \
- }
-
-
#include "CorePrereqs.h"
#include <map>
@@ -68,6 +60,7 @@
BaseObject(BaseObject* creator);
virtual ~BaseObject();
virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+ virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
/** @brief Returns if the object was initialized (passed the object registration). @return True was the object is initialized */
inline bool isInitialized() const { return this->bInitialized_; }
@@ -110,11 +103,20 @@
virtual void changedVisibility() {}
void setMainState(bool state);
- bool getMainState() const;
- void setMainStateName(const std::string& name);
+ /** @brief Sets the name of the main state (used for event reactions). */
+ void setMainStateName(const std::string& name)
+ {
+ if (this->mainStateName_ != name)
+ {
+ this->mainStateName_ = name;
+ this->changedMainStateName();
+ }
+ }
+ /** @brief Returns the name of the main state. */
inline const std::string& getMainStateName() const { return this->mainStateName_; }
- virtual void changedMainState();
+ /** @brief This function gets called if the main state name of the object changes. */
+ virtual void changedMainStateName();
/** @brief Sets a pointer to the xml file that loaded this object. @param file The pointer to the XMLFile */
inline void setFile(const XMLFile* file) { this->file_ = file; }
@@ -175,20 +177,20 @@
inline void unregisterEventListener(BaseObject* object)
{ this->eventListeners_.erase(object); }
- void addEventContainer(const std::string& sectionname, EventContainer* container);
- EventContainer* getEventContainer(const std::string& sectionname) const;
+ void addEventState(const std::string& name, EventState* container);
+ EventState* getEventState(const std::string& name) const;
std::string name_; //!< The name of the object
std::string oldName_; //!< The old name of the object
mbool bActive_; //!< True = the object is active
mbool bVisible_; //!< True = the object is visible
std::string mainStateName_;
- Functor* functorSetMainState_;
- Functor* functorGetMainState_;
+ Functor* mainStateFunctor_;
private:
void setXMLName(const std::string& name);
Template* getTemplate(unsigned int index) const;
+ void registerEventStates();
bool bInitialized_; //!< True if the object was initialized (passed the object registration)
const XMLFile* file_; //!< The XMLFile that loaded this object
@@ -203,18 +205,18 @@
Gametype* oldGametype_;
std::set<Template*> templates_;
- 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::map<std::string, EventContainer*> eventContainers_;
+ 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::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)
};
SUPER_FUNCTION(0, BaseObject, XMLPort, false);
SUPER_FUNCTION(2, BaseObject, changedActivity, false);
SUPER_FUNCTION(3, BaseObject, changedVisibility, false);
- SUPER_FUNCTION(4, BaseObject, processEvent, false);
- SUPER_FUNCTION(6, BaseObject, changedMainState, false);
- SUPER_FUNCTION(9, BaseObject, changedName, false);
- SUPER_FUNCTION(10, BaseObject, changedGametype, false);
+ SUPER_FUNCTION(4, BaseObject, XMLEventPort, false);
+ SUPER_FUNCTION(8, BaseObject, changedName, false);
+ SUPER_FUNCTION(9, BaseObject, changedGametype, false);
}
#endif /* _BaseObject_H__ */
Modified: code/branches/core5/src/libraries/core/CorePrereqs.h
===================================================================
--- code/branches/core5/src/libraries/core/CorePrereqs.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/CorePrereqs.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -76,6 +76,7 @@
{
enum Mode
{
+ NOP,
LoadObject,
SaveObject,
ExpandObject
@@ -129,7 +130,7 @@
class DynLib;
class DynLibManager;
struct Event;
- class EventContainer;
+ class EventState;
class Executor;
template <class T>
class ExecutorMember;
Modified: code/branches/core5/src/libraries/core/Event.cc
===================================================================
--- code/branches/core5/src/libraries/core/Event.cc 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/Event.cc 2009-10-05 15:02:25 UTC (rev 5879)
@@ -29,50 +29,80 @@
#include "Event.h"
#include "BaseObject.h"
+#include "Identifier.h"
namespace orxonox
{
- EventContainer::~EventContainer()
+ /**
+ @brief Destructor: Deletes the functor of the event state.
+ */
+ EventState::~EventState()
{
- delete this->eventfunction_;
+ if (this->statefunction_)
+ delete this->statefunction_;
}
- void EventContainer::process(BaseObject* object, const Event& event)
+ /**
+ @brief Processes an event (calls the set-function if the necessary conditions are met).
+
+ @param event The fired event
+ @param object The object whose state is affected by the event (only needed for debug output)
+ */
+ void EventState::process(const Event& event, BaseObject* object)
{
- if (this->bActive_)
+ if (this->bProcessingEvent_)
{
- COUT(2) << "Warning: Detected Event loop in section \"" << this->eventname_ << "\" of object \"" << object->getName() << "\" and fired by \"" << event.originator_->getName() << "\"" << std::endl;
+ COUT(2) << "Warning: Detected Event loop in section \"" << event.statename_ << "\" of object \"" << object->getName() << "\" and fired by \"" << event.originator_->getName() << "\"" << std::endl;
return;
}
- this->bActive_ = true;
+ this->bProcessingEvent_ = true;
- if (this->eventname_ == event.sectionname_)
+ // check if the originator is an instance of the requested class
+ if (event.originator_->isA(this->subclass_))
{
- if (event.originator_->isA(this->subclass_))
+ // actualize the activationcounter
+ if (event.activate_)
+ ++this->activeEvents_;
+ else
{
- if (event.activate_)
- ++this->activeEvents_;
- else
- {
- --this->activeEvents_;
+ --this->activeEvents_;
- if (this->activeEvents_ < 0)
- this->activeEvents_ = 0;
- }
+ if (this->activeEvents_ < 0)
+ this->activeEvents_ = 0;
+ }
- if (this->eventfunction_->getParamCount() == 0 && event.activate_)
- (*this->eventfunction_)();
- else if ((this->activeEvents_ == 1 && event.activate_) || (this->activeEvents_ == 0 && !event.activate_))
+ if (this->statefunction_->getParamCount() == 0 && event.activate_)
+ {
+ // if the eventfunction doesn't have a state, just call it whenever an activation-event comes in
+ (*this->statefunction_)();
+ }
+ else if ((this->activeEvents_ == 1 && event.activate_) || (this->activeEvents_ == 0 && !event.activate_))
+ {
+ // if the eventfunction needs a state, we just call the function if the state changed from 0 to 1 (state = true) or from 1 to 0 (state = false) [but not if activeEvents_ is > 1]
+ if (this->statefunction_->getParamCount() == 1)
{
- if (this->eventfunction_->getParamCount() == 1)
- (*this->eventfunction_)(this->activeEvents_);
- else if (this->eventfunction_->getParamCount() >= 2 && event.castedOriginator_)
- (*this->eventfunction_)(this->activeEvents_, event.castedOriginator_);
+ // one argument: just the eventstate
+ (*this->statefunction_)(this->activeEvents_);
}
+ else if (this->statefunction_->getParamCount() >= 2)
+ {
+ // two arguments: the eventstate and the originator
+ if (this->subclass_->isExactlyA(ClassIdentifier<BaseObject>::getIdentifier()))
+ {
+ // if the subclass is BaseObject, we don't have to cast the pointer
+ (*this->statefunction_)(this->activeEvents_, event.originator_);
+ }
+ else
+ {
+ // else cast the pointer to the desired class
+ void* castedOriginator = event.originator_->getDerivedPointer(this->subclass_->getClassID());
+ (*this->statefunction_)(this->activeEvents_, castedOriginator);
+ }
+ }
}
}
- this->bActive_ = false;
+ this->bProcessingEvent_ = false;
}
}
Modified: code/branches/core5/src/libraries/core/Event.h
===================================================================
--- code/branches/core5/src/libraries/core/Event.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/Event.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -34,31 +34,49 @@
namespace orxonox
{
+ /**
+ @brief The Event struct contains information about a fired Event.
+ */
struct _CoreExport Event
{
- Event(bool activate, BaseObject* originator) : activate_(activate), originator_(originator), castedOriginator_(0) {}
+ Event(bool activate, BaseObject* originator) : activate_(activate), originator_(originator) {}
- bool activate_;
- BaseObject* originator_;
- void* castedOriginator_;
- std::string sectionname_;
+ bool activate_; //!< True if this is an activating event (the event source was inactive before and just triggered the event) - false otherwise
+ std::string statename_; //!< The name of the state this event affects
+ BaseObject* originator_; //!< The object which triggered this event
};
- class _CoreExport EventContainer
+ /**
+ @brief The EventState contains information about an event state.
+
+ An event state is a state of an object, which can be changed by events.
+ Event states are changed through functions. Possible functions headers for set event states are:
+ - memoryless state: function()
+ - boolean state: function(bool state)
+ - individual state: function(bool state, SomeClass originator)
+
+ Note that SomeClass may be any class deriving from BaseObject. You will not receive events from originators of other classes.
+ The actual class for SomeClass must be specified as the second argument of the XMLPortEventState macro.
+
+ The this pointer of the affected object is hidden in the functors, because the events are processed in the BaseObject, but some
+ statefunctions may be from child-classes.
+ */
+ class _CoreExport EventState
{
public:
- EventContainer(const std::string& eventname, Functor* eventfunction, Identifier* subclass) : bActive_(false), eventname_(eventname), eventfunction_(eventfunction), subclass_(subclass), activeEvents_(0) {}
- virtual ~EventContainer();
+ EventState(Functor* statefunction, Identifier* subclass) : bProcessingEvent_(false), activeEvents_(0), statefunction_(statefunction), subclass_(subclass) {}
+ virtual ~EventState();
- void process(BaseObject* object, const Event& event);
+ void process(const Event& event, BaseObject* object);
+
+ Functor* getFunctor() const
+ { return this->statefunction_; }
private:
- bool bActive_;
- std::string eventname_;
- Functor* eventfunction_;
- Identifier* subclass_;
-
- int activeEvents_;
+ bool bProcessingEvent_; //!< This becomes true while the container processes an event (used to prevent loops)
+ int activeEvents_; //!< The number of events which affect this state and are currently active
+ Functor* statefunction_; //!< A functor to set the state
+ Identifier* subclass_; //!< Originators must be an instance of this class (usually BaseObject, but some statefunctions allow a second argument with an originator of a specific class)
};
}
Modified: code/branches/core5/src/libraries/core/EventIncludes.h
===================================================================
--- code/branches/core5/src/libraries/core/EventIncludes.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/EventIncludes.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -32,38 +32,40 @@
#include "CorePrereqs.h"
#include "Executor.h"
-#define ORXONOX_SET_EVENT(classname, eventname, functionname, event) \
- ORXONOX_SET_EVENT_GENERIC(eventcontainer##classname##functionname, classname, eventname, functionname, event, BaseObject)
-
-#define ORXONOX_SET_EVENT_TEMPLATE(classname, eventname, functionname, event, ...) \
- ORXONOX_SET_EVENT_GENERIC_TEMPLATE(eventcontainer##classname##functionname, classname, eventname, functionname, event, BaseObject, __VA_ARGS__)
-
-#define ORXONOX_SET_SUBCLASS_EVENT(classname, eventname, functionname, event, subclassname) \
- event.castedOriginator_ = orxonox::orxonox_cast<subclassname*>(event.originator_); \
- ORXONOX_SET_EVENT_GENERIC(eventcontainer##classname##functionname, classname, eventname, functionname, event, subclassname)
-
-#define ORXONOX_SET_SUBCLASS_EVENT_TEMPLATE(classname, eventname, functionname, event, subclassname, ...) \
- event.castedOriginator_ = orxonox::orxonox_cast<subclassname*>(event.originator_); \
- ORXONOX_SET_EVENT_GENERIC_TEMPLATE(eventcontainer##classname##functionname, classname, eventname, functionname, event, subclassname, __VA_ARGS__)
-
-#define ORXONOX_SET_EVENT_GENERIC(containername, classname, eventname, functionname, event, subclassname) \
- orxonox::EventContainer* containername = this->getEventContainer(eventname); \
- if (!containername) \
+/**
+ @brief Defines a new event state (a state of the object which can be changed by events).
+
+ @param classname The name of this class
+ @param subclassname Usually BaseObject - if different, only instances of this class can send events to this object
+ @param statename The name (string) of this state
+ @param function The function which should be used to set the state
+ @param xmlelement Argument for XMLPort
+ @param mode Argument for XMLPort
+*/
+#define XMLPortEventState(classname, subclassname, statename, function, xmlelement, mode) \
+ orxonox::EventState* containername##function = this->getEventState(statename); \
+ if (!containername##function) \
{ \
- Functor* functor = orxonox::createFunctor(&classname::functionname, this); \
- containername = new orxonox::EventContainer(std::string(eventname), functor, orxonox::ClassIdentifier<subclassname>::getIdentifier()); \
- this->addEventContainer(eventname, containername); \
+ containername##function = new orxonox::EventState(orxonox::createFunctor(&classname::function, this), orxonox::ClassIdentifier<subclassname>::getIdentifier()); \
+ this->addEventState(statename, containername##function); \
} \
- containername->process(this, event)
+ XMLPortEventStateIntern(xmlportevent##function, classname, statename, xmlelement, mode)
-#define ORXONOX_SET_EVENT_GENERIC_TEMPLATE(containername, classname, eventname, functionname, event, subclassname, ...) \
- orxonox::EventContainer* containername = this->getEventContainer(eventname); \
- if (!containername) \
+/**
+ @brief Like XMLPortEventState but with additional template arguments to identify the function of the state (if ambiguous).
+*/
+#define XMLPortEventStateTemplate(classname, subclassname, statename, function, xmlelement, mode, ...) \
+ orxonox::EventState* containername##function = this->getEventState(statename); \
+ if (!containername##function) \
{ \
- Functor* functor = orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::functionname, this); \
- containername = new orxonox::EventContainer(std::string(eventname), functor, orxonox::ClassIdentifier<subclassname>::getIdentifier()); \
- this->addEventContainer(eventname, containername); \
+ containername##function = new orxonox::EventState(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::function, this), orxonox::ClassIdentifier<subclassname>::getIdentifier()); \
+ this->addEventState(statename, containername##function); \
} \
- containername->process(this, event)
+ XMLPortEventStateIntern(xmlportevent##function, classname, statename, xmlelement, mode)
+#define XMLPortEventStateIntern(name, classname, statename, xmlelement, mode) \
+ static orxonox::ExecutorMember<classname>* xmlsetfunctor##name = (orxonox::ExecutorMember<classname>*)&orxonox::createExecutor(orxonox::createFunctor(&classname::addEventSource), std::string( #classname ) + "::" + "addEventSource" + "(" + statename + ")")->setDefaultValue(1, statename); \
+ static orxonox::ExecutorMember<classname>* xmlgetfunctor##name = (orxonox::ExecutorMember<classname>*)&orxonox::createExecutor(orxonox::createFunctor(&classname::getEventSource), std::string( #classname ) + "::" + "getEventSource" + "(" + statename + ")")->setDefaultValue(1, statename); \
+ XMLPortObjectGeneric(xmlport##name, classname, orxonox::BaseObject, statename, xmlsetfunctor##name, xmlgetfunctor##name, xmlelement, mode, false, true)
+
#endif /* _EventIncludes_H__ */
Modified: code/branches/core5/src/libraries/core/Identifier.cc
===================================================================
--- code/branches/core5/src/libraries/core/Identifier.cc 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/Identifier.cc 2009-10-05 15:02:25 UTC (rev 5879)
@@ -87,8 +87,6 @@
delete (it->second);
for (std::map<std::string, XMLPortObjectContainer*>::iterator it = this->xmlportObjectContainers_.begin(); it != this->xmlportObjectContainers_.end(); ++it)
delete (it->second);
- for (std::map<std::string, XMLPortObjectContainer*>::iterator it = this->xmlportEventContainers_.begin(); it != this->xmlportEventContainers_.end(); ++it)
- delete (it->second);
}
/**
@@ -564,37 +562,6 @@
}
/**
- @brief Returns a XMLPortEventContainer that attaches an event to this class.
- @param sectionname The name of the section that contains the event
- @return The container
- */
- XMLPortObjectContainer* Identifier::getXMLPortEventContainer(const std::string& eventname)
- {
- std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportEventContainers_.find(eventname);
- if (it != this->xmlportEventContainers_.end())
- return it->second;
- else
- return 0;
- }
-
- /**
- @brief Adds a new XMLPortEventContainer that attaches an event to this class.
- @param sectionname The name of the section that contains the event
- @param container The container
- */
- void Identifier::addXMLPortEventContainer(const std::string& eventname, XMLPortObjectContainer* container)
- {
- std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportEventContainers_.find(eventname);
- if (it != this->xmlportEventContainers_.end())
- {
- COUT(2) << "Warning: Overwriting XMLPortEventContainer in class " << this->getName() << "." << std::endl;
- delete (it->second);
- }
-
- this->xmlportEventContainers_[eventname] = container;
- }
-
- /**
@brief Lists the names of all Identifiers in a std::set<const Identifier*>.
@param out The outstream
@param list The list (or set) of Identifiers
Modified: code/branches/core5/src/libraries/core/Identifier.h
===================================================================
--- code/branches/core5/src/libraries/core/Identifier.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/Identifier.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -267,20 +267,6 @@
XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname);
- //////////////////
- ///// Events /////
- //////////////////
- /** @brief Returns the map that stores all XMLPort events. @return The const_iterator */
- inline const std::map<std::string, XMLPortObjectContainer*>& getXMLPortEventMap() const { return this->xmlportEventContainers_; }
- /** @brief Returns a const_iterator to the beginning of the map that stores all XMLPort events. @return The const_iterator */
- inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortEventMapBegin() const { return this->xmlportEventContainers_.begin(); }
- /** @brief Returns a const_iterator to the end of the map that stores all XMLPort events. @return The const_iterator */
- inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortEventMapEnd() const { return this->xmlportEventContainers_.end(); }
-
- void addXMLPortEventContainer(const std::string& eventname, XMLPortObjectContainer* container);
- XMLPortObjectContainer* getXMLPortEventContainer(const std::string& eventname);
-
-
protected:
Identifier();
Identifier(const Identifier& identifier); // don't copy
@@ -341,7 +327,6 @@
std::map<std::string, XMLPortParamContainer*> xmlportParamContainers_; //!< All loadable parameters
std::map<std::string, XMLPortObjectContainer*> xmlportObjectContainers_; //!< All attachable objects
- std::map<std::string, XMLPortObjectContainer*> xmlportEventContainers_; //!< All events
};
_CoreExport std::ostream& operator<<(std::ostream& out, const std::set<const Identifier*>& list);
Modified: code/branches/core5/src/libraries/core/OrxonoxClass.h
===================================================================
--- code/branches/core5/src/libraries/core/OrxonoxClass.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/OrxonoxClass.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -109,23 +109,23 @@
@return
Returns NULL if the no pointer was found.
*/
- template <class T>
- FORCEINLINE T* getDerivedPointer(unsigned int classID)
+ FORCEINLINE void* getDerivedPointer(unsigned int classID)
{
for (int i = this->objectPointers_.size() - 1; i >= 0; --i)
{
if (this->objectPointers_[i].first == classID)
- return static_cast<T*>(this->objectPointers_[i].second);
+ return this->objectPointers_[i].second;
}
return NULL;
}
- //! Const version of getDerivedPointer
- template <class T>
- FORCEINLINE const T* getDerivedPointer(unsigned int classID) const
- {
- return const_cast<OrxonoxClass*>(this)->getDerivedPointer<T>(classID);
- }
+ //! Version of getDerivedPointer with template
+ template <class T> FORCEINLINE T* getDerivedPointer(unsigned int classID)
+ { return static_cast<T*>(this->getDerivedPointer(classID)); }
+ //! Const version of getDerivedPointer with template
+ template <class T> FORCEINLINE const T* getDerivedPointer(unsigned int classID) const
+ { return const_cast<OrxonoxClass*>(this)->getDerivedPointer<T>(classID); }
+
private:
/** @brief Increments the reference counter (for smart pointers). */
inline void incrementReferenceCount()
Modified: code/branches/core5/src/libraries/core/Super.h
===================================================================
--- code/branches/core5/src/libraries/core/Super.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/Super.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -249,15 +249,12 @@
#define SUPER_changedVisibility(classname, functionname, ...) \
SUPER_NOARGS(classname, functionname)
- #define SUPER_processEvent(classname, functionname, ...) \
+ #define SUPER_XMLEventPort(classname, functionname, ...) \
SUPER_ARGS(classname, functionname, __VA_ARGS__)
#define SUPER_changedScale(classname, functionname, ...) \
SUPER_NOARGS(classname, functionname)
- #define SUPER_changedMainState(classname, functionname, ...) \
- SUPER_NOARGS(classname, functionname)
-
#define SUPER_changedOwner(classname, functionname, ...) \
SUPER_NOARGS(classname, functionname)
@@ -496,33 +493,29 @@
()
SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
- SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(4, processEvent, true, Event& event)
- (event)
+ SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(4, XMLEventPort, true, Element& xmlelement, XMLPort::Mode mode)
+ (xmlelement, mode)
SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(5, changedScale, false)
()
SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
- SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(6, changedMainState, false)
+ SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(6, changedOwner, false)
()
SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
- SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(7, changedOwner, false)
+ SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(7, changedOverlayGroup, false)
()
SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
- SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(8, changedOverlayGroup, false)
+ SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(8, changedName, false)
()
SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
- SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedName, false)
+ SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedGametype, false)
()
SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
-
- SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(10, changedGametype, false)
- ()
- SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
// (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
}
@@ -570,9 +563,8 @@
SUPER_INTRUSIVE_DECLARATION(tick);
SUPER_INTRUSIVE_DECLARATION(changedActivity);
SUPER_INTRUSIVE_DECLARATION(changedVisibility);
- SUPER_INTRUSIVE_DECLARATION(processEvent);
+ SUPER_INTRUSIVE_DECLARATION(XMLEventPort);
SUPER_INTRUSIVE_DECLARATION(changedScale);
- SUPER_INTRUSIVE_DECLARATION(changedMainState);
SUPER_INTRUSIVE_DECLARATION(changedOwner);
SUPER_INTRUSIVE_DECLARATION(changedOverlayGroup);
SUPER_INTRUSIVE_DECLARATION(changedName);
Modified: code/branches/core5/src/libraries/core/XMLPort.h
===================================================================
--- code/branches/core5/src/libraries/core/XMLPort.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/libraries/core/XMLPort.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -410,7 +410,7 @@
COUT(1) << ex.what() << std::endl;
}
}
- else
+ else if (mode == XMLPort::SaveObject)
{
if (this->saveexecutor_)
{
@@ -627,7 +627,7 @@
COUT(1) << ex.what() << std::endl;
}
}
- else
+ else if (mode == XMLPort::SaveObject)
{
}
Modified: code/branches/core5/src/modules/objects/Attacher.cc
===================================================================
--- code/branches/core5/src/modules/objects/Attacher.cc 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/modules/objects/Attacher.cc 2009-10-05 15:02:25 UTC (rev 5879)
@@ -52,8 +52,8 @@
void Attacher::processEvent(Event& event)
{
- for (std::list<WorldEntity*>::iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
- (*it)->fireEvent(event);
+ if (this->target_)
+ this->target_->processEvent(event);
}
void Attacher::changedActivity()
@@ -101,8 +101,13 @@
return;
for (ObjectList<WorldEntity>::iterator it = ObjectList<WorldEntity>::begin(); it != ObjectList<WorldEntity>::end(); ++it)
+ {
if (it->getName() == this->targetname_)
+ {
+ this->target_ = *it;
this->attachToParent(*it);
+ }
+ }
}
void Attacher::loadedNewXMLName(BaseObject* object)
Modified: code/branches/core5/src/modules/objects/triggers/EventTrigger.cc
===================================================================
--- code/branches/core5/src/modules/objects/triggers/EventTrigger.cc 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/modules/objects/triggers/EventTrigger.cc 2009-10-05 15:02:25 UTC (rev 5879)
@@ -46,11 +46,11 @@
{
}
- void EventTrigger::processEvent(Event& event)
+ void EventTrigger::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
{
- SUPER(EventTrigger, processEvent, event);
+ SUPER(EventTrigger, XMLEventPort, xmlelement, mode);
- ORXONOX_SET_EVENT(EventTrigger, "trigger", trigger, event);
+ XMLPortEventState(EventTrigger, BaseObject, "trigger", trigger, xmlelement, mode);
}
bool EventTrigger::isTriggered(TriggerMode::Value mode)
Modified: code/branches/core5/src/modules/objects/triggers/EventTrigger.h
===================================================================
--- code/branches/core5/src/modules/objects/triggers/EventTrigger.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/modules/objects/triggers/EventTrigger.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -40,7 +40,7 @@
EventTrigger(BaseObject* creator);
virtual ~EventTrigger();
- virtual void processEvent(Event& event);
+ virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
inline void trigger(bool bTriggered)
{ this->bEventTriggered_ = bTriggered; this->tick(0); }
Modified: code/branches/core5/src/modules/questsystem/QuestEffectBeacon.cc
===================================================================
--- code/branches/core5/src/modules/questsystem/QuestEffectBeacon.cc 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/modules/questsystem/QuestEffectBeacon.cc 2009-10-05 15:02:25 UTC (rev 5879)
@@ -74,18 +74,16 @@
XMLPortParam(QuestEffectBeacon, "times", setTimes, getTimes, xmlelement, mode);
XMLPortObject(QuestEffectBeacon, QuestEffect, "effects", addEffect, getEffect, xmlelement, mode);
+ XMLPortEventState(QuestEffectBeacon, PlayerTrigger, "execute", execute, xmlelement, mode);
+
COUT(3) << "New QuestEffectBeacon created." << std::endl;
}
- /**
- @brief
- Processes an event for this QuestEffectBeacon.
- */
- void QuestEffectBeacon::processEvent(Event& event)
+ void QuestEffectBeacon::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
{
- SUPER(QuestEffectBeacon, processEvent, event);
+ SUPER(QuestEffectBeacon, XMLEventPort, xmlelement, mode);
- ORXONOX_SET_SUBCLASS_EVENT(QuestEffectBeacon, "execute", execute, event, PlayerTrigger);
+ XMLPortEventState(QuestEffectBeacon, PlayerTrigger, "execute", execute, xmlelement, mode);
}
/**
Modified: code/branches/core5/src/modules/questsystem/QuestEffectBeacon.h
===================================================================
--- code/branches/core5/src/modules/questsystem/QuestEffectBeacon.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/modules/questsystem/QuestEffectBeacon.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -85,9 +85,8 @@
virtual ~QuestEffectBeacon();
virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a QuestEffectBeacon object through XML.
+ virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
- virtual void processEvent(Event& event); //!< Processes an event for this QuestEffectBeacon.
-
bool execute(bool b, PlayerTrigger* trigger); //!< Executes the QuestEffects of the QuestEffectBeacon.
/**
Modified: code/branches/core5/src/orxonox/graphics/ParticleSpawner.cc
===================================================================
--- code/branches/core5/src/orxonox/graphics/ParticleSpawner.cc 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/orxonox/graphics/ParticleSpawner.cc 2009-10-05 15:02:25 UTC (rev 5879)
@@ -70,11 +70,11 @@
XMLPortParam(ParticleSpawner, "destroydelay", setDestroydelay, getDestroydelay, xmlelement, mode).defaultValues(0.0f);
}
- void ParticleSpawner::processEvent(Event& event)
+ void ParticleSpawner::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
{
- SUPER(ParticleSpawner, processEvent, event);
+ SUPER(ParticleSpawner, XMLEventPort, xmlelement, mode);
- ORXONOX_SET_EVENT(ParticleSpawner, "spawn", spawn, event);
+ XMLPortEventState(ParticleSpawner, BaseObject, "spawn", spawn, xmlelement, mode);
}
void ParticleSpawner::configure(float lifetime, float startdelay, float destroydelay, bool autodestroy)
Modified: code/branches/core5/src/orxonox/graphics/ParticleSpawner.h
===================================================================
--- code/branches/core5/src/orxonox/graphics/ParticleSpawner.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/orxonox/graphics/ParticleSpawner.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -43,7 +43,7 @@
virtual ~ParticleSpawner();
virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
- virtual void processEvent(Event& event);
+ virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
inline void stop(bool bDestroy)
{ this->bForceDestroy_ = bDestroy; this->stopParticleSpawner(); }
Modified: code/branches/core5/src/orxonox/overlays/OrxonoxOverlay.h
===================================================================
--- code/branches/core5/src/orxonox/overlays/OrxonoxOverlay.h 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/orxonox/overlays/OrxonoxOverlay.h 2009-10-05 15:02:25 UTC (rev 5879)
@@ -212,8 +212,8 @@
OverlayGroup* group_;
};
- SUPER_FUNCTION(7, OrxonoxOverlay, changedOwner, false);
- SUPER_FUNCTION(8, OrxonoxOverlay, changedOverlayGroup, false);
+ SUPER_FUNCTION(6, OrxonoxOverlay, changedOwner, false);
+ SUPER_FUNCTION(7, OrxonoxOverlay, changedOverlayGroup, false);
}
#endif /* _OrxonoxOverlay_H__ */
Modified: code/branches/core5/src/orxonox/worldentities/WorldEntity.cc
===================================================================
--- code/branches/core5/src/orxonox/worldentities/WorldEntity.cc 2009-10-04 23:36:33 UTC (rev 5878)
+++ code/branches/core5/src/orxonox/worldentities/WorldEntity.cc 2009-10-05 15:02:25 UTC (rev 5879)
@@ -174,7 +174,7 @@
void WorldEntity::registerVariables()
{
- registerVariable(this->mainStateName_, VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedMainState));
+ registerVariable(this->mainStateName_, VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedMainStateName));
registerVariable(this->bActive_, VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedActivity));
registerVariable(this->bVisible_, VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedVisibility));
More information about the Orxonox-commit
mailing list