Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 6800 for code/trunk


Ignore:
Timestamp:
Apr 29, 2010, 1:16:16 PM (15 years ago)
Author:
dafrick
Message:

Created a new class of triggers called Multitriggers.
MultiTriggers are triggers which (as opposed to normal triggers) have a state for each object triggering the MultiTrigger, that means, that a MultiTrigger can be triggered for two different Players, while not being triggered for a third.
To go with this MultiTrigger I created a data structure (MultitriggerContainer), which helps relaying important information to the objects, that receive the Events of the trigger.
Also there is a MultiDistanceTrigger, which is just the DistanceTrigger as a MultiTrigger.

To make this work I had to make some adjustements to the eventsystem, namely an EventState can now be either an EventState (as it was before) or an EventSink, which means that every efent arriving at the EventState is processed as opposed to just the ones which change the state.
There is a new makro (XMLPortEventSink) to create an EventState with sink behaviour. It can be used exacly as the XMLPortEventState makro.

Location:
code/trunk/src
Files:
6 added
11 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/libraries/core/BaseObject.cc

    r6524 r6800  
    103103        }
    104104    }
     105   
     106    /** @brief Adds an object which listens to the events of this object. */
     107    void BaseObject::registerEventListener(BaseObject* object)
     108    {
     109        COUT(4) << "New EventListener: " << object->getIdentifier()->getName() << " &(" << object << ")." << std::endl;
     110        this->eventListeners_.insert(object);
     111    }
    105112
    106113    /**
     
    356363    {
    357364        this->registerEventStates();
     365       
     366        COUT(4) << this->getIdentifier()->getName() << " (&" << this << ") processing event. originator: " << event.originator_->getIdentifier()->getName() << " (&" << event.originator_ << "), activate: " << event.activate_ << ", name: " << event.name_ << ", statename: " << event.statename_ << "." << std::endl;
    358367
    359368        std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(event.statename_);
  • code/trunk/src/libraries/core/BaseObject.h

    r6524 r6800  
    188188        private:
    189189            /** @brief Adds an object which listens to the events of this object. */
    190             inline void registerEventListener(BaseObject* object)
    191                 { this->eventListeners_.insert(object); }
     190            void registerEventListener(BaseObject* object);
    192191            /** @brief Removes an event listener from this object. */
    193192            inline void unregisterEventListener(BaseObject* object)
  • code/trunk/src/libraries/core/Event.cc

    r6417 r6800  
    5959        this->bProcessingEvent_ = true;
    6060
     61        COUT(4) << "Processing event (EventState) : originator: " << event.originator_->getIdentifier()->getName() << " (&" << event.originator_ << "), activate: " << event.activate_ << ", name: " << event.name_ << ", statename: " << event.statename_ << ", object: " << object->getIdentifier()->getName() << " (&" << object << ")" << ", subclass: " << this->subclass_->getName() << ", (?): " << event.originator_->isA(this->subclass_) << "." << std::endl;
     62       
    6163        // check if the originator is an instance of the requested class
    6264        if (event.originator_->isA(this->subclass_))
    6365        {
     66            // If the EventState doesn't act as an EventSink.
    6467            // actualize the activationcounter
    65             if (event.activate_)
    66                 ++this->activeEvents_;
    67             else
     68            if(!this->bSink_)
    6869            {
    69                 --this->activeEvents_;
     70                if (event.activate_)
     71                    ++this->activeEvents_;
     72                else
     73                {
     74                    --this->activeEvents_;
    7075
    71                 if (this->activeEvents_ < 0)
    72                     this->activeEvents_ = 0;
     76                    if (this->activeEvents_ < 0)
     77                        this->activeEvents_ = 0;
     78                }
    7379            }
    7480
     
    7884                (*this->statefunction_)();
    7985            }
    80             else if ((this->activeEvents_ == 1 && event.activate_) || (this->activeEvents_ == 0 && !event.activate_))
     86            else if (this->bSink_ || (!this->bSink_ && ((this->activeEvents_ == 1 && event.activate_) || (this->activeEvents_ == 0 && !event.activate_)) ) )
    8187            {
    8288                // 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]
     
    8490                {
    8591                    // one argument: just the eventstate
    86                     (*this->statefunction_)(this->activeEvents_);
     92                    (*this->statefunction_)(event.activate_);
    8793                }
    8894                else if (this->statefunction_->getParamCount() >= 2)
     
    9298                    {
    9399                        // if the subclass is BaseObject, we don't have to cast the pointer
    94                         (*this->statefunction_)(this->activeEvents_, event.originator_);
     100                        (*this->statefunction_)(event.activate_, event.originator_);
    95101                    }
    96102                    else
     
    98104                        // else cast the pointer to the desired class
    99105                        void* castedOriginator = event.originator_->getDerivedPointer(this->subclass_->getClassID());
    100                         (*this->statefunction_)(this->activeEvents_, castedOriginator);
     106                        (*this->statefunction_)(event.activate_, castedOriginator);
    101107                    }
    102108                }
  • code/trunk/src/libraries/core/Event.h

    r6417 r6800  
    4646        BaseObject* originator_; //!< The object which triggered this event
    4747        std::string name_;       //!< The name of this event
     48
    4849    };
    4950
     
    6667    {
    6768        public:
    68             EventState(Functor* statefunction, Identifier* subclass) : bProcessingEvent_(false), activeEvents_(0), statefunction_(statefunction), subclass_(subclass) {}
     69            EventState(Functor* statefunction, Identifier* subclass, bool bSink = false) : bProcessingEvent_(false), activeEvents_(0), statefunction_(statefunction), subclass_(subclass), bSink_(bSink) {}
    6970            virtual ~EventState();
    7071
     
    7980            Functor*    statefunction_;     //!< A functor to set the state
    8081            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)
     82            bool        bSink_;             //!< Determines whether the EventState acts as an EventSink forwarding any Event (even if the state didn't change) or in the normal manner, only processing Events that change the state.
    8183    };
    8284}
  • code/trunk/src/libraries/core/EventIncludes.h

    r6417 r6800  
    5252    } \
    5353    XMLPortEventStateIntern(xmlportevent##function, classname, statename, xmlelement, mode)
     54   
     55#define XMLPortEventSink(classname, subclassname, statename, function, xmlelement, mode) \
     56    orxonox::EventState* containername##function = this->getEventState(statename); \
     57    if (!containername##function) \
     58    { \
     59        containername##function = new orxonox::EventState(orxonox::createFunctor(&classname::function, this), orxonox::ClassIdentifier<subclassname>::getIdentifier(), true); \
     60        this->addEventState(statename, containername##function); \
     61    } \
     62    XMLPortEventStateIntern(xmlportevent##function, classname, statename, xmlelement, mode)
    5463
    5564/**
    56     @brief Like XMLPortEventState but with additional template arguments to identify the function of the state (if ambiguous).
     65    @brief Like XMLPortEventState but creates an event sink instead of an event state.
     66           The most important destinction between an EventState and an EventSink is, that an EventState only processes event which change the state of the EventState, where as an EventSink is an EventState that processes any Event that reaches it.
    5767*/
    5868#define XMLPortEventStateTemplate(classname, subclassname, statename, function, xmlelement, mode, ...) \
  • code/trunk/src/modules/objects/ObjectsPrereqs.h

    r5929 r6800  
    8585    // triggers
    8686    class CheckPoint;
     87    class DistanceMultiTrigger;
    8788    class DistanceTrigger;
    8889    class EventTrigger;
     90    class MultiTrigger;
     91    class MultiTriggerContainer;
    8992    class Trigger;
    9093}
  • code/trunk/src/modules/objects/eventsystem/EventListener.cc

    r6417 r6800  
    6161            return;
    6262        }
     63       
     64        COUT(4) << "EventListener: Processing event: originator: " << event.originator_->getIdentifier()->getName() << " (&" << event.originator_ << ")" << ", activate: " << event.activate_ << ", name: " << event.name_ << std::endl;
    6365
    6466        this->bActive_ = true;
  • code/trunk/src/modules/objects/triggers/CMakeLists.txt

    r5781 r6800  
    11ADD_SOURCE_FILES(OBJECTS_SRC_FILES
    2   Trigger.cc
     2  CheckPoint.cc
     3  DistanceMultiTrigger.cc
    34  DistanceTrigger.cc
    45  EventTrigger.cc
    5   CheckPoint.cc
     6  MultiTrigger.cc
     7  MultiTriggerContainer.cc
     8  Trigger.cc
    69)
  • code/trunk/src/modules/questsystem/CMakeLists.txt

    r5781 r6800  
    3434  LINK_LIBRARIES
    3535    orxonox
     36    objects
    3637    overlays
    3738  SOURCE_FILES ${QUESTSYSTEM_SRC_FILES}
  • code/trunk/src/modules/questsystem/QuestEffectBeacon.cc

    r5938 r6800  
    3939#include "worldentities/pawns/Pawn.h"
    4040#include "interfaces/PlayerTrigger.h"
     41#include "objects/triggers/MultiTriggerContainer.h"
    4142#include "QuestEffect.h"
    4243
     
    7576        XMLPortObject(QuestEffectBeacon, QuestEffect, "effects", addEffect, getEffect, xmlelement, mode);
    7677
    77         XMLPortEventState(QuestEffectBeacon, PlayerTrigger, "execute", execute, xmlelement, mode);
     78        XMLPortEventState(QuestEffectBeacon, BaseObject, "execute", execute, xmlelement, mode); //TODO: Change BaseObject to MultiTrigger as soon as MultiTrigger is the base of all triggers.
    7879
    7980        COUT(3) << "New QuestEffectBeacon created." << std::endl;
     
    8485        SUPER(QuestEffectBeacon, XMLEventPort, xmlelement, mode);
    8586
    86         XMLPortEventState(QuestEffectBeacon, PlayerTrigger, "execute", execute, xmlelement, mode);
     87        XMLPortEventSink(QuestEffectBeacon, BaseObject, "execute", execute, xmlelement, mode);
    8788    }
    8889
     
    9293        This means extracting the Pawn from the PlayerTrigger, provided by the Event causing the execution, and the extracting the PlayerInfo from the received Pawn and invoking the QuestEffectbeacon's QuestEffects on the received PlayerInfo.
    9394    @param trigger
    94         Apointer to the PlayerTrigger that threw the Event.
     95        A pointer to the PlayerTrigger that threw the Event.
    9596    @return
    9697        Returns true if successfully executed, false if not.
    9798    */
    98     bool QuestEffectBeacon::execute(bool b, PlayerTrigger* trigger)
    99     {
     99    bool QuestEffectBeacon::execute(bool b, BaseObject* trigger)
     100    {
     101        //TODO: Remove debug output.
     102        COUT(1) << "Debug: Calling execute on QuestEffectBeacon." << std::endl;
     103       
    100104        if(!b)
    101105        {
     
    108112        }
    109113
    110         if(!trigger->isForPlayer()) //!< The PlayerTrigger is not exclusively for Pawns which means we cannot extract one.
    111         {
    112             return false;
    113         }
    114 
    115         //! Extracting the Pawn from the PlayerTrigger.
    116         Pawn* pawn = trigger->getTriggeringPlayer();
     114        PlayerTrigger* pTrigger = orxonox_cast<PlayerTrigger*>(trigger);
     115        MultiTriggerContainer* mTrigger = orxonox_cast<MultiTriggerContainer*>(trigger);
     116        Pawn* pawn = NULL;
     117       
     118        //! If the trigger is neither a Playertrigger nor a MultiTrigger (i.e. a MultitriggerContainer) we can do anything with it.
     119        if(pTrigger == NULL && mTrigger == NULL)
     120            return false;
     121       
     122        // If the trigger is a PlayerTrigger.       
     123        if(pTrigger != NULL)
     124        {
     125            if(!pTrigger->isForPlayer())  //!< The PlayerTrigger is not exclusively for Pawns which means we cannot extract one.
     126                return false;
     127            else
     128                pawn = pTrigger->getTriggeringPlayer();
     129        }
     130       
     131        // If the trigger is a MultiTrigger (i.e. a MultiTriggerContainer)
     132        if(mTrigger != NULL)
     133        {
     134            pawn = orxonox_cast<Pawn*>(mTrigger->getData());
     135        }
    117136
    118137        if(pawn == NULL)
  • code/trunk/src/modules/questsystem/QuestEffectBeacon.h

    r5938 r6800  
    8888            virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
    8989
    90             bool execute(bool b, PlayerTrigger* trigger); //!< Executes the QuestEffects of the QuestEffectBeacon.
     90            bool execute(bool b, BaseObject* trigger); //!< Executes the QuestEffects of the QuestEffectBeacon.
    9191
    9292            /**
Note: See TracChangeset for help on using the changeset viewer.