]> git.mxchange.org Git - simgear.git/blob - simgear/structure/StateMachine.hxx
Improve (mostly Canvas event related) documentation.
[simgear.git] / simgear / structure / StateMachine.hxx
1 /* -*-c++-*-
2  *
3  * Copyright (C) 2013 James Turner
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef SIMGEAR_STATE_MACHINE_H
23 #define SIMGEAR_STATE_MACHINE_H
24
25 #include <memory>
26 #include <string>
27
28 #include <simgear/structure/SGReferenced.hxx>
29 #include <simgear/structure/SGSharedPtr.hxx>
30      
31 // forward decls
32 class SGPropertyNode;
33 class SGBinding;
34 class SGCondition;
35
36 namespace simgear
37 {
38
39 class StateMachine : public SGReferenced
40 {
41 public:
42     StateMachine();
43     virtual ~StateMachine();
44     
45     class State : public SGReferenced
46     {
47     public:    
48         virtual ~State();
49         
50         std::string name() const;
51         
52         void addUpdateBinding(SGBinding* aBinding);
53         void addEntryBinding(SGBinding* aBinding);
54         void addExitBinding(SGBinding* aBinding);
55         
56     private:  
57         friend class StateMachine;
58         
59         State(const std::string& name);
60         
61         void fireExitBindings();
62         void fireEntryBindings();
63         
64         void update();
65         
66         class StatePrivate;
67         std::auto_ptr<StatePrivate> d;
68     };
69     
70     class Transition : public SGReferenced
71     {
72     public:
73         virtual ~Transition();
74         
75         std::string name() const;
76         
77         /**
78          * Set if the target state should automatically be excluded
79          * from the source state. Defaults to true, can be cleared
80          * to allow a state to re-enter itself
81          */
82         void setExcludeTarget(bool aExclude);
83         
84         
85         /**
86          * The state we end in, after this transition fires
87          */
88         State* target() const;
89         
90         /**
91          * Add a state in which this transition is eligible to fire
92          */
93         void addSourceState(State* aSource);
94         
95         /**
96          * Specify the transition trigger condition. Takes ownership
97          */
98         void setTriggerCondition(SGCondition* aCondition);
99         
100         
101         void addBinding(SGBinding* aBinding);
102     private:
103         friend class StateMachine;
104         
105         Transition(const std::string& aName, State* aTarget);
106         
107         /**
108          * predicate to determine if this transition can fire given a
109          * current state.
110          */
111         bool applicableForState(State* aCurrent) const;
112         
113         /**
114         * test if the transition should fire, based on current state
115         */
116         bool evaluate() const;
117          
118         void fireBindings();
119     
120         class TransitionPrivate;
121         std::auto_ptr<TransitionPrivate> d;
122     };
123     
124     typedef SGSharedPtr<State> State_ptr;
125     typedef SGSharedPtr<Transition> Transition_ptr;
126     
127     void initFromPlist(SGPropertyNode* desc, SGPropertyNode* root);
128     
129     /**
130      * create a state machine from a property list description
131      */
132     static StateMachine* createFromPlist(SGPropertyNode* desc, SGPropertyNode* root);
133     
134     SGPropertyNode* root();
135     
136     void init();
137     void shutdown();
138     
139     void update(double dt);
140     
141     State_ptr state() const;
142     
143     /**
144      * public API to force a change to a particular state.
145      * @param aOnlyIfDifferent - only make a transition if the new state is
146      *   different from the current state. Otherwise, the existing state will
147      * be exited and re-entered.
148      */
149     void changeToState(State_ptr aState, bool aOnlyIfDifferent=true);
150     
151      /// wrapper to change state by looking up a name
152     void changeToStateName(const std::string& aName, bool aOnlyIfDifferent=true);
153     
154     State_ptr findStateByName(const std::string& aName) const;
155     
156     State_ptr stateByIndex(unsigned int aIndex) const;
157     
158     int indexOfState(State_ptr aState) const;
159     
160     // programatic creation
161     State_ptr createState(const std::string& aName);
162     Transition_ptr createTransition(const std::string& aName, State_ptr aTarget);
163 private:
164     void addState(State_ptr aState);
165     void addTransition(Transition_ptr aTrans);
166     
167     void innerChangeState(State_ptr aState, Transition_ptr aTrans);
168     
169     class StateMachinePrivate;
170     std::auto_ptr<StateMachinePrivate> d;
171 };
172
173 typedef SGSharedPtr<StateMachine> StateMachine_ptr;
174
175 } // of simgear namespace
176
177 #endif // of SIMGEAR_STATE_MACHINE_H