28 #include <boost/interprocess/sync/file_lock.hpp>
29 #include <boost/interprocess/sync/scoped_lock.hpp>
31 #include <IceUtil/IceUtil.h>
46 stateType = eRemoteState;
57 RemoteStateInterface(
source),
58 RemoteStateIceBase(
source),
69 remoteStateId =
source.remoteStateId;
76 stateOffererPrx =
source.stateOffererPrx;
89 if (remoteStateId >= 0 && stateOffererPrx)
95 stateOffererPrx->removeInstance(remoteStateId);
97 catch (Ice::NotRegisteredException& e)
99 ARMARX_WARNING <<
"Could not remove instance of RemoteState '" << stateClassName
100 <<
"'; probably the remote component is not alive anymore" <<
flush;
108 if (!stateName.empty())
110 this->stateName = stateName;
119 if (!proxyName.empty())
121 this->proxyName = proxyName;
133 static const char*
const g_lockFile =
"/tmp/armarx-statechart.lock";
134 static std::once_flag g_createLockFileFlag;
135 static std::mutex g_processMutex;
142 stateOffererPrx = getProxy<RemoteStateOffererIceBasePrx>(proxyName);
144 if (!stateOffererPrx)
150 myProxy = RemoteStateIceBasePrx::checkedCast(
getProxy());
153 #define USE_NEW_CREATE_STATECHART_INSTANCE
154 #ifdef USE_NEW_CREATE_STATECHART_INSTANCE
156 std::call_once(g_createLockFileFlag,
159 if (!std::filesystem::exists(g_lockFile))
161 std::ofstream lockFile(g_lockFile);
162 lockFile <<
"ArmarX Statechart Lock File";
166 boost::interprocess::file_lock file_lock(g_lockFile);
169 boost::interprocess::scoped_lock<boost::interprocess::file_lock> globalLock(file_lock);
170 std::scoped_lock localLock(g_processMutex);
173 catch (std::exception
const& ex)
176 <<
"'\n Waiting for 10 ms before calling createRemoteStateInstance for "
177 << stateClassName <<
", " << stateName;
181 ARMARX_IMPORTANT <<
"Calling stateOffererPrx->createRemoteStateInstanceNew for "
182 << stateClassName <<
", " << stateName;
184 CreateRemoteStateInstanceInput
input;
185 input.stateClassName = stateClassName;
186 input.remoteState = myProxy;
187 input.parentStateItentifierStr = globalStateIdentifier;
188 input.instanceName = stateName;
190 CreateRemoteStateInstanceOutput output;
195 output = stateOffererPrx->createRemoteStateInstanceNew(
input);
197 catch (Ice::ConnectFailedException
const& e)
199 ARMARX_WARNING <<
"Ice connect failed, trying again in a little bit";
201 output = stateOffererPrx->createRemoteStateInstanceNew(
input);
203 remoteStateId = output.remoteStateId;
204 inputParameters = output.inputParameters;
205 outputParameters = output.outputParameters;
207 StateIceBasePtr state = output.statechartInstance;
210 stateOffererPrx->getRemoteInputParameters(stateClassName), inputParameters);
215 stateOffererPrx->getRemoteOutputParameters(stateClassName), outputParameters);
217 std::call_once(g_createLockFileFlag,
220 if (!std::filesystem::exists(g_lockFile))
222 std::ofstream lockFile(g_lockFile);
223 lockFile <<
"ArmarX Statechart Lock File";
227 boost::interprocess::file_lock file_lock(g_lockFile);
230 boost::interprocess::scoped_lock<boost::interprocess::file_lock> globalLock(file_lock);
231 std::scoped_lock localLock(g_processMutex);
234 catch (std::exception
const& ex)
237 <<
"'\n Waiting for 10 ms before calling createRemoteStateInstance for "
238 << stateClassName <<
", " << stateName;
242 ARMARX_IMPORTANT <<
"Calling stateOffererPrx->createRemoteStateInstance for "
243 << stateClassName <<
", " << stateName;
246 remoteStateId = stateOffererPrx->createRemoteStateInstance(
247 stateClassName, myProxy, globalStateIdentifier, stateName);
249 catch (Ice::ConnectFailedException
const& e)
251 ARMARX_WARNING <<
"Ice connect failed, trying again in a little bit";
253 remoteStateId = stateOffererPrx->createRemoteStateInstance(
254 stateClassName, myProxy, globalStateIdentifier, stateName);
256 StateIceBasePtr state = stateOffererPrx->getStatechartInstance(remoteStateId);
259 subStateList = state->subStateList;
260 transitions = state->transitions;
261 activeSubstate = state->activeSubstate;
262 initState = state->initState;
271 <<
"' was disconnected during execution -> sending failure event";
279 if (remoteStateId != -1 && stateOffererPrx)
281 stateOffererPrx->removeInstance(remoteStateId);
289 stateOffererPrx =
nullptr;
299 getArmarXManager()->addObject(ManagedIceObjectPtr::dynamicCast(result),
false);
302 result->getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
313 result->setName(result->getDefaultName());
314 result->setStateName(stateName);
316 result->setProxyName(proxyName);
318 getArmarXManager()->addObject(ManagedIceObjectPtr::dynamicCast(result),
false);
325 std::stringstream componentName;
326 componentName <<
"RemoteState_" <<
getLocalUniqueId() <<
"_" << proxyName <<
"_"
327 << globalStateIdentifier;
328 return componentName.str();
358 stateName +
" is NULL");
369 stateName +
" is NULL");
377 const EventBasePtr& event,
378 const Ice::Current&
c)
387 stateName +
" is NULL");
399 stateName +
" is NULL");
418 stateName +
" is NULL");
434 if (!stateOffererPrx || remoteStateId == -1)
441 return stateOffererPrx->hasSubstatesRemote(stateClassName);
452 if (!stateOffererPrx || remoteStateId == -1)
459 return stateOffererPrx->hasActiveSubstateRemote(remoteStateId);
472 if (remoteStateId != -1)
474 inputParameters = stateOffererPrx->getRemoteInputParametersById(remoteStateId);
478 inputParameters = stateOffererPrx->getRemoteInputParameters(stateClassName);
491 if (stateOffererPrx &&
494 if (remoteStateId != -1)
496 outputParameters = stateOffererPrx->getRemoteOutputParametersById(remoteStateId);
500 outputParameters = stateOffererPrx->getRemoteOutputParameters(stateClassName);
505 return outputParameters;
511 if (remoteStateId == -1 || !stateOffererPrx)
516 return StateBasePtr::dynamicCast(stateOffererPrx->getStatechartInstance(remoteStateId));
522 auto start = IceUtil::Time::now();
527 double waitTime = (IceUtil::Time::now() - start).toMilliSecondsDouble();
529 eManagedIceObjectStarted, timeoutMS < 0 ? -1 :
std::max(0.0, timeoutMS - waitTime));
535 return initialized &&
getState() >= eManagedIceObjectStarted;
545 <<
"', but it is not reachable yet!";
555 if (lock.owns_lock())
559 ARMARX_DEBUG <<
"input for remotestate " << stateName <<
" (" << remoteStateId
563 stateOffererPrx->callRemoteState(remoteStateId,
566 catch (Ice::Exception& e)
569 <<
"::baseOnEnter(): " << e.what() <<
"\n"
570 << e.ice_stackTrace() <<
flush;
572 catch (std::exception& e)
575 <<
"::baseOnEnter(): " << e.what() <<
"\n"
598 if (remoteStateId == -1)
605 bool result = stateOffererPrx->breakRemoteState(remoteStateId, evt);
607 outputParameters = stateOffererPrx->getRemoteOutputParametersById(remoteStateId);
625 stateOffererPrx->exitRemoteState(remoteStateId);
626 outputParameters = stateOffererPrx->getRemoteOutputParametersById(remoteStateId);
636 ARMARX_DEBUG <<
"notifying state with id " << remoteStateId
637 <<
" eventBuffered:" << std::string((eventBuffered) ?
"true" :
"false")
640 if (remoteStateId != -1 && stateOffererPrx)
642 stateOffererPrx->begin_notifyEventBufferedDueToUnbreakableStateRemote(remoteStateId,
650 if (remoteStateId != -1 && stateOffererPrx)
652 StateIceBasePtr state = stateOffererPrx->refetchRemoteSubstates(remoteStateId);
653 subStateList = state->subStateList;
654 transitions = state->transitions;
655 activeSubstate = state->activeSubstate;
656 initState = state->initState;
664 if (remoteStateId != -1 && stateOffererPrx)
667 auto pos =
id.find_last_of(
">");
668 if (pos != std::string::npos)
670 id.erase(
id.find_last_of(
">") - 1);
672 stateOffererPrx->updateGlobalStateIdRecursive(remoteStateId,
id);
681 return stateOffererPrx->breakActiveSubstateRemotely(remoteStateId, event);
689 <<
", parentState Ice ID: "
690 << (parentState ? parentState->ice_id() :
"(null)");