RemoteStateOfferer.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 ArmarXCore::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#pragma once
25
26// Slice Includes
27#include <ArmarXCore/interface/statechart/RemoteStateOffererIce.h>
28
29// ArmarX Includes
33
34// Statechart Includes
35#include <type_traits>
36
37#include "RemoteState.h"
38#include "RemoteStateWrapper.h"
39#include "State.h"
40#include "StatechartManager.h"
41
42namespace armarx
43{
44 std::string joinStrings(std::vector<std::string> const& input, std::string const& seperator);
45
46 struct RemoteStateOffererBase : virtual RemoteStateOffererIceBase, virtual State
47 {
48 //! \brief Implement this function to specify the RemoteStateOfferer prefix.
49 //! \note Do not override getDefaultName()!
50 virtual std::string getStateOffererName() const = 0;
51 //! \brief Pure virtual function, in which the states must be added, that should be remote-accessable.
52 virtual void onInitRemoteStateOfferer() = 0;
53 //! \brief Virtual function, in which the user can fetch some proxies.
54 virtual void onConnectRemoteStateOfferer();
55 //! \brief Virtual function, in which the user can implement some clean up.
56 virtual void onExitRemoteStateOfferer();
57
58
59 virtual void waitUntilComponentStarted() = 0;
60
61 // inherited from RemoteStateOffererInterface
62 CreateRemoteStateInstanceOutput
63 createRemoteStateInstanceNew(CreateRemoteStateInstanceInput const& input,
64 Ice::Current const& context) override;
65
66 int createRemoteStateInstance(const std::string& stateName,
67 const RemoteStateIceBasePrx& remoteStatePrx,
68 const std::string& parentStateItentifierStr,
69 const std::string& instanceName,
70 const Ice::Current& context = Ice::emptyCurrent) override;
71
72 void updateGlobalStateIdRecursive(int stateId,
73 const std::string& parentId,
74 const Ice::Current& context = Ice::emptyCurrent) override;
75
76 void callRemoteState(int stateId,
77 const StringVariantContainerBaseMap& properties,
78 const Ice::Current& context = Ice::emptyCurrent) override;
79
80 void exitRemoteState(int stateId,
81 const ::Ice::Current& context = Ice::emptyCurrent) override;
82
83 bool breakRemoteState(int stateId,
84 const EventBasePtr& evt,
85 const ::Ice::Current& context = Ice::emptyCurrent) override;
86
87 bool isRemoteStateFinished(int stateId,
88 const ::Ice::Current& context = Ice::emptyCurrent) override;
89
90 bool
92 const EventBasePtr& evt,
93 const ::Ice::Current& context = Ice::emptyCurrent) override;
94
96 int stateId,
97 bool eventBuffered,
98 const ::Ice::Current& context = Ice::emptyCurrent) override;
99 StateIceBasePtr
100 refetchRemoteSubstates(int stateId,
101 const ::Ice::Current& context = Ice::emptyCurrent) override;
102 StateParameterMap
103 getRemoteInputParameters(const std::string& stateName,
104 const ::Ice::Current& context = Ice::emptyCurrent) override;
105 StateParameterMap
106 getRemoteOutputParameters(const std::string& stateName,
107 const ::Ice::Current& context = Ice::emptyCurrent) override;
108 StateParameterMap
110 const ::Ice::Current& context = Ice::emptyCurrent) override;
111 StateParameterMap
113 const ::Ice::Current& context = Ice::emptyCurrent) override;
114
115 bool hasSubstatesRemote(const std::string& stateName,
116 const ::Ice::Current& context = Ice::emptyCurrent) const override;
117 bool hasActiveSubstateRemote(int stateId,
118 const ::Ice::Current& context = Ice::emptyCurrent) override;
119 Ice::StringSeq
120 getAvailableStates(const ::Ice::Current& context = Ice::emptyCurrent) override;
121 StateIdNameMap
122 getAvailableStateInstances(const ::Ice::Current& context = Ice::emptyCurrent) override;
123 StateIceBasePtr getStatechart(const std::string& stateName,
124 const ::Ice::Current& context = Ice::emptyCurrent) override;
125 StateIceBasePtr getStatechartInstance(int stateId,
126 const Ice::Current& = Ice::emptyCurrent) override;
127 StateIceBasePtr
128 getStatechartInstanceByGlobalIdStr(const std::string& globalStateIdStr,
129 const Ice::Current& = Ice::emptyCurrent) override;
130 bool isHostOfStateByGlobalIdStr(const std::string& globalStateIdStr,
131 const Ice::Current& = Ice::emptyCurrent) override;
132
133 void removeInstance(int stateId, const Ice::Current& = Ice::emptyCurrent) override;
134 void issueEvent(int receivingStateId,
135 const EventBasePtr& evt,
136 const Ice::Current& = Ice::emptyCurrent) override;
137 void issueEventWithGlobalIdStr(const std::string& globalStateIdStr,
138 const EventBasePtr& evt,
139 const Ice::Current& = Ice::emptyCurrent) override;
140
141 //! \brief Overridden so that the user cannot use it
142 RemoteStatePtr addRemoteState(std::string stateName,
143 std::string proxyName,
144 std::string instanceName) override;
145 //! \brief Overridden so that the user cannot use it
146 RemoteStatePtr addDynamicRemoteState(std::string instanceName) override;
147
148 /** \struct RemoteStateData
149 A struct that holds meta data for a remoteaccessable state instances.
150 */
152 {
153 //! Local id of this RemoteStateOfferer, that identifies the state instance in the stateInstanceList
154 int id;
155 //! Not used yet.
156 std::string callerIceName;
157 //! Proxy to the state, that called this state
158 RemoteStateIceBasePrx callerStatePrx;
159 //! Pointer to a Pseudo parent state, that contains the real state instance.
161 };
162
163 RemoteStateData getInstance(int stateId);
164 StateBasePtr getGlobalInstancePtr(int globalId) const;
165 virtual StateBasePtr getStatePtr(const std::string& stateName) const;
166 std::map<int, StateBasePtr> getChildStatesByName(int parentId, std::string stateName);
167
168 StateIceBasePtr
169 getStatechartInstanceByGlobalIdStrRecursive(const std::string& globalStateIdStr,
170 StateBasePtr state,
171 int& stateCounter);
172
175 void run() override;
176
177 void initState(State& state);
178
179
181 //! Holds the instances that where requested from remotely located states
182 std::map<int, RemoteStateData> stateInstanceList;
183 std::string componentName;
184 };
185
186 /**
187 \class RemoteStateOfferer
188 \brief Class that holds states, which offer functionality for other states over Ice.
189 \ingroup StatechartGrp
190 To offer such functionality one must derive from this class and implement
191 the function armarx::RemoteStateOfferer::onInitRemoteStateOfferer() and add the states offering remote functionality there.<br/>
192 For every incoming call to a state a copy of the base instance is created, so that concurrent calls dont interfere with each other.<br/>
193 The implemented, remoteaccessable states must call setRemoteaccessable().<br/>
194 An Example can be found in applications/StateChartExamples/RemoteAccessableStateExample.
195
196 \tparam ContextType The template parameter must be a class that derives from
197 StatechartContext
198
199 \see StatechartContext, RemoteState, DynamicRemoteState, RemoteStateWrapper
200
201 */
202 template <typename ContextType = StatechartContext>
203 struct RemoteStateOfferer : virtual RemoteStateOffererBase, virtual ContextType
204 {
206
207 static_assert(std::is_base_of_v<StatechartContext, ContextType>,
208 "The template parameter of RemoteStateOfferer, must be a class that derives "
209 "from StatechartContext or StatechartContext itself");
210
211 std::string
212 getDefaultName() const override
213 {
214 return getStateOffererName() + "StateOfferer";
215 }
216
217 void onInitStatechart() override;
218 void onConnectStatechart() override;
219 void onExitStatechart() override;
220 };
221
222 /////////////////////////////////////////////////////////////
223 ////////////// Implementation
224 /////////////////////////////////////////////////////////////
225
226
227 template <typename ContextType>
228 void
230 {
231 stateName = getDefaultName();
232 ContextType::setToplevelState(this);
233
234 StatePhase oldPhase = getStatePhase();
236
237
238 try
239 {
241 }
242 catch (...)
243 {
244 setStatePhase(oldPhase);
246 throw;
247 }
248
249 for (AbstractStateIceBasePtr state : subStateList)
250 {
251 StateControllerPtr stateController = StateControllerPtr::dynamicCast(state);
252
253 if (stateController)
254 {
255 int numberLogLevels = Component::getProperty<int>("ProfilingDepth").getValue();
256 stateController->addProfilerRecursive(Component::getProfiler(), numberLogLevels);
257 stateController->addProfilerRecursive(StatechartContext::stateReporter, -1);
258 }
259 }
260
261 ContextType::setAutoEnterToplevelState(false);
262 }
263
264 template <typename ContextType>
265 void
270
271 template <typename ContextType>
272 void
277
278 template <typename ContextType>
279 void
281 {
282 if (!ContextType::getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted,
283 5000))
284 {
285 throw LocalException()
286 << "Cannot create a remote state instance because the RemoteStateOfferer '"
287 << ContextType::getName() << "' is still waiting for dependencies: "
288 << joinStrings(ContextType::getUnresolvedDependencies(), ", ");
289 }
290 }
291
292} // namespace armarx
Property< PropertyType > getProperty(const std::string &name)
Profiler::ProfilerPtr getProfiler() const
getProfiler returns an instance of armarx::Profiler
void terminate()
Initiates termination of this IceManagedObject.
void setStatePhase(StatePhase newPhase)
StatePhase
enum that specifies the phase in which the state is currently in used to control the usage of state-f...
Definition StateBase.h:296
StatePhase getStatePhase() const
Profiler::ProfilerPtr stateReporter
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< RemoteState > RemoteStatePtr
Definition RemoteState.h:47
std::string joinStrings(std::vector< std::string > const &input, std::string const &seperator)
Definition State.cpp:45
IceInternal::Handle< RemoteStateWrapper > RemoteStateWrapperPtr
IceInternal::Handle< StateBase > StateBasePtr
Definition StateBase.h:49
IceInternal::Handle< StateController > StateControllerPtr
A struct that holds meta data for a remoteaccessable state instances.
RemoteStateWrapperPtr remoteWrappedState
Pointer to a Pseudo parent state, that contains the real state instance.
int id
Local id of this RemoteStateOfferer, that identifies the state instance in the stateInstanceList.
RemoteStateIceBasePrx callerStatePrx
Proxy to the state, that called this state.
CreateRemoteStateInstanceOutput createRemoteStateInstanceNew(CreateRemoteStateInstanceInput const &input, Ice::Current const &context) override
bool isRemoteStateFinished(int stateId, const ::Ice::Current &context=Ice::emptyCurrent) override
RemoteStateData getInstance(int stateId)
int createRemoteStateInstance(const std::string &stateName, const RemoteStateIceBasePrx &remoteStatePrx, const std::string &parentStateItentifierStr, const std::string &instanceName, const Ice::Current &context=Ice::emptyCurrent) override
StateIceBasePtr getStatechartInstanceByGlobalIdStr(const std::string &globalStateIdStr, const Ice::Current &=Ice::emptyCurrent) override
void removeInstance(int stateId, const Ice::Current &=Ice::emptyCurrent) override
void notifyEventBufferedDueToUnbreakableStateRemote(int stateId, bool eventBuffered, const ::Ice::Current &context=Ice::emptyCurrent) override
virtual void onConnectRemoteStateOfferer()
Virtual function, in which the user can fetch some proxies.
StateIceBasePtr refetchRemoteSubstates(int stateId, const ::Ice::Current &context=Ice::emptyCurrent) override
bool hasSubstatesRemote(const std::string &stateName, const ::Ice::Current &context=Ice::emptyCurrent) const override
void issueEventWithGlobalIdStr(const std::string &globalStateIdStr, const EventBasePtr &evt, const Ice::Current &=Ice::emptyCurrent) override
void exitRemoteState(int stateId, const ::Ice::Current &context=Ice::emptyCurrent) override
Ice::StringSeq getAvailableStates(const ::Ice::Current &context=Ice::emptyCurrent) override
StateParameterMap getRemoteInputParametersById(int stateId, const ::Ice::Current &context=Ice::emptyCurrent) override
void updateGlobalStateIdRecursive(int stateId, const std::string &parentId, const Ice::Current &context=Ice::emptyCurrent) override
RemoteStatePtr addDynamicRemoteState(std::string instanceName) override
Overridden so that the user cannot use it.
void issueEvent(int receivingStateId, const EventBasePtr &evt, const Ice::Current &=Ice::emptyCurrent) override
std::map< int, RemoteStateData > stateInstanceList
Holds the instances that where requested from remotely located states.
StateIdNameMap getAvailableStateInstances(const ::Ice::Current &context=Ice::emptyCurrent) override
virtual void waitUntilComponentStarted()=0
bool breakRemoteState(int stateId, const EventBasePtr &evt, const ::Ice::Current &context=Ice::emptyCurrent) override
virtual void onExitRemoteStateOfferer()
Virtual function, in which the user can implement some clean up.
virtual std::string getStateOffererName() const =0
Implement this function to specify the RemoteStateOfferer prefix.
StateBasePtr getGlobalInstancePtr(int globalId) const
virtual void onInitRemoteStateOfferer()=0
Pure virtual function, in which the states must be added, that should be remote-accessable.
RemoteStatePtr addRemoteState(std::string stateName, std::string proxyName, std::string instanceName) override
Overridden so that the user cannot use it.
std::map< int, StateBasePtr > getChildStatesByName(int parentId, std::string stateName)
void callRemoteState(int stateId, const StringVariantContainerBaseMap &properties, const Ice::Current &context=Ice::emptyCurrent) override
bool breakActiveSubstateRemotely(int stateId, const EventBasePtr &evt, const ::Ice::Current &context=Ice::emptyCurrent) override
StateParameterMap getRemoteInputParameters(const std::string &stateName, const ::Ice::Current &context=Ice::emptyCurrent) override
StateIceBasePtr getStatechartInstanceByGlobalIdStrRecursive(const std::string &globalStateIdStr, StateBasePtr state, int &stateCounter)
StateParameterMap getRemoteOutputParameters(const std::string &stateName, const ::Ice::Current &context=Ice::emptyCurrent) override
StateIceBasePtr getStatechartInstance(int stateId, const Ice::Current &=Ice::emptyCurrent) override
bool isHostOfStateByGlobalIdStr(const std::string &globalStateIdStr, const Ice::Current &=Ice::emptyCurrent) override
void run() override
Virtual function, that can be reimplemented to calculate complex operations.
StateIceBasePtr getStatechart(const std::string &stateName, const ::Ice::Current &context=Ice::emptyCurrent) override
bool hasActiveSubstateRemote(int stateId, const ::Ice::Current &context=Ice::emptyCurrent) override
virtual StateBasePtr getStatePtr(const std::string &stateName) const
StateParameterMap getRemoteOutputParametersById(int stateId, const ::Ice::Current &context=Ice::emptyCurrent) override
Class that holds states, which offer functionality for other states over Ice.
void onInitStatechart() override
onInitStatechart this method is called when the statechart is started.
void onExitStatechart() override
onExitStatechart can be implemented by subclasses
void waitUntilComponentStarted() override
void onConnectStatechart() override
onConnectStatechart is called before armarx::StatechartContext::startStatechart() and after armarx::S...
std::string getDefaultName() const override
Retrieve default name of component.