Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/objects/triggers/MultiTrigger.h @ 11185

Last change on this file since 11185 was 11071, checked in by landauf, 9 years ago

merged branch cpp11_v3 back to trunk

  • Property svn:eol-style set to native
File size: 12.6 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Damian 'Mozork' Frick
24 *   Co-authors:
25 *      ...
26 *
27*/
28
29/**
30    @file MultiTrigger.h
31    @brief Definition of the MultiTrigger class.
32    @ingroup MultiTrigger
33*/
34
35#ifndef _MultiTrigger_H__
36#define _MultiTrigger_H__
37
38#include "objects/ObjectsPrereqs.h"
39
40#include "core/BaseObject.h"
41#include "core/ClassTreeMask.h"
42
43#include <set>
44#include <deque>
45
46#include "TriggerBase.h"
47
48namespace orxonox
49{
50
51    /**
52    @brief
53    Struct to handle @ref orxonox::MultiTrigger "MultiTrigger" states internally.
54
55    @ingroup MultiTrigger
56    */
57    struct MultiTriggerState
58    {
59        BaseObject* originator;
60        bool bTriggered;
61    };
62
63    /**
64    @brief
65        The MultiTrigger class implements a trigger that has a distinct state for each object triggering it.
66        In more detail: A Trigger is an object that can either be <em>active</em> or <em>inactive</em>, with a specified behavior how to switch between the two. A MultiTrigger generalizes that behavior for multiple objects triggering the trigger. A MultiTrigger can be <em>active</em> or <em>inactive</em> for any object triggering it, with the state for each object being completely independent of the state for other objects. Each time a switch occurs an @ref orxonox::Event "Event" is fired with as the originator a @ref orxonox::MultiTriggerContainer "MultiTriggerContainer", containing a pointer to the MultiTrigger that caused the @ref orxonox::Event "Event" and a pointer to the object that caused the trigger to change it's activity.
67
68        MultiTriggers also allow for additional complexity which can be added through the choice of the parameters explained (briefly) below:
69        But first you must understand a small implementation detail. There is a distinction between the MultiTrigger being triggered (there is the state <em>triggered</em> for that) and the MultiTrigger being active (for that is the state <em>activity</em>). From the outside only the <em>activity</em> is visible. The state <em>triggered</em> tells us whether the trigger is actually triggered, but it could pretend (for some reason, some of which we will see shortly) to be <em>active</em>, while it in fact isn't. The standard behavior is, that the <em>activity</em> changes, when the MultiTrigger transits from being <em>triggered</em> to being <em>not triggered</em> or the other way around.
70        The parameters are:
71        - @b delay The delay is the time that the trigger waits until it reacts (i.e. changes it's state) to the triggering condition being fulfilled.
72        - @b switch Switch is a boolean, if true the MultiTrigger is in <em>switch-mode</em>, meaning, that the <em>activity</em> changes only when the trigger is triggered, this means, that now the <em>activity</em> only changes, when the trigger changes from not being triggered to being triggered but not the other way around. The default is <code>false</code>.
73        - @b stayactive Stay active is also a boolean, if true the MultiTrigger stays active after it has been activated as many times as specified by the parameter <em>activations</em>. The default is <code>false</code>.
74        - @b activations The number of times the MultiTrigger can be activated until the trigger can't be triggered anymore. The default is <code>-1</code>, which denotes infinity.
75        - @b invert Invert is a boolean, if true the MultiTrigger is in <em>invert-mode</em>, meaning, that if the triggering condition is fulfilled the MultiTrigger will have the state <em>not triggered</em> and and if the condition is not fulfilled it will have the state <em>triggered</em>. In short it just inverts the behavior of the MultiTrigger. The default is <code>false</code>.
76        - @b simultaneousTriggerers The number of simultaneous triggerers limits the number of objects that are allowed to trigger the MultiTrigger at the same time. Or more precisely, the number of distinct objects the MultiTrigger has <em>triggered</em> states for, at each point in time. The default is <code>-1</code>, which denotes infinity.
77        - @b mode The mode describes how the MultiTrigger acts in relation to all the triggers, that are appended to it. There are 3 modes: <em>and</em>, meaning that the MultiTrigger can only be triggered if all the appended triggers are active. <em>or</em>, meaning that the MultiTrigger can only triggered if at least one of the appended triggers is active. And <em>xor</em>, meaning that the MultiTrigger can only be triggered if one and only one appended trigger is active. Note, that I wrote <em>can only be active</em>, that implies, that there is an additional condition to the <em>activity</em> 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 <em>activity</em> of a MultiTrigger is still coupled to the object that triggered it. The default is <em>and</em>.
78        - @b broadcast Broadcast is a boolean, if true the MutliTrigger is in <em>broadcast-mode</em>, meaning, that all trigger events that are caused by no originator (originator is nullptr) are broadcast as having come from every possible originator, or more precisely as having come from all objects that are specified targets of this MultiTrigger. The default is false.
79        - @b target The target describes the kind of objects that are allowed to trigger this MultiTrigger. The default is @ref orxonox::Pawn "Pawn".
80        - Also there is the possibility of appending triggers (as long as they inherit from TriggerBase) to the MultiTrigger just by adding them as children in the XML description of your MultiTrigger.
81
82        An example of a MultiTrigger created through XML would look like this:
83        @code
84        <MultiTrigger position="0,0,0" delay="1.3" switch="true" stayactive="true" activations="7" invert="true" simultaneousTriggerers="2" mode="xor" broadcast="false" target="Pawn">
85            <TriggerBase />
86            ...
87            <TriggerBase />
88        </MultiTrigger>
89        @endcode
90
91    @author
92        Damian 'Mozork' Frick
93
94        Many concepts and loads of inspiration from the @ref orxonox::Trigger "Trigger" class by Benjamin Knecht.
95
96    @ingroup MultiTrigger
97    */
98    class _ObjectsExport MultiTrigger : public TriggerBase
99    {
100        public:
101            MultiTrigger(Context* context); //!< Constructor. Registers the objects and initializes default values.
102            virtual ~MultiTrigger(); //!< Destructor.
103
104            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a MultiTrigger object through XML.
105            virtual void tick(float dt); //!< A method that is executed each tick.
106
107            /**
108            @brief Check whether the MultiTrigger is active.
109            @return Returns if the MultiTrigger is active.
110            */
111            inline bool isActive(void) const
112                { return this->isActive(nullptr); }
113            bool isActive(BaseObject* triggerer = nullptr) const; //!< Check whether the MultiTrigger is active for a given object.
114
115            /**
116            @brief Set the number of objects that are allowed to simultaneously trigger this MultiTrigger.
117            @param triggerers The number of objects. -1 denotes infinitely many.
118            */
119            inline void setSimultaneousTriggerers(int triggerers)
120                { if(triggerers >= 0 || triggerers == TriggerBase::INF_s) this->maxNumSimultaneousTriggerers_ = triggerers; }
121            /**
122            @brief Get the number of objects that are allowed to simultaneously trigger this MultiTriggger.
123            @return Returns the number of objects. -1 denotes infinity.
124            */
125            inline int getSimultaneousTriggerers(void)
126                { return this->maxNumSimultaneousTriggerers_; }
127
128            /**
129            @brief Set the broadcast-mode of the MultiTrigger.
130            @param bBroadcast If true the MultiTrigger is set to broadcast;
131            */
132            inline void setBroadcast(bool bBroadcast)
133                { this->bBroadcast_ = bBroadcast; }
134            /**
135            @brief Get the broadcast-mode of the MultiTrigger.
136            @return Returns true if the MultiTrigger is set to broadcast.
137            */
138            inline bool getBroadcast(void)
139                { return this->bBroadcast_; }
140
141            /**
142            @brief Get whether the input object is a target of the MultiTrigger.
143            @param target A pointer to the object.
144            @return Returns true if the input object is a target, false if not.
145            */
146            inline bool isTarget(BaseObject* target)
147                { if(target == nullptr) return true; else return targetMask_.isIncluded(target->getIdentifier()); }
148               
149            void addTarget(const std::string& targets); //!< Add some target to the MultiTrigger.
150
151        protected:
152            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.
153
154            void changeTriggered(BaseObject* originator = nullptr); //!< This method can be called by any class inheriting from MultiTrigger to change it's triggered status for a specified originator.
155
156            bool isModeTriggered(BaseObject* triggerer = nullptr); //!< Checks whether the MultiTrigger is triggered concerning it's children.
157            bool isTriggered(BaseObject* triggerer = nullptr); //!< Get whether the MultiTrigger is triggered for a given object.
158
159            virtual void fire(bool status, BaseObject* originator = nullptr);  //!< Helper method. Creates an Event for the given status and originator and fires it.
160            void broadcast(bool status); //!< Helper method. Broadcasts an Event for every object that is a target.
161
162            void removeTarget(const std::string& target); //!< Remove some target from the MultiTrigger.
163
164            /**
165            @brief Get the target mask used to identify the targets of this MultiTrigger.
166            @return Returns the target mask.
167            */
168            inline ClassTreeMask& getTargetMask(void)
169                { return this->targetMask_; }
170
171        private:
172            void childActivityChanged(BaseObject* originator); //!< This method is called by any child to advertise changes in it's state to it's parent.
173
174            bool addState(MultiTriggerState* state); //!< Helper method. Adds a state to the state queue, where the state will wait to become active.
175
176            bool checkAnd(BaseObject* triggerer); //!< Checks whether the children amount to true for the <em>and</em> mode for a given object.
177            bool checkOr(BaseObject* triggerer); //!< Checks whether the children amount to true for the <em>or</em> mode for a given object.
178            bool checkXor(BaseObject* triggerer); //!< Checks whether the children amount to true for the <em>xor</em> mode for a given object.
179
180            /**
181            @brief Get the objects for which this MultiTrigger is active.
182            @return Returns a set with all the object this MultiTrigger is active for.
183            */
184            std::set<BaseObject*>& getActive(void)
185                { return this->active_; }
186
187            int maxNumSimultaneousTriggerers_; //!< The maximum number of objects simultaneously trigggering this MultiTrigger.
188
189            bool bBroadcast_; //!< Bool for the broadcast-mode, if true all triggers go to all possible targets.
190
191            std::set<BaseObject*> active_; //!< The set of all objects the MultiTrigger is active for.
192            std::set<BaseObject*> triggered_; //!< The set of all objects the MultiTrigger is triggered for.
193
194            std::deque<std::pair<float, MultiTriggerState*>> stateQueue_; //!< The queue of states waiting to become active.
195
196            ClassTreeMask targetMask_; //!< The target mask, masking all objects that can trigger this MultiTrigger.
197
198    };
199
200}
201
202#endif // _MultiTrigger_H__
Note: See TracBrowser for help on using the repository browser.