[Orxonox-commit 2139] r6855 - code/trunk/src/modules/objects/triggers

dafrick at orxonox.net dafrick at orxonox.net
Tue May 4 21:55:00 CEST 2010


Author: dafrick
Date: 2010-05-04 21:54:59 +0200 (Tue, 04 May 2010)
New Revision: 6855

Modified:
   code/trunk/src/modules/objects/triggers/MultiTrigger.cc
   code/trunk/src/modules/objects/triggers/MultiTrigger.h
Log:
Done documenting MultiTrigger. Also some simplification and resilience improvement on the code done.


Modified: code/trunk/src/modules/objects/triggers/MultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/MultiTrigger.cc	2010-05-04 09:12:54 UTC (rev 6854)
+++ code/trunk/src/modules/objects/triggers/MultiTrigger.cc	2010-05-04 19:54:59 UTC (rev 6855)
@@ -26,6 +26,11 @@
  *
 */
 
+/**
+    @file MultiTrigger.cc
+    @brief Implementation of the MultiTrigger class.
+*/
+
 #include "MultiTrigger.h"
 
 #include "core/CoreIncludes.h"
@@ -38,8 +43,8 @@
 
     // Initialization of some static (magic) variables.
     /*static*/ const int MultiTrigger::INF_s = -1;
+    /*static*/ const std::string MultiTrigger::and_s = "and";
     /*static*/ const std::string MultiTrigger::or_s = "or";
-    /*static*/ const std::string MultiTrigger::and_s = "and";
     /*static*/ const std::string MultiTrigger::xor_s = "xor";
     
     CreateFactory(MultiTrigger);
@@ -50,26 +55,25 @@
     @param creator
         The creator.
     */
-    //TODO: Clean up.
     MultiTrigger::MultiTrigger(BaseObject* creator) : StaticEntity(creator)
     {
         RegisterObject(MultiTrigger);
 
         this->bFirstTick_ = true;
-        
-        this->mode_ = MultiTriggerMode::EventTriggerAND;
 
-        this->bInvertMode_ = false;
+        this->delay_ = 0.0f;
         this->bSwitch_ = false;
         this->bStayActive_ = false;
-        this->delay_ = 0.0f;
+        
         this->remainingActivations_ = INF_s;
         this->maxNumSimultaniousTriggerers_ = INF_s;
+
+        this->bInvertMode_ = false;
+        this->mode_ = MultiTriggerMode::EventTriggerAND;
         
         this->targetMask_.exclude(Class(BaseObject));
 
         this->setSyncMode(0x0);
-        
     }
     
     /**
@@ -85,20 +89,6 @@
             this->stateQueue_.pop_front();
             delete state;
         }
-
-        // Destroying the appended triggers
-        for(std::set<MultiTrigger*>::iterator it = this->children_.begin(); it != this->children_.end(); it++)
-        {
-            (*it)->destroy();
-        }
-        this->children_.clear();
-
-        // Telling everyone, that this trigger is gone.
-        for(std::set<BaseObject*>::iterator it = this->active_.begin(); it != this->active_.end(); it++)
-        {
-            this->fire(false, *it);
-        }
-        this->active_.clear();
     }
     
     /**
@@ -110,13 +100,13 @@
     {
         SUPER(MultiTrigger, XMLPort, xmlelement, mode);
 
-        XMLPortParam(MultiTrigger, "delay", setDelay, getDelay, xmlelement, mode).defaultValues(0.0f);
-        XMLPortParam(MultiTrigger, "switch", setSwitch, getSwitch, xmlelement, mode).defaultValues(false);
-        XMLPortParam(MultiTrigger, "stayactive", setStayActive, getStayActive, xmlelement, mode).defaultValues(false);
-        XMLPortParam(MultiTrigger, "activations", setActivations, getActivations, xmlelement, mode).defaultValues(INF_s);
-        XMLPortParam(MultiTrigger, "invert", setInvert, getInvert, xmlelement, mode).defaultValues(false);
-        XMLPortParam(MultiTrigger, "simultaniousTriggerers", setSimultaniousTriggerers, getSimultaniousTriggerers, xmlelement, mode).defaultValues(INF_s);
-        XMLPortParamTemplate(MultiTrigger, "mode", setMode, getModeString, xmlelement, mode, const std::string&).defaultValues(MultiTrigger::and_s);
+        XMLPortParam(MultiTrigger, "delay", setDelay, getDelay, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "switch", setSwitch, getSwitch, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "stayactive", setStayActive, getStayActive, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "activations", setActivations, getActivations, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "simultaniousTriggerers", setSimultaniousTriggerers, getSimultaniousTriggerers, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "invert", setInvert, getInvert, xmlelement, mode);
+        XMLPortParamTemplate(MultiTrigger, "mode", setMode, getModeString, xmlelement, mode, const std::string&);
         XMLPortParamLoadOnly(MultiTrigger, "target", addTargets, xmlelement, mode).defaultValues("ControllableEntity"); //TODO: Remove load only
 
         //TODO: Maybe nicer with explicit subgroup, e.g. triggers
@@ -154,7 +144,6 @@
         {
             while(queue->size() > 0)
             {
-                //TODO: Be more efficient, Don't delete a state and create a new one immediately after that. Reuse!
                 MultiTriggerState* state = queue->front();
                 // If the state is NULL. (This really shouldn't happen)
                 if(state == NULL)
@@ -170,15 +159,19 @@
                 // If the 'triggered' state has changed a new state is added to the state queue.
                 //TODO: Do something against flooding, when there is delay.
                 if(this->delay_ != 0.0f || bTriggered ^ this->isTriggered(state->originator))
-                    this->addState(bTriggered, state->originator);
+                {
+                    state->bTriggered = bTriggered;
+                    this->addState(state);
+                }
+                else
+                    delete state;
                 
                 queue->pop();
-                delete state;
             }
             delete queue;
         }
 
-        // Go through the state queue.
+        // Go through the state queue and activate all pending states whose remaining time has expired.
         if (this->stateQueue_.size() > 0)
         {
             MultiTriggerState* state;
@@ -214,14 +207,22 @@
                             bStateChanged = true;
                         }
 
+                        // Get the activity of the new state.
+                        bool bActive;
+                        // If the MultiTrigger is in switch mode.
+                        if(this->bSwitch_ && !state->bTriggered)
+                            bActive = this->isActive(state->originator);
+                        else
+                            bActive = !this->isActive(state->originator);
+
                         // If the activity is different from what it is now, change it and fire an Event.
-                        if(state->bActive ^ this->isActive(state->originator))
+                        if(bActive ^ this->isActive(state->originator))
                         {
 
                             bool bFire = true;
                             
                             // Add the originator to the objects activating this MultiTrigger.
-                            if(state->bActive == true)
+                            if(bActive == true)
                             {
                                 if(this->remainingActivations_ != 0)
                                 {
@@ -250,19 +251,20 @@
                             // Fire the Event if the activity has changed.
                             if(bFire)
                             {
-                                this->fire(state->bActive, state->originator);
+                                this->fire(bActive, state->originator);
                                 bStateChanged = true;
                             }
                         }
 
                         // 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: " << state->bActive << ", triggered: " << state->bTriggered << "." << std::endl;
+                            COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") changed state. originator: " << state->originator->getIdentifier()->getName() << " (&" << state->originator << "), active: " << bActive << ", triggered: " << state->bTriggered << "." << std::endl;
 
-                        // If the MultiTrigger has exceeded its amount of activations and it desn't stay active, it has to be destroyed,
-                        if(this->remainingActivations_ == 0 && bStateChanged && !state->bActive && !this->bStayActive_)
+                        // If the MultiTrigger has exceeded its amount of activations and it doesn't stay active, it has to be destroyed,
+                        if(this->remainingActivations_ == 0 && !bActive)
                         {
-                            this->destroy();
+                            this->BaseObject::setActive(false);
+                            COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") ran out of activations. Setting it to inactive." << std::endl;
                         }
                     }
                     
@@ -281,42 +283,149 @@
         }
     }
 
-    //TODO: Document
-    bool MultiTrigger::isModeTriggered(BaseObject* triggerer)
+    /**
+    @brief
+        Get whether the MultiTrigger is active for a given object.
+    @param triggerers
+        A pointer to the object.
+    @return
+        Returns true if the MultiTrigger is active, false if not.
+    */
+    bool MultiTrigger::isActive(BaseObject* triggerer)
     {
-        if (this->children_.size() != 0)
+        std::set<BaseObject*>::iterator it = this->active_.find(triggerer);
+        if(it == this->active_.end())
+            return false;
+        return true;
+    }
+
+    /**
+    @brief
+        Set the mode of the MultiTrigger.
+    @param modeName
+        The name of the mode as a string.
+    */
+    void MultiTrigger::setMode(const std::string& modeName)
+    {
+        if (modeName == MultiTrigger::and_s)
+            this->setMode(MultiTriggerMode::EventTriggerAND);
+        else if (modeName == MultiTrigger::or_s)
+            this->setMode(MultiTriggerMode::EventTriggerOR);
+        else if (modeName == MultiTrigger::xor_s)
+            this->setMode(MultiTriggerMode::EventTriggerXOR);
+    }
+
+    /**
+    @brief
+        Get the mode of the MultiTrigger.
+    @return
+        Returns the mode as a string.
+    */
+    const std::string& MultiTrigger::getModeString() const
+    {
+        if (this->mode_ == MultiTriggerMode::EventTriggerAND)
+            return MultiTrigger::and_s;
+        else if (this->mode_ == MultiTriggerMode::EventTriggerOR)
+            return MultiTrigger::or_s;
+        else if (this->mode_ == MultiTriggerMode::EventTriggerXOR)
+            return MultiTrigger::xor_s;
+        else
+            return MultiTrigger::and_s;
+    }
+
+    /**
+    @brief
+        Add some target to the MultiTrigger.
+    @param targetStr
+        The target as a string.
+    */
+    void MultiTrigger::addTargets(const std::string& targetStr)
+    {
+        Identifier* target = ClassByString(targetStr);
+
+        if (target == NULL)
         {
-            bool returnVal = false;
+            COUT(1) << "Error: \"" << targetStr << "\" is not a valid class name to include in ClassTreeMask (in " << this->getName() << ", class " << this->getIdentifier()->getName() << ')' << std::endl;
+            return;
+        }
 
-            switch (this->mode_)
-            {
-                case MultiTriggerMode::EventTriggerAND:
-                    returnVal = checkAnd(triggerer);
-                    break;
-                case MultiTriggerMode::EventTriggerOR:
-                    returnVal = checkOr(triggerer);
-                    break;
-                case MultiTriggerMode::EventTriggerXOR:
-                    returnVal = checkXor(triggerer);
-                    break;
-                default:
-                    returnVal = false;
-                    break;
-            }
+        this->targetMask_.include(target);
 
-            return returnVal;
-        }
-        
-        return true;
+        // A MultiTriggers shouldn't react to itself or other MultiTriggers.
+        this->targetMask_.exclude(Class(MultiTrigger), true);
+
+        // We only want WorldEntities
+        ClassTreeMask WEMask;
+        WEMask.include(Class(WorldEntity));
+        this->targetMask_ *= WEMask;
+
+        this->notifyMaskUpdate();
     }
-    
-    //TODO: Document
+
+    /**
+    @brief
+        Remove some target from the MultiTrigger.
+    @param targetStr
+        The target to be removed as a string.
+    */
+    void MultiTrigger::removeTargets(const std::string& targetStr)
+    {
+        Identifier* target = ClassByString(targetStr);
+        this->targetMask_.exclude(target);
+    }
+
+    /**
+    @brief
+        Adds a MultiTrigger as a sub-trigger to the trigger.
+        Beware: Loops are not prevented and potentially very bad, so just don't create any loops.
+    @param trigger
+        The trigger to be added.
+    */
+    void MultiTrigger::addTrigger(MultiTrigger* trigger)
+    {
+        if (this != trigger && trigger != NULL)
+            this->subTriggers_.insert(trigger);
+    }
+
+    /**
+    @brief
+        Get the sub-trigger of this MultiTrigger at the given index.
+    @param index
+        The index.
+    @return
+        Returns a pointer ot the MultiTrigger. NULL if no such trigger exists.
+    */
+    const MultiTrigger* MultiTrigger::getTrigger(unsigned int index) const
+    {
+        // If the index is greater than the number of sub-triggers.
+        if (this->subTriggers_.size() <= index)
+            return NULL;
+
+        std::set<MultiTrigger*>::const_iterator it;
+        it = this->subTriggers_.begin();
+
+        for (unsigned int i = 0; i != index; ++i)
+            ++it;
+
+        return (*it);
+    }
+
+    /**
+    @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.
+    */
     std::queue<MultiTriggerState*>* MultiTrigger::letTrigger(void)
     {
-        // Goes through all trigger children and gets the objects triggering them.
+        // Goes through all sub-triggers and gets the objects triggering them.
         std::set<BaseObject*>* triggerers = new std::set<BaseObject*>();
         std::set<BaseObject*>::iterator objIt;
-        for(std::set<MultiTrigger*>::iterator it = this->children_.begin(); it != this->children_.end(); it ++)
+        for(std::set<MultiTrigger*>::iterator it = this->subTriggers_.begin(); it != this->subTriggers_.end(); it ++)
         {
             std::set<BaseObject*> set = (*it)->getActive();
             for(objIt = set.begin(); objIt != set.end(); objIt++)
@@ -331,9 +440,11 @@
             triggerers->insert(*objIt);
         }
 
+        // If no objects are triggering this MultiTrigger or the sub-triggers.
         if(triggerers->size() == 0)
             return NULL;
-        
+
+        // Create a state for each object triggering this MultiTrigger or any of the sub-triggers and append it to the queue.
         std::queue<MultiTriggerState*>* queue = new std::queue<MultiTriggerState*>();
         MultiTriggerState* state = NULL;
         for(std::set<BaseObject*>::iterator it = triggerers->begin(); it != triggerers->end(); it++)
@@ -344,11 +455,55 @@
             queue->push(state);
         }
         delete triggerers;
-        
+
         return queue;
     }
+
+    /**
+    @brief
+        Checks whether the sub-triggers are in such a way that, according to the mode of the MultiTrigger, the MultiTrigger is triggered (only considering the sub-triggers, not the state of MultiTrigger itself), for a given object.
+        To make an example: When the mode is 'and', then this would be true or a given object if all the sub-triggers were triggered ofr the given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if the MultiTrigger is triggered concerning it's sub-triggers.
+    */
+    bool MultiTrigger::isModeTriggered(BaseObject* triggerer)
+    {
+        if (this->subTriggers_.size() != 0)
+        {
+            bool returnVal = false;
+
+            switch (this->mode_)
+            {
+                case MultiTriggerMode::EventTriggerAND:
+                    returnVal = checkAnd(triggerer);
+                    break;
+                case MultiTriggerMode::EventTriggerOR:
+                    returnVal = checkOr(triggerer);
+                    break;
+                case MultiTriggerMode::EventTriggerXOR:
+                    returnVal = checkXor(triggerer);
+                    break;
+                default:
+                    returnVal = false;
+                    break;
+            }
+
+            return returnVal;
+        }
+        
+        return true;
+    }
     
-    //TODO: Document
+    /**
+    @brief
+        Get whether the MultiTrigger is triggered for a given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if the MultiTrigger is triggered for the given object.
+    */
     bool MultiTrigger::isTriggered(BaseObject* triggerer)
     {
         std::set<BaseObject*>::iterator it = this->triggered_.find(triggerer);
@@ -357,11 +512,62 @@
         return true;
     }
 
-    //TODO: Document
+    /**
+    @brief
+        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.
+    @param originator
+        The object that triggered the MultiTrigger to fire this Event.
+    */
+    void MultiTrigger::fire(bool status, BaseObject* originator)
+    {
+        // If the originator is NULL, a normal event without MultiTriggerContainer is sent.
+        if(originator == NULL)
+        {
+            this->fireEvent(status);
+            return;
+        }
+        
+        MultiTriggerContainer* container = new MultiTriggerContainer(this, this, originator);
+        this->fireEvent(status, container);
+        COUT(4) << "MultiTrigger '" <<  this->getName() << "' (&" << this << "): Fired event. originator: " << originator->getIdentifier()->getName() << " (&" << originator << "), status: " << status << "." << std::endl;
+        delete container;
+    }
+
+    /**
+    @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.
+    */
+    bool MultiTrigger::addState(MultiTriggerState* state)
+    {
+        assert(state);
+        
+        // If the originator is no target of this MultiTrigger.
+        if(!this->isTarget(state->originator))
+            return false;
+        
+        // Add it ot the state queue.
+        this->stateQueue_.push_back(std::pair<float, MultiTriggerState*>(this->delay_, state));
+
+        return true;
+    }
+
+    /**
+    @brief
+        Checks whether the sub-triggers amount to true for the 'and' mode for a given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if they do.
+    */
     bool MultiTrigger::checkAnd(BaseObject* triggerer)
     {
         std::set<MultiTrigger*>::iterator it;
-        for(it = this->children_.begin(); it != this->children_.end(); ++it)
+        for(it = this->subTriggers_.begin(); it != this->subTriggers_.end(); ++it)
         {
             if (!(*it)->isActive(triggerer))
                 return false;
@@ -369,11 +575,18 @@
         return true;
     }
 
-    //TODO: Document
+    /**
+    @brief
+        Checks whether the sub-triggers amount to true for the 'or' mode for a given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if they do.
+    */
     bool MultiTrigger::checkOr(BaseObject* triggerer)
     {
         std::set<MultiTrigger*>::iterator it;
-        for(it = this->children_.begin(); it != this->children_.end(); ++it)
+        for(it = this->subTriggers_.begin(); it != this->subTriggers_.end(); ++it)
         {
             if ((*it)->isActive(triggerer))
                 return true;
@@ -381,12 +594,19 @@
         return false;
     }
 
-    //TODO: Document
+    /**
+    @brief
+        Checks whether the sub-triggers amount to true for the 'xor' mode for a given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if they do.
+    */
     bool MultiTrigger::checkXor(BaseObject* triggerer)
     {
         std::set<MultiTrigger*>::iterator it;
         bool test = false;
-        for(it = this->children_.begin(); it != this->children_.end(); ++it)
+        for(it = this->subTriggers_.begin(); it != this->subTriggers_.end(); ++it)
         {
             if (test && (*it)->isActive(triggerer))
                 return false;
@@ -395,133 +615,5 @@
         }
         return test;
     }
-    
-    //TODO: Document
-    bool MultiTrigger::addState(bool bTriggered, BaseObject* originator)
-    {
-        if(!this->isTarget(originator))
-            return false;
-        
-        // If the state doesn't change.
-        if(this->isTriggered() && bTriggered)
-            return false;
-        
-        bool bActive = !this->isActive(originator);
-        
-        // If the MultiTrigger is in switch mode.
-        if(this->bSwitch_ && !bTriggered)
-        {
-            bActive = this->isActive(originator);
-        }
-        
-        // Create state.
-        MultiTriggerState* state = new MultiTriggerState;
-        state->bActive = bActive;
-        state->bTriggered = bTriggered;
-        state->originator = originator;
-        this->stateQueue_.push_back(std::pair<float, MultiTriggerState*>(this->delay_, state));
-        
-        return true;
-    }
 
-    //TODO: Document
-    void MultiTrigger::setMode(const std::string& modeName)
-    {
-        if (modeName == MultiTrigger::and_s)
-            this->setMode(MultiTriggerMode::EventTriggerAND);
-        else if (modeName == MultiTrigger::or_s)
-            this->setMode(MultiTriggerMode::EventTriggerOR);
-        else if (modeName == MultiTrigger::xor_s)
-            this->setMode(MultiTriggerMode::EventTriggerXOR);
-    }
-
-    //TODO: Document
-    const std::string& MultiTrigger::getModeString() const
-    {
-        if (this->mode_ == MultiTriggerMode::EventTriggerAND)
-            return MultiTrigger::and_s;
-        else if (this->mode_ == MultiTriggerMode::EventTriggerOR)
-            return MultiTrigger::or_s;
-        else if (this->mode_ == MultiTriggerMode::EventTriggerXOR)
-            return MultiTrigger::xor_s;
-        else
-            return MultiTrigger::and_s;
-    }
-    
-    //TODO: Document
-    bool MultiTrigger::isActive(BaseObject* triggerer)
-    {
-        std::set<BaseObject*>::iterator it = this->active_.find(triggerer);
-        if(it == this->active_.end())
-            return false;
-        return true;
-    }
-
-    //TODO: Document
-    void MultiTrigger::addTrigger(MultiTrigger* trigger)
-    {
-        if (this != trigger && trigger != NULL)
-            this->children_.insert(trigger);
-    }
-
-    //TODO: Document
-    const MultiTrigger* MultiTrigger::getTrigger(unsigned int index) const
-    {
-        if (this->children_.size() <= index)
-            return NULL;
-
-        std::set<MultiTrigger*>::const_iterator it;
-        it = this->children_.begin();
-
-        for (unsigned int i = 0; i != index; ++i)
-            ++it;
-
-        return (*it);
-    }
-    
-    //TODO: Document
-    void MultiTrigger::fire(bool status, BaseObject* originator)
-    {
-        if(originator == NULL)
-        {
-            this->fireEvent(status);
-            return;
-        }
-        MultiTriggerContainer* container = new MultiTriggerContainer(this, this, originator);
-        this->fireEvent(status, container);
-        COUT(4) << "MultiTrigger &" << this << ": Fired event. originator: " << originator->getIdentifier()->getName() << " (&" << originator << "), status: " << status << "." << std::endl;
-        delete container;
-    }
-    
-    //TODO: Document
-    void MultiTrigger::addTargets(const std::string& targets)
-    {
-        Identifier* target = ClassByString(targets);
-
-        if (target == NULL)
-        {
-            COUT(1) << "Error: \"" << targets << "\" is not a valid class name to include in ClassTreeMask (in " << this->getName() << ", class " << this->getIdentifier()->getName() << ')' << std::endl;
-            return;
-        }
-
-        this->targetMask_.include(target);
-
-        // trigger shouldn't react on itself or other triggers
-        this->targetMask_.exclude(Class(MultiTrigger), true);
-
-        // we only want WorldEntities
-        ClassTreeMask WEMask;
-        WEMask.include(Class(WorldEntity));
-        this->targetMask_ *= WEMask;
-
-        this->notifyMaskUpdate();
-    }
-
-    //TODO: Document
-    void MultiTrigger::removeTargets(const std::string& targets)
-    {
-        Identifier* target = ClassByString(targets);
-        this->targetMask_.exclude(target);
-    }
-    
 }

Modified: code/trunk/src/modules/objects/triggers/MultiTrigger.h
===================================================================
--- code/trunk/src/modules/objects/triggers/MultiTrigger.h	2010-05-04 09:12:54 UTC (rev 6854)
+++ code/trunk/src/modules/objects/triggers/MultiTrigger.h	2010-05-04 19:54:59 UTC (rev 6855)
@@ -26,6 +26,11 @@
  *
 */
 
+/**
+    @file MultiTrigger.h
+    @brief Definition of the MultiTrigger class.
+*/
+
 #ifndef _MultiTrigger_H__
 #define _MultiTrigger_H__
 
@@ -58,7 +63,6 @@
     struct MultiTriggerState
     {
         BaseObject* originator;
-        bool bActive;
         bool bTriggered;
     };
 
@@ -92,97 +96,175 @@
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a MultiTrigger object through XML.
             virtual void tick(float dt); //!< A method that is executed each tick.
             
-            bool isActive(BaseObject* triggerer = NULL);
-            void addTrigger(MultiTrigger* trigger);
-            const MultiTrigger* getTrigger(unsigned int index) const;
-            
-            void addTargets(const std::string& targets);
-            void removeTargets(const std::string& targets);
-            inline bool isTarget(BaseObject* target)
-                { return targetMask_.isIncluded(target->getIdentifier()); }
-            
-            void setMode(const std::string& modeName);
-            const std::string& getModeString(void) const;
-            inline void setMode(MultiTriggerMode::Value mode)
-                { this->mode_ = mode; }
-            inline MultiTriggerMode::Value getMode() const
-                { return mode_; }
+            bool isActive(BaseObject* triggerer = NULL); //!< Get whether the MultiTrigger is active for a given object.
 
-            inline void setInvert(bool bInvert)
-                { this->bInvertMode_ = bInvert; }
-            inline bool getInvert() const
-                { return this->bInvertMode_; }
+            /**
+            @brief Set the delay of the MultiTrigger.
+            @param delay The delay to be set.
+            */
+            inline void setDelay(float delay)
+                { if(delay > 0) this->delay_= delay; }
+            /**
+            @brief Get the delay of the MultiTrigger.
+            @return The delay.
+            */
+            inline float getDelay() const
+                { return this->delay_; }
 
+            /**
+            @brief Set switch-mode of the MultiTrigger.
+            @param bSwitch If true the MultiTrigger is set to switched.
+            */
             inline void setSwitch(bool bSwitch)
                 { this->bSwitch_ = bSwitch; }
+            /**
+            @brief Get the switch-mode of the MultiTrigger.
+            @return Returns true if the MultiTriger is in switch-mode.
+            */
             inline bool getSwitch() const
                 { return this->bSwitch_; }
 
+            /**
+            @brief Set the stay-active-mode of the MultiTrigger.
+            @param bStayActive If true the MultiTrigger is set to stay active.
+            */
             inline void setStayActive(bool bStayActive)
                 { this->bStayActive_ = bStayActive; }
+            /**
+            @brief Get the stay-active-mode of the MultiTrigger.
+            @return Returns true if the MultiTrigger stays active.
+            */
             inline bool getStayActive() const
                 { return this->bStayActive_; }
 
+            /**
+            @brief Set the number of activations the MultiTrigger can go through.
+            @param activations The number of activations. -1 denotes infinitely many activations.
+            */
             inline void setActivations(int activations)
-                { this->remainingActivations_ = activations; }
+                { if(activations >= 0 || activations == INF_s) this->remainingActivations_ = activations; }
+            /**
+            @brief Get the number of remaining activations of the MultiTrigger.
+            @return The number of activations. -1 denotes infinity.
+            */
             inline int getActivations() const
                 { return this->remainingActivations_; }
-                
+
+            /**
+            @brief Set the number of objects that are allowed to simultaniously trigger this MultiTrigger.
+            @param triggerers The number of objects. -1 denotes infinitely many.
+            */
             inline void setSimultaniousTriggerers(int triggerers)
-                { this->maxNumSimultaniousTriggerers_ = triggerers; }
+                { if(triggerers >= 0 || triggerers == INF_s) this->maxNumSimultaniousTriggerers_ = triggerers; }
+            /**
+            @brief Get the number of objects that are allowed to simultaniously trigger this MultiTriggger.
+            @return Returns the number of objects. -1 denotes infinity.
+            */
             inline int getSimultaniousTriggerers(void)
                 { return this->maxNumSimultaniousTriggerers_; }
 
-            inline void setDelay(float delay)
-                { this->delay_= delay; }
-            inline float getDelay() const
-                { return this->delay_; }
+            /**
+            @brief Set the invert-mode of the MultiTrigger.
+            @param bInvert If true the MultiTrigger is set to invert.
+            */
+            inline void setInvert(bool bInvert)
+                { this->bInvertMode_ = bInvert; }
+            /**
+            @brief Get the invert-mode of the MultiTrigger.
+            @return Returns true if the MultiTrigger is set to invert.
+            */
+            inline bool getInvert() const
+                { return this->bInvertMode_; }
+
+            void setMode(const std::string& modeName); //!< Set the mode of the MultiTrigger.
+            /**
+            @brief Set the mode of the MultiTrigger.
+            @param mode The mode of the MultiTrigger.
+            */
+            inline void setMode(MultiTriggerMode::Value mode) //!< Get the mode of the MultiTrigger.
+                { this->mode_ = mode; }
+            const std::string& getModeString(void) const;
+            /**
+            @brief Get the mode of the MultiTrigger.
+            @return Returns and Enum for the mode of the MultiTrigger.
+            */
+            inline MultiTriggerMode::Value getMode() const
+                { return mode_; }
+
+            /**
+            @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()); }
+            void addTargets(const std::string& targets); //!< Add some target to the MultiTrigger.
+            void removeTargets(const std::string& targets); //!< Remove some target from the MultiTrigger.
             
+            void addTrigger(MultiTrigger* trigger); //!< Adds a MultiTrigger as a sub-trigger to the trigger.
+            const MultiTrigger* getTrigger(unsigned int index) const; //!< Get the sub-trigger of this MultiTrigger at the given index.
+            
         protected:
-            void fire(bool status, BaseObject* originator = NULL);
+            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.
             
-            bool isModeTriggered(BaseObject* triggerer = NULL);
-            bool isTriggered(BaseObject* triggerer = NULL);
-            
-            virtual std::queue<MultiTriggerState*>* letTrigger(void);
-            
+            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.
+
+            /**
+            @brief Get the target mask used to identify the targets of this MultiTrigger.
+            @return Returns the target mask.
+            */
             inline ClassTreeMask& getTargetMask(void)
                 { return this->targetMask_; }
+            /**
+            @brief Is called, when the target mask changes.
+            */
+            //TODO: Check if something mus be done here.
             virtual void notifyMaskUpdate(void) {}
             
         private:
-            static const int INF_s;
+            static const int INF_s; //!< Magic number for infinity.
+            //! Magic strings for the mode.
+            static const std::string and_s;
             static const std::string or_s;
-            static const std::string and_s;
             static const std::string xor_s;
             
-            bool addState(bool bTriggered, BaseObject* originator = NULL);
+            bool addState(MultiTriggerState* state); //!< Helper method. Adds a state to the state queue, where the state will wait to become active.
             
-            bool checkAnd(BaseObject* triggerer);
-            bool checkOr(BaseObject* triggerer);
-            bool checkXor(BaseObject* triggerer);
+            bool checkAnd(BaseObject* triggerer); //!< Checks whether the sub-triggers amount to true for the 'and' mode for a given object.
+            bool checkOr(BaseObject* triggerer); //!< Checks whether the sub-triggers amount to true for the 'or' mode for a given object.
+            bool checkXor(BaseObject* triggerer); //!< Checks whether the sub-triggers amount to true for the 'xor' mode for a given object.
 
+            /**
+            @brief Get the objects for which this MultiTrigger is active.
+            @return Returns a set with all the object this MultiTrigger is active for.
+            */
             std::set<BaseObject*>& getActive(void)
                 { return this->active_; }
 
-            bool bFirstTick_;
+            bool bFirstTick_; //!< Bool to distinguish the first tick form all the following.
 
-            MultiTriggerMode::Value mode_;
-            bool bInvertMode_;
-            bool bSwitch_;
-            bool bStayActive_;
-            float delay_;
-            int remainingActivations_;
-            int maxNumSimultaniousTriggerers_;
+            float delay_; //!< The delay that is imposed on all new trigger events.
+            bool bSwitch_; //!< Bool for the switch-mode, if true the MultiTrigger behaves like a switch.
+            bool bStayActive_; //!< Bool for the stay-active-mode, if true the MultiTrigger stays active after its last activation.;
             
-            std::set<BaseObject*> active_;
-            std::set<BaseObject*> triggered_;
+            int remainingActivations_; //!< The remaining activations of this MultiTrigger.
+            int maxNumSimultaniousTriggerers_; //!< The maximum number of objects simultaniously trigggering this MultiTrigger.
 
-            std::set<MultiTrigger*> children_;
-            std::deque<std::pair<float, MultiTriggerState*> > stateQueue_;
+            bool bInvertMode_; //!< Bool for the invert-mode, if true the MultiTrigger is inverted.
+            MultiTriggerMode::Value mode_; //!< The mode of the MultiTrigger.
+
+            std::set<MultiTrigger*> subTriggers_; //!< The sub-triggers of this MultiTrigger.
             
-            ClassTreeMask targetMask_;
+            std::set<BaseObject*> active_; //!< The set of all objects the MultiTrigger is active for.
+            std::set<BaseObject*> triggered_; //!< The set of all objects the MultiTrigger is triggered for.
+
+            std::deque< std::pair<float, MultiTriggerState*> > stateQueue_; //!< The queue of states waiting to become active.
             
+            ClassTreeMask targetMask_; //!< The target mask, masking all objects that can trigger this MultiTrigger.
+            
     };
 
 }




More information about the Orxonox-commit mailing list