DynamicRemoteState.cpp
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#include "DynamicRemoteState.h"
26
27#include <IceUtil/IceUtil.h>
28
32
33using namespace armarx;
34
36{
37 stateType = eDynamicRemoteState;
38 stateName = "DynamicRemoteState";
39 greedyInputDictionary = true;
40}
41
43 IceUtil::Shared(source),
44 Ice::Object(source),
45 StateIceBase(source),
46 RemoteStateInterface(source),
47 RemoteStateIceBase(source),
48 Logging(source),
49 StateBase(source),
50 StateController(source),
51 State(source),
52 ManagedIceObject(source),
53 RemoteState(source)
54
55{
56 stateType = eDynamicRemoteState;
57 stateName = "DynamicRemoteState";
58 greedyInputDictionary = true;
59}
60
63{
64 assert(0);
65 stateName = "DynamicRemoteState";
66 stateType = eDynamicRemoteState;
67 greedyInputDictionary = true;
68
69 return *this;
70}
71
72std::string
74{
75 std::stringstream str;
76 str << this->StateBase::impl->localUniqueId << "_" << globalStateIdentifier;
77 return str.str();
78}
79
80void
84
85void
87{
88 // get proxy to self/this
89 myProxy = RemoteStateIceBasePrx::checkedCast(getProxy());
90}
91
92bool
93DynamicRemoteState::__checkStatePreconditions()
94{
95
96 StateParameterMap::iterator itProxy = inputParameters.find("proxyName");
97 StateParameterMap::iterator itState = inputParameters.find("stateName");
98
99 if (itProxy == inputParameters.end())
100 {
102 << "'proxyName' is not specified in the input parameters of the DynamicRemoteState '" +
103 stateName + "'."
104 << flush;
105 return false;
106 }
107
108 if (itState == inputParameters.end())
109 {
111 << "'stateName' is not specified in the input parameters of the DynamicRemoteState '" +
112 stateName + "'."
113 << flush;
114 return false;
115 }
116
117 if (!itProxy->second->set)
118 {
120 << "'proxyName' is not set in the input parameters of the DynamicRemoteState '" +
121 stateName + "'."
122 << flush;
123 return false;
124 }
125
126 if (!itState->second->set)
127 {
129 << ("'stateName' is not set in the input parameters of the DynamicRemoteState '" +
130 stateName + "'.")
131 << flush;
132 return false;
133 }
134
135 ARMARX_INFO_S << VAROUT(proxyName) << VAROUT(getName());
136
137 if (!proxyName.empty())
138 {
139 removeProxyDependency(proxyName);
140 }
141
142 try
143 {
144 // clean up old instance
145 if (remoteStateId >= 0 && stateOffererPrx)
146 {
147 ARMARX_INFO_S << "Removing instance " << remoteStateId;
148 stateOffererPrx->removeInstance(remoteStateId);
149 }
150 }
151 catch (...)
152 {
153 }
154
155
156 SingleVariantPtr sVar = SingleVariantPtr::dynamicCast(itProxy->second->value);
157 proxyName = sVar->get()->getString();
158
159 if (proxyName.empty())
160 {
161 // throw LocalException("'proxyName' parameter is empty.");
162 ARMARX_WARNING << "'proxyName' parameter is empty." << flush;
163 return false;
164 }
165
166 sVar = SingleVariantPtr::dynamicCast(itState->second->value);
167 std::string tempStateStr = sVar->get()->getString();
168
169 if (tempStateStr.empty())
170 {
171 // throw LocalException("'stateName' parameter is empty.");
172 ARMARX_WARNING << ("'stateName' parameter is empty.") << flush;
173 return false;
174 }
175
176 stateClassName = tempStateStr;
177 stateName = tempStateStr;
178
179
180 // StateParameterMap remoteInput;
181 if (!getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted))
182 {
183 return false;
184 }
185
186 try
187 {
188 stateOffererPrx = getProxy<RemoteStateOffererIceBasePrx>(proxyName, true);
189 // remoteInput = stateOffererPrx->getRemoteInputParameters(stateClassName);
190 }
191 catch (const Ice::NotRegisteredException&)
192 {
193 ARMARX_WARNING << "The Component with name '" + proxyName + "' is not registered in Ice."
194 << flush;
195 return false;
196 }
197 catch (std::exception& e)
198 {
199 ARMARX_WARNING << "Could not get proxy for DynamicRemotestate with: proxyName: '" +
200 proxyName + "' and stateName: '" + stateName + "'!\n\n"
201 << e.what();
202 return false;
203 }
204
205 auto pos = globalStateIdentifier.find_last_of(">");
206 if (pos != std::string::npos)
207 {
208 globalStateIdentifier.erase(globalStateIdentifier.find_last_of(">") - 1);
209 }
210
211 // get the remotestate inputparameters and fill them with the already set (greedy) input parameters of this dynamic remote state
212 // StateParameterMap tempMap;
213 // StateUtilFunctions::copyDictionary(inputParameters, tempMap);
214 // StateUtilFunctions::copyDictionary(remoteInput, inputParameters);
215 // StateUtilFunctions::fillDictionary(StateUtilFunctions::getSetValues(tempMap), inputParameters);
216 // std::string paramCheckOutput;
217
218
219 // if (!StateUtilFunctions::checkForCompleteParameters(inputParameters, &paramCheckOutput))
220 // {
221 // ARMARX_WARNING << ("Not all required inputparameters of the Dynamic Remote State '" + stateName + "' are set.\n" + paramCheckOutput);
222 // return false;
223 // }
224
225
226 itProxy->second->set = false;
227 itState->second->set = false;
228
229 // myProxy is set in onConnectComponent() which is running in another thread, to avoid race conditions, wait for it
230 if (!getObjectScheduler()->waitForObjectState(eManagedIceObjectStarted, 10000))
231 {
233 << ("Waited more than 10 seconds for dynamic remote state to be ready - bailing out");
234 return false;
235 }
236
237 return true;
238}
239
240void
242{
243
244 bool loadingSuccessfull = __checkStatePreconditions();
245
246 if (!loadingSuccessfull)
247 {
248 EventPtr evt = new LoadingFailed(EVENTTOALL);
249 __enqueueEvent(evt);
250 return;
251 }
252
253 // this is usually done in RemoteState::onConnectComponent()
254 // but in DynamicRemoteState it must be done here because the proxy name
255 // is only available in the Event sent to this state
256 remoteStateId = stateOffererPrx->createRemoteStateInstance(
257 stateClassName, myProxy, globalStateIdentifier, stateName);
258 globalStateIdentifier += "->" + stateName;
259 StateIceBasePtr state = stateOffererPrx->getStatechartInstance(remoteStateId);
260 subStateList = state->subStateList;
261 transitions = state->transitions;
262
264}
265
266void
268{
270 inputParameters.clear();
271 removeProxyDependency(proxyName);
272 // the input parameters have been deleted due to assignment of the remote inputparameters, re-insert them
274}
275
276bool
278{
279
280 bool result = RemoteState::_baseOnBreak(evt);
281
282 if (result)
283 {
284 inputParameters.clear();
285 removeProxyDependency(proxyName);
286 // the input parameters have been deleted due to assignment of the remote inputparameters, re-insert them
288 }
289 return result;
290}
291
294{
295 RemoteStatePtr result = RemoteStatePtr::dynamicCast(new DynamicRemoteState);
296 result->setName(result->getDefaultName() + IceUtil::generateUUID());
297 getArmarXManager()->addObject(ManagedIceObjectPtr::dynamicCast(result));
298 return result;
299}
300
303{
304 RemoteStatePtr result = new DynamicRemoteState(*this);
305 result->setName(result->getDefaultName() + IceUtil::generateUUID());
306 getArmarXManager()->addObject(ManagedIceObjectPtr::dynamicCast(result));
307
308 return result;
309}
310
311void
313{
314 addParameter(inputParameters, "proxyName", VariantType::String, false);
315 addParameter(inputParameters, "stateName", VariantType::String, false);
316}
#define EVENTTOALL
Definition StateBase.h:42
#define VAROUT(x)
std::string str(const T &t)
DynamicRemoteStates can be used to connect to remote statecharts dynamically at runtime.
void onInitComponent() override
Pure virtual hook for the subclass.
StateBasePtr clone() const override
bool _baseOnBreak(const EventPtr evt) override
If the call to RemoteState::_baseOnBreak() returns true the input parameters are redefined.
StateBasePtr createEmptyCopy() const override
DynamicRemoteState()
Initialize all instance variables.
void onConnectComponent() override
Pure virtual hook for the subclass.
void _baseOnExit() override
Calls RemoteState::_baseOnBreak() and redefines the input parameters.
DynamicRemoteState & operator=(const DynamicRemoteState &source)
Assignment operator which currently is set to fail on any invocation.
void _baseOnEnter() override
Does the setup of the remote statechart and calls RemoteState::_baseOnEnter() afterwards.
std::string getDefaultName() const override
Retrieve default name of component.
Base Class for all Logging classes.
Definition Logging.h:240
The ManagedIceObject is the base class for all ArmarX objects.
ArmarXObjectSchedulerPtr getObjectScheduler() const
std::string getName() const
Retrieve name of object.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
bool removeProxyDependency(const std::string &name)
This function removes the dependency of this object on the in parameter name specified object.
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
bool _baseOnBreak(const EventPtr evt) override
Called by processEvent()-function or parentstate. Must NOT be called by user.
void _baseOnExit() override
Overridden function to redirect this call to the real state in the other application.
void _baseOnEnter() override
Overridden function to redirect this call to the real state in the other application.
This class is the implementation of the Slice Definition of a state.
Definition StateBase.h:60
bool addParameter(StateParameterMap &paramMap, const std::string &key, VariantTypeId type, bool optional, VariantPtr defaultValue=VariantPtr()) const
std::unique_ptr< Impl > impl
Definition StateBase.h:289
The StateController class processes events and controls the statechart flow.
virtual void __enqueueEvent(const EventPtr event)
Class that offers the main functionality needed to create a statechart.
Definition State.h:54
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
const VariantTypeId String
Definition Variant.h:921
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< RemoteState > RemoteStatePtr
Definition RemoteState.h:47
IceInternal::Handle< SingleVariant > SingleVariantPtr
const LogSender::manipulator flush
Definition LogSender.h:251
IceInternal::Handle< Event > EventPtr
Typedef of EventPtr as IceInternal::Handle<Event> for convenience.
Definition Event.h:40
IceInternal::Handle< StateBase > StateBasePtr
Definition StateBase.h:49