38 #include <boost/regex.hpp>
45 using namespace StateUtilFunctions;
57 impl->visitCounter = 0;
58 impl->context =
nullptr;
59 impl->manager =
nullptr;
61 setTag(std::string(
"Statechart"));
63 initialStateMapping =
nullptr;
69 (*
impl->stateInstancesPtr)[
impl->localUniqueId] =
this;
80 impl->__useRunFunction =
true;
81 impl->__parentState =
nullptr;
82 impl->visitCounter = 0;
83 impl->context =
nullptr;
84 impl->manager =
nullptr;
86 setTag(std::string(
"Statechart"));
87 initialStateMapping =
nullptr;
95 (*
impl->stateInstancesPtr)[
impl->localUniqueId] =
this;
109 for (
unsigned int i = 0; i < subStateList.size(); i++)
111 RemoteStatePtr remoteStatePtr = RemoteStatePtr::dynamicCast(subStateList.at(i));
114 && remoteStatePtr->getArmarXManager())
120 remoteStatePtr->getArmarXManager()->removeObjectNonBlocking(remoteStatePtr->getName());
130 impl->stateInstancesPtr->erase(
impl->localUniqueId);
142 hint =
"This function must be called in defineSubstates().";
146 hint =
"This function must be called in defineParameters().";
151 hint =
"This function must be called in defineState().";
156 hint =
"This function must be called in onEnter().";
164 std::stringstream typeStr;
165 typeStr << (int)
getStatePhase() <<
"/" << int(allowedType) ;
166 throw LocalException(
"It is not allowed to call the function " + std::string(functionName) +
" here! (Current Phase/Allowed Phase): " + typeStr.str() +
") " + hint);
172 if (!std::any_of(allowedTypes.begin(), allowedTypes.end(), [&](
StatePhase value)
174 return value == getStatePhase();
179 for (
auto& allowedType : allowedTypes)
188 hint +=
"defineSubstates()";
192 hint +=
"defineParameters()";
197 hint +=
"defineState()";
215 hint =
"\nThis function must be called in " + hint;
218 std::stringstream typeStr;
220 throw LocalException(
"It is not allowed to call the function " + std::string(functionName) +
" here! (Current Phase: " + typeStr.str() +
") " + hint);
229 std::stringstream typeStr;
230 typeStr << (int)
getStatePhase() <<
"/" << int(allowedType) ;
231 throw LocalException(
"It is not allowed to call the function " + std::string(functionName) +
" here! (Current Phase/min. Allowed Phase): " + typeStr.str() +
") ");
250 impl->__parentState = parentState;
256 if (
impl->__parentState)
258 if (!
impl->__parentState->globalStateIdentifier.empty())
260 globalStateIdentifier =
impl->__parentState->getGlobalHierarchyString() +
"->" + stateName;
269 globalStateIdentifier = stateName;
277 for (
unsigned int i = 0; i < subStateList.size(); i++)
279 StateBasePtr::dynamicCast(subStateList.at(i))->__updateGlobalStateIdRecursive();
286 initialized = enable;
287 impl->initCondition.notify_all();
292 if (subStateList.size() > 0)
302 boost::recursive_mutex::scoped_lock lock(
impl->__processEventMutex);
304 if (activeSubstate._ptr)
320 if (!sourceState.initialized)
331 if (sourceState.initialStateMapping)
333 initialStateMapping = PMPtr::dynamicCast(sourceState.initialStateMapping)->clone();
336 impl->__useRunFunction = sourceState.
impl->__useRunFunction;
338 impl->statePhase = sourceState.
impl->statePhase;
339 impl->__parentState =
nullptr;
340 activeSubstate =
nullptr;
342 impl->manager = sourceState.
impl->manager;
343 impl->cancelEnteringSubstates = sourceState.
impl->cancelEnteringSubstates;
345 impl->triggeredEndstateEvent = sourceState.
impl->triggeredEndstateEvent;
347 if (sourceState.subStateList.size() > 0)
349 for (
unsigned int i = 0; i < sourceState.subStateList.size(); i++)
351 StateBasePtr curSubstate = StateBasePtr::dynamicCast(sourceState.subStateList.at(i))->clone();
352 subStateList.at(i) = curSubstate;
354 if (!curSubstate._ptr)
356 throw LocalException(
"StatePtrePtr::dynamicCast failed in deepCopy() in file " + std::string(__FILE__));
359 curSubstate->impl->__parentState =
this;
361 if (sourceState.initState._ptr == sourceState.subStateList.at(i)._ptr)
363 initState = curSubstate;
366 if (sourceState.activeSubstate._ptr == sourceState.subStateList.at(i)._ptr)
368 activeSubstate = curSubstate;
373 for (
unsigned int j = 0; j < sourceState.transitions.size(); j++)
375 if (sourceState.transitions[j].mappingToNextStatesInput)
377 transitions[j].mappingToNextStatesInput = PMPtr::dynamicCast(sourceState.transitions[j].mappingToNextStatesInput)->clone();
380 if (sourceState.transitions[j].mappingToParentStatesLocal)
382 transitions[j].mappingToParentStatesLocal = PMPtr::dynamicCast(sourceState.transitions[j].mappingToParentStatesLocal)->clone();
385 if (sourceState.transitions[j].mappingToParentStatesOutput)
387 transitions[j].mappingToParentStatesOutput = PMPtr::dynamicCast(sourceState.transitions[j].mappingToParentStatesOutput)->clone();
390 if (sourceState.transitions[j].sourceState._ptr == sourceState.subStateList.at(i)._ptr)
392 transitions[j].sourceState = curSubstate;
395 if (sourceState.transitions[j].destinationState._ptr == sourceState.subStateList.at(i)._ptr)
397 transitions[j].destinationState = curSubstate;
404 activeSubstate =
nullptr;
424 ARMARX_WARNING <<
"The StatechartContext should not be null" << std::endl;
429 ARMARX_WARNING <<
"The StatechartManager should not be null" << std::endl;
432 this->
impl->manager = manager;
433 this->
impl->context = context;
438 setTag(
"State: " + stateName);
450 if (subStateList.size() > 0)
471 activeSubstate =
nullptr;
479 if (!
impl->context && checkNULL)
484 return impl->context;
502 impl->__useRunFunction =
false;
515 this->
impl->context = context;
520 return outputParameters;
530 return impl->localUniqueId;
535 return stateClassName;
540 StateIceBase* curParent =
impl->__parentState;
545 result = curParent->stateName +
"->" + result;
546 curParent = StateBasePtr::dynamicCast(curParent)->impl->__parentState;
556 return globalStateIdentifier;
566 if (!
impl->initCondition.timed_wait(lock, boost::posix_time::milliseconds(timeoutMS)))
573 impl->initCondition.wait(lock);
590 VariantContainerBasePtr variantContainer =
new SingleVariant(
static_cast<const Variant&
>(variant));
591 VariantContainerBasePtr defaultContainer;
595 const auto&
data = *defaultValue;
599 return addParameterContainer(paramMap, key, *variantContainer->getContainerType(), optional, defaultContainer);
606 throw LocalException(
"The key-string of a parameter must not be empty.");
609 const boost::regex e(
"^([a-zA-Z0-9_\\.]+)$");
611 if (!boost::regex_match(key, e))
613 throw LocalException(
"Invalid character in new key '" + key +
"'. Only a-zA-Z0-9_ are allowed.");
627 if (containerType.subType)
643 param->value->setContainerType(containerType.clone());
647 param->defaultValue = defaultValue->cloneContainer();
650 param->optionalParam = optional;
653 if (paramMap.find(key) != paramMap.end())
658 paramMap[key] = param;
664 StateParameterMap::iterator it = paramMap.find(key);
666 if (it == paramMap.end())
675 + key +
"' with type '"
677 +
"' to another type of a Variant ("
678 + it->second->value->getContainerType()->typeId +
")!");
681 it->second->set =
true;
692 StateParameterMap::iterator it = paramMap.find(key);
694 if (it == paramMap.end())
699 if (valueContainer.getSize() > 0 &&
VariantContainerType::allTypesToString(it->second->value->getContainerType()).find(::armarx::InvalidVariantData::ice_staticId()) == std::string::npos)
703 + key +
"' with type '"
705 +
"' to another type of container ("
708 auto type = it->second->value->getContainerType();
709 it->second->value = valueContainer.cloneContainer();
710 it->second->value->setContainerType(type);
711 it->second->set =
true;
716 StateParameterMap::const_iterator it = paramMap.find(key);
718 if (it == paramMap.end())
723 if (!it->second->set)
725 throw LocalException(
"Requested parameter '" + key +
"' was not set in state " + stateName);
728 valueContainer = it->second->value;
733 StateParameterMap::const_iterator it = paramMap.find(key);
735 if (it == paramMap.end())
737 throw LocalException(
"Requested parameter '" + key +
"' not found in state " + stateName);
740 return it->second->set;
745 std::string parameters;
747 for (StateParameterMap::const_iterator it = paramMap.begin(); it != paramMap.end(); it++, parameters +=
",\n")
757 for (
size_t i = 0; i <
impl->inputInheritance.size(); i++)
765 for (StateParameterMap::iterator it = substateInput.begin(); it != substateInput.end(); it++)
767 StateParameterIceBasePtr param = it->second;
768 addParameterContainer(inputParameters,
impl->inputInheritance.at(i) +
"." + it->first, *param->value->getContainerType(), param->optionalParam);
776 for (StateParameterMap::iterator i = inputParameters.begin(); i != inputParameters.end(); i++)
778 StateParameterIceBasePtr p = i->second;
782 p->value = p->defaultValue->cloneContainer();
790 for (
unsigned int i = 0; i < subStateList.size(); i++)
792 if (StateBasePtr::dynamicCast(subStateList.at(i))->stateName == substateName)
794 return StateBasePtr::dynamicCast(subStateList.at(i));
803 StateParameterMap::const_iterator it = paramMap.find( key);
805 if (it == paramMap.end())
810 if (!it->second->set)
812 throw LocalException(
"Requested parameter '" + key +
"' was not set in state " + stateName);
818 throw InvalidTypeException(
"Parameter '" + key +
"' is not a single variant!");
827 stateClassName = className;
832 for (
auto s : subStateList)
835 state->refetchSubstates();
841 return impl->triggeredEndstateEvent;
847 return impl->statePhase;
853 impl->statePhase = newPhase;
860 result.insert(inputSetValues.begin(), inputSetValues.end());
868 throw LocalException(
"The toplevelState must not be NULL");
871 std::vector<StateBasePtr> activeStates;
873 boost::recursive_mutex::scoped_lock lock(toplevelState->impl->__processEventMutex);
875 while (activeState->activeSubstate)
877 activeState = StateBasePtr::dynamicCast(activeState->activeSubstate);
880 activeStates.push_back(activeState);
889 impl->cancelEnteringSubstates =
false;
893 eventsDelayed =
false;
894 greedyInputDictionary =
false;
896 inputParameters.clear();
897 localParameters.clear();
898 outputParameters.clear();
899 subStateList.clear();
901 initialStateMapping =
nullptr;
903 activeSubstate =
nullptr;
904 impl->__parentState =
nullptr;
905 impl->triggeredEndstateEvent =
nullptr;