StateController.h
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5*
6* ArmarX is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License version 2 as
8* published by the Free Software Foundation.
9*
10* ArmarX 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
13* GNU 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, see <http://www.gnu.org/licenses/>.
17*
18* @package ArmarX::statechart
19* @author Mirko Waechter ( mirko.waechter at kit dot edu)
20* @date 2012
21* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22* GNU General Public License
23*/
24
25#pragma once
26
27#include <functional>
28#include <memory>
29
30#include "StateBase.h"
31
32namespace armarx
33{
34 class StateController;
35 using StateControllerPtr = IceInternal::Handle<StateController>;
36 template <typename Type>
37 class RunningTask;
38} // namespace armarx
39
40namespace armarx::Profiler
41{
42 class Profiler;
43 using ProfilerPtr = std::shared_ptr<Profiler>;
44 using ProfilerSet = std::set<ProfilerPtr>;
45} // namespace armarx::Profiler
46
47namespace armarx
48{
49 /**
50 *\class StateController
51 *\ingroup StatechartGrp
52 * The StateController class processes events and controls the
53 * statechart flow.
54 */
55 class StateController : virtual public StateBase
56 {
57 public:
58 using transitionFunction = std::function<void(StateController* state,
59 const StateIceBasePtr& nextState,
60 const StateIceBasePtr& previousState)>;
61 using TransitionFunctionMap = std::map<std::string, transitionFunction>;
62
64 StateController(const StateController& source);
65 ~StateController() override;
66
67 bool isFinished() const;
68 /**
69 * @brief waitForStateToFinish waits until this thread has finished
70 * (i.e. a FinalSubState has been reached).<br/>
71 *
72 * This function can only be called in a toplevelstate (a state with
73 * no parent state).
74 *
75 * @param timeOutMs
76 * @see isFinished()
77 */
78 void waitForStateToFinish(int timeoutMs = -1) const;
79
80
81 /**
82 * @brief disableRunFunction sets useRunFunction to false and waits
83 * (blocking) for the current StateBase::run() function to complete.
84 *
85 * @note This function needs to be called <b>before</b> the destructor of the
86 * state is called. If not called before destructor, the StateBase::run()
87 * function might cause a segfault.
88 */
89 void disableRunFunction();
90
91 /**
92 * @brief isRunningTaskStopped checks whether the RunningTask, that
93 * executes run() is requested to stop. Check this function periodically in
94 * run()
95 * @return status of runningtask
96 */
97 bool isRunningTaskStopped() const;
98
99 /**
100 * @brief Checks whether the run() function has already finished
101 * @return true if finished
102 */
103 bool isRunningTaskFinished() const;
104
105 /**
106 * @brief Waits until the run-function has finished. This might be useful to do in onBreak() or onEnter()
107 * @see onEnter(), onBreak(), onRun()
108 */
109 void waitForRunningTaskToFinish() const;
110
111 /**
112 * @brief Disables the reporting to profilers for this states during state visits.
113 */
114 void disableStateReporting(bool disable = true);
115
116 void addTransitionFunction(const TransitionIceBase& t, transitionFunction function);
117 std::string getTransitionID(const TransitionIceBase& t) const;
118 std::string getTransitionID(const std::string& eventName,
119 const std::string sourceStateName) const;
120 bool findTransition(const std::string& eventName,
121 const std::string sourceStateName,
122 TransitionIceBase& transition);
123
124 /*! \brief Function to set the statemachine in the first state and call OnEnter().
125 *
126 * Should only be called for the outer most state(machine).
127 * All initial substates of this state and of it's substates are also entered.
128 * @param inputparameters Dictionary of parameters that should be mapped into the
129 * input parameters of this state. Uses '*'=>'*' mapping.
130 */
131 void enter(const StringVariantContainerBaseMap& tempInputParameters =
132 StringVariantContainerBaseMap());
133
134
135 /**
136 * \brief Called by StateControllerprocessEvent()-function or parentstate. Must NOT
137 * be called by user.
138 *
139 * Calls OnEnter() in this hierarchylevel and of every initialstate of all sub levels.
140 */
141 virtual void _baseOnEnter();
142
143 virtual void _startRun();
144 virtual void _baseRun();
145
146 /*! \brief Called by StateController::processEvent()-function or parentstate. Must NOT
147 be called by user.
148
149 Calls OnExit() in this hierarchylevel and all sub levels.
150 @relates baseOnExit()
151 */
152 virtual void _baseOnExit();
153
154 /*! \brief Called by StateControllerprocessEvent()-function or parentstate. Must NOT be called by user.
155
156 Calls OnBreak() in this hierarchylevel and all sub levels.
157 */
158 virtual bool _baseOnBreak(const EventPtr evt);
159
160
161 /**
162 * @brief addProfilerRecursive recursively adds a new armarx::Profiler::Profiler object as armarx::StateController::localProfiler(the default one does not do anything at all).
163 *
164 * \p recursiveLevels determins how many levels deep this new profiler object should be set:
165 *
166 * \li == -1: all reachable substates
167 * \li == 0: only current state
168 * \li > 0: current state + \p recursiveLevels deep)
169 *
170 * This is automtically set in armarx::StatechartContext::setToplevelState() based on statechart properties.
171 *
172 * @param profiler profiler instance to use in the state for calling armarx::Profiler::Profiler methods
173 * @param recursiveLevels how many levels deep the profiler should be set
174 */
175 void addProfilerRecursive(Profiler::ProfilerPtr profiler, int recursiveLevels = 0);
176 void removeProfilerRecursive(Profiler::ProfilerPtr profiler, int recursiveLevels = 0);
177
178 struct Impl;
179 std::unique_ptr<Impl> cimpl;
180
181 /**
182 * @brief Getter function that automatically casts the parentState
183 * member of StateBase into StateControllerPtr. @throw LocalException
184 * if parent state could not be cas @return Pointer to the parent state
185 */
187
188 virtual bool __breakActiveSubstate(const EventPtr event);
189
190 /*! \brief Function that gets called, when a state enters a FinalSubstate.
191 Virtual function, so that RemoteStateWrapper can override it.
192 */
193 virtual void __finalize(const EventPtr event);
194
195 /*! \brief Function that gets called, when a state enters a FinalSubstate.
196 Virtual function, so that RemoteStateWrapper can override it.
197 */
198 virtual void __substatesFinished(const EventPtr ev);
199
200 virtual void __enqueueEvent(const EventPtr event);
201
202 /**
203 * @brief This function is implemented in StateUtil and removes all conditions
204 * that have been installed in onEnter() or run(). It is called after onExit()
205 */
206 virtual void
210
211 /** \brief Before:Function to get the unbreakable-buffer status of all
212 parent state - recursively. * now: checks the flag for the buffer, that
213 gets set externally @return Returns true if no parent has any events in
214 the unbreakable buffer, false otherwise.
215 */
216 virtual bool __getUnbreakableBufferStati() const;
217
218 /*! \brief Main function to control the statemachine/state.
219
220 Determines with Parameter \c event, the active state and the
221 transitiontable, which transition to choose.<br/> If no transition
222 is found, an eUnexpectedEvent-exception is thrown.
223 */
224 virtual void __processEvent(const EventPtr event, bool buffered = false);
225
226 /**
227 * @brief Apply the mappings during a transitions. The order is parent's local,
228 * parent's output and then next state's input.
229 * @param srcState
230 * @param t Transition that is currently executed
231 * @param event Event that led to the transition
232 */
233 bool __applyMappings(const StateControllerPtr& srcState,
234 const TransitionIceBase& t,
235 const EventPtr& event,
236 TransitionError& error);
237 void __printTransitionError(const TransitionError& transitionError,
238 const EventPtr& event) const;
239
240
241 bool __findValidTransition(const EventPtr& event,
242 const StateIceBasePtr& sourceState,
243 TransitionIceBase& resultTransition,
244 TransitionError& error) const;
245 TransitionError __validateTransition(const TransitionIceBase& transition,
246 const EventPtr event,
247 const StateIceBasePtr& sourceState,
248 const StateIceBasePtr& destinationState) const;
249
250 virtual unsigned int __getUnbreakableBufferSize() const;
251
252 /*! This virtual function notifies all substates that an event has been
253 * buffered due to unbreakable states and that they must not process any
254 * further events when they have reached a breakable state.
255 **/
256 virtual void __notifyEventBufferedDueToUnbreakableState(bool eventBuffered = true);
257
258 /*! \brief Processes buffered events, that could not be processed immediately due to unbreakable substates.
259
260 Gets called after a transition from a unbreakable substate to a breakable substate after execution of OnEnter() of the breakable state.<br/>
261 It is not called yet, when a transition occurs between 2 unbreakable states.<br/>
262 The calling substate can be of any level below this state in the hierarchy.<br/>
263 */
264 virtual void __processBufferedEvents();
265
266 void __waitForRemoteStates() const;
267
268 bool __checkExistenceOfTransition(const TransitionIceBase& transition);
269
270 friend class State;
271 friend class StateUtility;
272 template <class EventType, class StateType>
273 friend class FinalStateBase;
274 template <typename ContextType>
275 friend class RemoteStateOfferer;
276 friend class RemoteState;
277 friend class DynamicRemoteState;
279 friend class StatechartManager;
280 friend class StatechartContext;
281 };
282} // namespace armarx
The armarx::Profiler::Profiler class can be used for timing executions within the ArmarX framework.
Definition Profiler.h:89
The StateController class processes events and controls the statechart flow.
virtual void __notifyEventBufferedDueToUnbreakableState(bool eventBuffered=true)
void __printTransitionError(const TransitionError &transitionError, const EventPtr &event) const
virtual void __enqueueEvent(const EventPtr event)
std::function< void(StateController *state, const StateIceBasePtr &nextState, const StateIceBasePtr &previousState)> transitionFunction
virtual bool __getUnbreakableBufferStati() const
Before:Function to get the unbreakable-buffer status of all parent state - recursively.
std::string getTransitionID(const TransitionIceBase &t) const
virtual bool __breakActiveSubstate(const EventPtr event)
virtual void _baseOnExit()
Called by StateController::processEvent()-function or parentstate. Must NOT be called by user.
bool findTransition(const std::string &eventName, const std::string sourceStateName, TransitionIceBase &transition)
virtual void _removeInstalledConditions()
This function is implemented in StateUtil and removes all conditions that have been installed in onEn...
virtual void __finalize(const EventPtr event)
Function that gets called, when a state enters a FinalSubstate. Virtual function, so that RemoteState...
virtual void __processBufferedEvents()
Processes buffered events, that could not be processed immediately due to unbreakable substates.
void disableStateReporting(bool disable=true)
Disables the reporting to profilers for this states during state visits.
virtual void __processEvent(const EventPtr event, bool buffered=false)
Main function to control the statemachine/state.
std::unique_ptr< Impl > cimpl
bool isRunningTaskStopped() const
isRunningTaskStopped checks whether the RunningTask, that executes run() is requested to stop.
void waitForStateToFinish(int timeoutMs=-1) const
waitForStateToFinish waits until this thread has finished (i.e.
void enter(const StringVariantContainerBaseMap &tempInputParameters=StringVariantContainerBaseMap())
Function to set the statemachine in the first state and call OnEnter().
virtual unsigned int __getUnbreakableBufferSize() const
TransitionError __validateTransition(const TransitionIceBase &transition, const EventPtr event, const StateIceBasePtr &sourceState, const StateIceBasePtr &destinationState) const
void waitForRunningTaskToFinish() const
Waits until the run-function has finished.
bool __findValidTransition(const EventPtr &event, const StateIceBasePtr &sourceState, TransitionIceBase &resultTransition, TransitionError &error) const
void disableRunFunction()
disableRunFunction sets useRunFunction to false and waits (blocking) for the current StateBase::run()...
virtual void _baseOnEnter()
Called by StateControllerprocessEvent()-function or parentstate.
bool __applyMappings(const StateControllerPtr &srcState, const TransitionIceBase &t, const EventPtr &event, TransitionError &error)
Apply the mappings during a transitions.
StateControllerPtr __getParentState() const
Getter function that automatically casts the parentState member of StateBase into StateControllerPtr.
void addProfilerRecursive(Profiler::ProfilerPtr profiler, int recursiveLevels=0)
addProfilerRecursive recursively adds a new armarx::Profiler::Profiler object as armarx::StateControl...
bool __checkExistenceOfTransition(const TransitionIceBase &transition)
bool isRunningTaskFinished() const
Checks whether the run() function has already finished.
std::map< std::string, transitionFunction > TransitionFunctionMap
void removeProfilerRecursive(Profiler::ProfilerPtr profiler, int recursiveLevels=0)
virtual bool _baseOnBreak(const EventPtr evt)
Called by StateControllerprocessEvent()-function or parentstate. Must NOT be called by user.
friend class StatechartEventDistributor
void addTransitionFunction(const TransitionIceBase &t, transitionFunction function)
virtual void __substatesFinished(const EventPtr ev)
Function that gets called, when a state enters a FinalSubstate. Virtual function, so that RemoteState...
std::shared_ptr< Profiler > ProfilerPtr
std::set< ProfilerPtr > ProfilerSet
Definition Profiler.h:41
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< Event > EventPtr
Typedef of EventPtr as IceInternal::Handle<Event> for convenience.
Definition Event.h:40
IceInternal::Handle< StateController > StateControllerPtr