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 
33 using 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),
51  State(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 
72 std::string
74 {
75  std::stringstream str;
76  str << this->StateBase::impl->localUniqueId << "_" << globalStateIdentifier;
77  return str.str();
78 }
79 
80 void
82 {
83 }
84 
85 void
87 {
88  // get proxy to self/this
89  myProxy = RemoteStateIceBasePrx::checkedCast(getProxy());
90 }
91 
92 bool
93 DynamicRemoteState::__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 
240 void
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 
266 void
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 
276 bool
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 
311 void
313 {
314  addParameter(inputParameters, "proxyName", VariantType::String, false);
315  addParameter(inputParameters, "stateName", VariantType::String, false);
316 }
armarx::StateController::__enqueueEvent
virtual void __enqueueEvent(const EventPtr event)
Definition: StateController.cpp:195
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:43
armarx::DynamicRemoteState::_baseOnEnter
void _baseOnEnter() override
Does the setup of the remote statechart and calls RemoteState::_baseOnEnter() afterwards.
Definition: DynamicRemoteState.cpp:241
armarx::DynamicRemoteState::createEmptyCopy
StateBasePtr createEmptyCopy() const override
Definition: DynamicRemoteState.cpp:293
armarx::DynamicRemoteState::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: DynamicRemoteState.cpp:86
armarx::StateController
Definition: StateController.h:55
ArmarXManager.h
StateBaseImpl.h
armarx::RemoteState::_baseOnEnter
void _baseOnEnter() override
Overridden function to redirect this call to the real state in the other application.
Definition: RemoteState.cpp:539
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:360
armarx::ManagedIceObject::removeProxyDependency
bool removeProxyDependency(const std::string &name)
This function removes the dependency of this object on the in parameter name specified object.
Definition: ManagedIceObject.cpp:337
armarx::DynamicRemoteState::clone
StateBasePtr clone() const override
Definition: DynamicRemoteState.cpp:302
IceUtil
Definition: Instance.h:21
IceInternal::Handle
Definition: forward_declarations.h:8
armarx::flush
const LogSender::manipulator flush
Definition: LogSender.h:251
armarx::DynamicRemoteState::_baseOnExit
void _baseOnExit() override
Calls RemoteState::_baseOnBreak() and redefines the input parameters.
Definition: DynamicRemoteState.cpp:267
armarx::RemoteState
This Statetype is used to create a state instance that represents a state that is located in another ...
Definition: RemoteState.h:62
armarx::DynamicRemoteState
DynamicRemoteStates can be used to connect to remote statecharts dynamically at runtime.
Definition: DynamicRemoteState.h:52
ArmarXObjectScheduler.h
boost::source
Vertex source(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:661
armarx::StateBase::addParameter
bool addParameter(StateParameterMap &paramMap, const std::string &key, VariantTypeId type, bool optional, VariantPtr defaultValue=VariantPtr()) const
Definition: StateBase.cpp:615
armarx::State
Definition: State.h:53
armarx::StateBase
Definition: StateBase.h:59
armarx::DynamicRemoteState::DynamicRemoteState
DynamicRemoteState()
Initialize all instance variables.
Definition: DynamicRemoteState.cpp:35
armarx::DynamicRemoteState::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: DynamicRemoteState.cpp:81
Ice
Definition: DBTypes.cpp:63
armarx::DynamicRemoteState::defineParameters
void defineParameters() override
Definition: DynamicRemoteState.cpp:312
armarx::ManagedIceObject
The ManagedIceObject is the base class for all ArmarX objects.
Definition: ManagedIceObject.h:162
armarx::DynamicRemoteState::_baseOnBreak
bool _baseOnBreak(const EventPtr evt) override
If the call to RemoteState::_baseOnBreak() returns true the input parameters are redefined.
Definition: DynamicRemoteState.cpp:277
armarx::Logging
Base Class for all Logging classes.
Definition: Logging.h:239
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:108
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:202
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::VariantType::String
const VariantTypeId String
Definition: Variant.h:921
armarx::ManagedIceObject::getProxy
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Definition: ManagedIceObject.cpp:407
armarx::StateBase::impl
std::unique_ptr< Impl > impl
Definition: StateBase.h:288
armarx::RemoteState::_baseOnBreak
bool _baseOnBreak(const EventPtr evt) override
Called by processEvent()-function or parentstate. Must NOT be called by user.
Definition: RemoteState.cpp:590
DynamicRemoteState.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::ManagedIceObject::getObjectScheduler
ArmarXObjectSchedulerPtr getObjectScheduler() const
Definition: ManagedIceObject.cpp:776
armarx::DynamicRemoteState::getDefaultName
std::string getDefaultName() const override
Retrieve default name of component.
Definition: DynamicRemoteState.cpp:73
armarx::RemoteState::_baseOnExit
void _baseOnExit() override
Overridden function to redirect this call to the real state in the other application.
Definition: RemoteState.cpp:616
EVENTTOALL
#define EVENTTOALL
Definition: StateBase.h:42
armarx::DynamicRemoteState::operator=
DynamicRemoteState & operator=(const DynamicRemoteState &source)
Assignment operator which currently is set to fail on any invocation.
Definition: DynamicRemoteState.cpp:62