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