[Orxonox-commit 2148] r6864 - in code/trunk/src: modules/objects modules/objects/triggers orxonox/worldentities/pawns
dafrick at orxonox.net
dafrick at orxonox.net
Sun May 9 10:56:44 CEST 2010
Author: dafrick
Date: 2010-05-09 10:56:43 +0200 (Sun, 09 May 2010)
New Revision: 6864
Added:
code/trunk/src/modules/objects/triggers/EventMultiTrigger.cc
code/trunk/src/modules/objects/triggers/EventMultiTrigger.h
Modified:
code/trunk/src/modules/objects/ObjectsPrereqs.h
code/trunk/src/modules/objects/triggers/CMakeLists.txt
code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h
code/trunk/src/modules/objects/triggers/MultiTrigger.cc
code/trunk/src/modules/objects/triggers/MultiTrigger.h
code/trunk/src/orxonox/worldentities/pawns/Pawn.cc
Log:
Created a new MutliTrigger: EventMultiTrigger, which essentially does the same as EventTrigger but for every object that is a target as specified by teh EventMultiTrigger an Event is fired with information as being triggered by the target object.
This allows, e.g. to use the EventMultiTrigger to trigger QuestEffectBeacons.
I've also added a fireEvent() to Pawn such that an Event is fired when the Pawn is destroyed (forcebly). With EventMultiTrigger (but also with EventTrigger) one can now find out whether a Pawn died.
Here a little piece of example XML code to illustrate the usage:
<EventMutliTrigger name="trigger1">
<events>
<trigger>
<Spaceship />
</trigger>
</events>
</EventMultiTrigger>
To be able to implement this another feature was added to MultiTrigger, which is called broadcast. If enabled the MultiTrigger sends all Events triggered by NULL as to have come by all possible triggerers.
Additionally I've fixed a bug:
In DistanceMultiTrigger, an infinite loop occured under some circumstances. Not any more.
And did some niceifying (aka. documenting, renaming and code restructuring).
Modified: code/trunk/src/modules/objects/ObjectsPrereqs.h
===================================================================
--- code/trunk/src/modules/objects/ObjectsPrereqs.h 2010-05-07 14:14:18 UTC (rev 6863)
+++ code/trunk/src/modules/objects/ObjectsPrereqs.h 2010-05-09 08:56:43 UTC (rev 6864)
@@ -86,6 +86,7 @@
class CheckPoint;
class DistanceMultiTrigger;
class DistanceTrigger;
+ class EventMultiTrigger;
class EventTrigger;
class MultiTrigger;
class MultiTriggerContainer;
Modified: code/trunk/src/modules/objects/triggers/CMakeLists.txt
===================================================================
--- code/trunk/src/modules/objects/triggers/CMakeLists.txt 2010-05-07 14:14:18 UTC (rev 6863)
+++ code/trunk/src/modules/objects/triggers/CMakeLists.txt 2010-05-09 08:56:43 UTC (rev 6864)
@@ -2,6 +2,7 @@
CheckPoint.cc
DistanceMultiTrigger.cc
DistanceTrigger.cc
+ EventMultiTrigger.cc
EventTrigger.cc
MultiTrigger.cc
MultiTriggerContainer.cc
Modified: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc 2010-05-07 14:14:18 UTC (rev 6863)
+++ code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc 2010-05-09 08:56:43 UTC (rev 6864)
@@ -58,7 +58,6 @@
*/
DistanceMultiTrigger::~DistanceMultiTrigger()
{
-
}
/**
@@ -80,7 +79,6 @@
*/
std::queue<MultiTriggerState*>* DistanceMultiTrigger::letTrigger(void)
{
- ClassTreeMask& targetMask = this->getTargetMask();
std::queue<MultiTriggerState*>* queue = NULL;
@@ -91,7 +89,7 @@
WorldEntity* key = it->first;
if(entity == NULL)
{
- it++;
+ ++it;
this->removeFromRange(key);
continue;
}
@@ -100,8 +98,11 @@
// If the object is no longer in range.
if (distanceVec.length() > this->distance_)
{
- if(!this->removeFromRange(entity))
+ if(!this->removeFromRange(key))
+ {
+ ++it;
continue;
+ }
// If no queue has been created, yet.
if(queue == NULL)
@@ -117,6 +118,8 @@
++it;
}
+ ClassTreeMask& targetMask = this->getTargetMask();
+
// Check for new objects that are in range
for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
{
Modified: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h 2010-05-07 14:14:18 UTC (rev 6863)
+++ code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h 2010-05-09 08:56:43 UTC (rev 6864)
@@ -91,7 +91,7 @@
@return Returns true if successful.
*/
inline bool removeFromRange(WorldEntity* entity)
- { (*this->range_.find(entity)->second)->destroy(); bool erased = this->range_.erase(entity) > 0; return erased; }
+ { WeakPtr<WorldEntity>* weakptr = this->range_.find(entity)->second; bool erased = this->range_.erase(entity) > 0; if(erased) delete weakptr; return erased; }
private:
float distance_; //!< The distance at which the DistanceMultiTrigger triggers.
Added: code/trunk/src/modules/objects/triggers/EventMultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/EventMultiTrigger.cc (rev 0)
+++ code/trunk/src/modules/objects/triggers/EventMultiTrigger.cc 2010-05-09 08:56:43 UTC (rev 6864)
@@ -0,0 +1,72 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Damian 'Mozork' Frick
+ * Co-authors:
+ * ...
+ *
+ */
+
+/**
+ @file EventMultiTrigger.cc
+ @brief Implementation of the EventMultiTrigger class.
+*/
+
+#include "EventMultiTrigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/EventIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+
+ CreateFactory(EventMultiTrigger);
+
+ EventMultiTrigger::EventMultiTrigger(BaseObject* creator) : MultiTrigger(creator)
+ {
+ RegisterObject(EventMultiTrigger);
+
+ this->bEventTriggered_ = false;
+ }
+
+ EventMultiTrigger::~EventMultiTrigger()
+ {
+
+ }
+
+ void EventMultiTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+ {
+ SUPER(EventMultiTrigger, XMLPort, xmlelement, mode);
+
+ this->setBroadcast(true);
+ }
+
+ void EventMultiTrigger::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+ {
+ SUPER(EventMultiTrigger, XMLEventPort, xmlelement, mode);
+
+ XMLPortEventState(EventMultiTrigger, BaseObject, "trigger", trigger, xmlelement, mode);
+ }
+
+}
+
Added: code/trunk/src/modules/objects/triggers/EventMultiTrigger.h
===================================================================
--- code/trunk/src/modules/objects/triggers/EventMultiTrigger.h (rev 0)
+++ code/trunk/src/modules/objects/triggers/EventMultiTrigger.h 2010-05-09 08:56:43 UTC (rev 6864)
@@ -0,0 +1,63 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Damian 'Mozork' Frick
+ * Co-authors:
+ * ...
+ *
+ */
+
+/**
+ @file EventMultiTrigger.h
+ @brief Definition of the EventMultiTrigger class.
+*/
+
+#ifndef _EventMultiTrigger_H__
+#define _EventMultiTrigger_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "MultiTrigger.h"
+
+namespace orxonox
+{
+
+ class _ObjectsExport EventMultiTrigger : public MultiTrigger
+ {
+
+ public:
+ EventMultiTrigger(BaseObject* creator);
+ ~EventMultiTrigger();
+
+ virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating an EventMultiTrigger object through XML.
+ virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+
+ inline void trigger(bool bTriggered)
+ { this->bEventTriggered_ = bTriggered; this->changeTriggered(); }
+
+ private:
+ bool bEventTriggered_;
+ };
+
+}
+
+#endif // _EventMultiTrigger_H__
Modified: code/trunk/src/modules/objects/triggers/MultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/MultiTrigger.cc 2010-05-07 14:14:18 UTC (rev 6863)
+++ code/trunk/src/modules/objects/triggers/MultiTrigger.cc 2010-05-09 08:56:43 UTC (rev 6864)
@@ -71,6 +71,8 @@
this->bInvertMode_ = false;
this->mode_ = MultiTriggerMode::EventTriggerAND;
+ this->bBroadcast_ = false;
+
this->parentTrigger_ = NULL;
this->targetMask_.exclude(Class(BaseObject));
@@ -84,7 +86,7 @@
*/
MultiTrigger::~MultiTrigger()
{
- COUT(4) << "Destorying MultiTrigger &" << this << ". " << this->stateQueue_.size() << " states still in queue. Deleting." << std::endl;
+ COUT(4) << "Destroying MultiTrigger &" << this << ". " << this->stateQueue_.size() << " states still in queue. Deleting." << std::endl;
while(this->stateQueue_.size() > 0)
{
MultiTriggerState* state = this->stateQueue_.front().second;
@@ -109,6 +111,7 @@
XMLPortParam(MultiTrigger, "simultaniousTriggerers", setSimultaniousTriggerers, getSimultaniousTriggerers, xmlelement, mode);
XMLPortParam(MultiTrigger, "invert", setInvert, getInvert, xmlelement, mode);
XMLPortParamTemplate(MultiTrigger, "mode", setMode, getModeString, xmlelement, mode, const std::string&);
+ XMLPortParam(MultiTrigger, "broadcast", setBroadcast, getBroadcast, xmlelement, mode);
XMLPortParamLoadOnly(MultiTrigger, "target", addTargets, xmlelement, mode).defaultValues("Pawn"); //TODO: Remove load only
//TODO: Maybe nicer with explicit subgroup, e.g. triggers
@@ -256,7 +259,13 @@
// Fire the Event if the activity has changed.
if(bFire)
{
- this->fire(bActive, state->originator);
+ if(this->bBroadcast_ && state->originator == NULL)
+ {
+ this->broadcast(bActive);
+ }
+ else
+ this->fire(bActive, state->originator);
+
bStateChanged = true;
}
}
@@ -264,9 +273,12 @@
// Print some debug output if the state has changed.
if(bStateChanged)
{
- COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") changed state. originator: " << state->originator->getIdentifier()->getName() << " (&" << state->originator << "), active: " << bActive << ", triggered: " << state->bTriggered << "." << std::endl;
+ if(state->originator != NULL)
+ COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") changed state. originator: " << state->originator->getIdentifier()->getName() << " (&" << state->originator << "), active: " << bActive << ", triggered: " << state->bTriggered << "." << std::endl;
+ else
+ COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") changed state. originator: NULL, active: " << bActive << ", triggered: " << state->bTriggered << "." << std::endl;
if(this->parentTrigger_ != NULL)
- this->parentTrigger_->activityChanged(state->originator);
+ this->parentTrigger_->subTrigggerActivityChanged(state->originator);
}
// If the MultiTrigger has exceeded its amount of activations and it doesn't stay active, it has to be destroyed,
@@ -424,8 +436,6 @@
@brief
This method is called by the MultiTrigger to get information about new trigger events that need to be looked at.
This method is the device for the behaviour (the conditions under which the MultiTrigger triggers) of any derived class from MultiTrigger.
-
- In this implementation it collects all objects triggering all sub-triggers nd the MultiTrigger itself and creates a state for each of them.
@return
A pointer to a queue of MultiTriggerState pointers is returned, containing all the neccessary information to decide whether these states should indeed become new states of the MultiTrigger.
Please be aware that both the queue and the states in the queue need to be deleted one they have been used. This is already done in the tick() method of this class but would have to be done by any method calling this method.
@@ -434,10 +444,32 @@
{
return NULL;
}
-
- void MultiTrigger::activityChanged(BaseObject* originator)
+
+ /**
+ @brief
+ This method can be called by any class inheriting from MultiTrigger to change it's triggered status for a specified originator.
+
+ Compared to the letTrigger mode, which just polls and lets the pollee send it's state changed back, the changeTriggered method lets the trigger advertise its state changes just as they happen so it's much like the interrupt version of letTrigger.
+ @param originator
+ The originator which triggered the state change.
+ */
+ void MultiTrigger::changeTriggered(BaseObject* originator)
{
MultiTriggerState* state = new MultiTriggerState;
+ state->bTriggered = (!this->isTriggered(originator) & this->isModeTriggered(originator)) ^ this->bInvertMode_;
+ state->originator = originator;
+ this->addState(state);
+ }
+
+ /**
+ @brief
+ This method is called by any sub-trigger to advertise changes in it's state to it's parent-trigger.
+ @param originator
+ The object that caused the change in activity.
+ */
+ void MultiTrigger::subTrigggerActivityChanged(BaseObject* originator)
+ {
+ MultiTriggerState* state = new MultiTriggerState;
state->bTriggered = (this->isTriggered(originator) & this->isModeTriggered(originator)) ^ this->bInvertMode_;
state->originator = originator;
this->addState(state);
@@ -498,10 +530,10 @@
/**
@brief
- Helper method. Creates an event for the given status and originator and fires it.
+ Helper method. Creates an Event for the given status and originator and fires it.
Or more precisely creates a MultiTriggerContainer to encompass all neccesary information and creates an Event from that and sends it.
@param status
- The status of the event to be fired. This is equivalent to the activity of the MultiTrigger.
+ The status of the Event to be fired. This is equivalent to the activity of the MultiTrigger.
@param originator
The object that triggered the MultiTrigger to fire this Event.
*/
@@ -511,6 +543,7 @@
if(originator == NULL)
{
this->fireEvent(status);
+ COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << "): Fired event. status: " << status << "." << std::endl;
return;
}
@@ -522,6 +555,23 @@
/**
@brief
+ Helper method. Broadcasts an Event for every object that is a target.
+ @param status
+ The status of the Events to be fired. This is equivalent to the activity of the MultiTrigger.
+ */
+ void MultiTrigger::broadcast(bool status)
+ {
+ ClassTreeMask& targetMask = this->getTargetMask();
+
+ for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
+ {
+ BaseObject* object = static_cast<BaseObject*>(*it);
+ this->fire(status, object);
+ }
+ }
+
+ /**
+ @brief
Helper method. Adds a state to the state queue, where the state will wait to become active.
@param state
The state to be added.
Modified: code/trunk/src/modules/objects/triggers/MultiTrigger.h
===================================================================
--- code/trunk/src/modules/objects/triggers/MultiTrigger.h 2010-05-07 14:14:18 UTC (rev 6863)
+++ code/trunk/src/modules/objects/triggers/MultiTrigger.h 2010-05-09 08:56:43 UTC (rev 6864)
@@ -81,6 +81,7 @@
'invert': Invert is a bool, if true the trigger is in invert-mode, meaning, that if the triggering condition is fulfilled the MultiTrigger will have the state not triggered and and if the condition is not fulfilled it will have the state triggered. In short it just inverts the behaviour of the MultiTrigger. The default is false.
'simultaniousTriggerers': The number of simultanious triggerers limits the number of object that are allowed to trigger the MultiTrigger at the same time. Or a little more precisely, the number of distinct objects the MultiTrigger has 'triggered' states for, at each point in time.
'mode': The mode describes how the MultiTrigger acts in relation to all the MultiTriggers, that are appended to it. There are 3 modes: 'and', meaning that the MultiTrigger can only be triggered if all the appended MultiTriggers are active. 'or', meaning that the MultiTrigger can only triggered if at least one of the appendend MultiTriggers is active. And 'xor', meaning that the MultiTrigger can only be triggered if one and only one appended MultiTrigger is active. Notice, that I wrote 'can only be active', that implies, that there is an addtitional condition to the activity of the MultiTrigger and that is the fulfillment of the triggering condition (the MultiTrigger itself doesn't have one, but all derived classes should). Also bear in mind, that the activity of a MultiTrigger is still coupled to the object that triggered it. The default is 'and'.
+ 'broadcast' Broadcast is a bool, if true the MutliTrigger is in broadcast-mode, meaining, that all trigger events that are caused by no originator (originator is NULL) are broadcasted as having come from every possible originator, or more precisely as having come from all objects that are specified targets of this MultiTrigger.
'target': The target describes the kind of objects that are allowed to trigger this MultiTrigger. The default is 'Pawn'.
Also there is the possibility of appending MultiTriggers to the MultiTrigger just by adding them as subobjects in the XML description of your MultiTrigger.
@@ -108,7 +109,7 @@
@brief Get the delay of the MultiTrigger.
@return The delay.
*/
- inline float getDelay() const
+ inline float getDelay(void) const
{ return this->delay_; }
/**
@@ -121,7 +122,7 @@
@brief Get the switch-mode of the MultiTrigger.
@return Returns true if the MultiTriger is in switch-mode.
*/
- inline bool getSwitch() const
+ inline bool getSwitch(void) const
{ return this->bSwitch_; }
/**
@@ -134,7 +135,7 @@
@brief Get the stay-active-mode of the MultiTrigger.
@return Returns true if the MultiTrigger stays active.
*/
- inline bool getStayActive() const
+ inline bool getStayActive(void) const
{ return this->bStayActive_; }
/**
@@ -147,7 +148,7 @@
@brief Get the number of remaining activations of the MultiTrigger.
@return The number of activations. -1 denotes infinity.
*/
- inline int getActivations() const
+ inline int getActivations(void) const
{ return this->remainingActivations_; }
/**
@@ -173,7 +174,7 @@
@brief Get the invert-mode of the MultiTrigger.
@return Returns true if the MultiTrigger is set to invert.
*/
- inline bool getInvert() const
+ inline bool getInvert(void) const
{ return this->bInvertMode_; }
void setMode(const std::string& modeName); //!< Set the mode of the MultiTrigger.
@@ -192,12 +193,25 @@
{ return mode_; }
/**
+ @brief Set the broadcast-mode of the MultiTrigger.
+ @param bBroadcast If true the MultiTrigger is set to broadcast;
+ */
+ inline void setBroadcast(bool bBroadcast)
+ { this->bBroadcast_ = bBroadcast; }
+ /**
+ @brief Get the broadcast-mode of the MultiTrigger.
+ @return Returns true if the MultiTrigger is set to broadcast.
+ */
+ inline bool getBroadcast(void)
+ { return this->bBroadcast_; }
+
+ /**
@brief Get whether the input object is a target of the MultiTrigger.
@param target A pointer to the object.
@return Returns true if the input object is a target, false if not.
*/
inline bool isTarget(BaseObject* target)
- { return targetMask_.isIncluded(target->getIdentifier()); }
+ { if(target == NULL) return true; else return targetMask_.isIncluded(target->getIdentifier()); }
void addTargets(const std::string& targets); //!< Add some target to the MultiTrigger.
void removeTargets(const std::string& targets); //!< Remove some target from the MultiTrigger.
@@ -207,12 +221,13 @@
protected:
virtual std::queue<MultiTriggerState*>* letTrigger(void); //!< This method is called by the MultiTrigger to get information about new trigger events that need to be looked at.
- void activityChanged(BaseObject* originator);
+ void changeTriggered(BaseObject* originator = NULL); //!< This method can be called by any class inheriting from MultiTrigger to change it's triggered status for a specified originator.
bool isModeTriggered(BaseObject* triggerer = NULL); //!< Checks whetherx the MultiTrigger is triggered concerning it's sub-triggers.
bool isTriggered(BaseObject* triggerer = NULL); //!< Get whether the MultiTrigger is triggered for a given object.
- void fire(bool status, BaseObject* originator = NULL); //!< Helper method. Creates an event for the given status and originator and fires it.
+ void fire(bool status, BaseObject* originator = NULL); //!< Helper method. Creates an Event for the given status and originator and fires it.
+ void broadcast(bool status); //!< Helper method. Broadcasts an Event for every object that is a target.
/**
@brief Adds the parent of a MultiTrigger.
@@ -239,6 +254,8 @@
static const std::string and_s;
static const std::string or_s;
static const std::string xor_s;
+
+ void subTrigggerActivityChanged(BaseObject* originator); //!< This method is called by any sub-trigger to advertise changes in it's state to it's parent-trigger.
bool addState(MultiTriggerState* state); //!< Helper method. Adds a state to the state queue, where the state will wait to become active.
@@ -265,6 +282,8 @@
bool bInvertMode_; //!< Bool for the invert-mode, if true the MultiTrigger is inverted.
MultiTriggerMode::Value mode_; //!< The mode of the MultiTrigger.
+ bool bBroadcast_; //!< Bool for the broadcast-mode, if true all triggers go to all possible targets.
+
MultiTrigger* parentTrigger_;
std::set<MultiTrigger*> subTriggers_; //!< The sub-triggers of this MultiTrigger.
Modified: code/trunk/src/orxonox/worldentities/pawns/Pawn.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/Pawn.cc 2010-05-07 14:14:18 UTC (rev 6863)
+++ code/trunk/src/orxonox/worldentities/pawns/Pawn.cc 2010-05-09 08:56:43 UTC (rev 6864)
@@ -130,7 +130,10 @@
if (GameMode::isMaster())
if (this->health_ <= 0 && bAlive_)
+ {
+ this->fireEvent(); // Event to notify anyone who want's to know about the death.
this->death();
+ }
}
void Pawn::setPlayer(PlayerInfo* player)
More information about the Orxonox-commit
mailing list