41 #include <boost/regex.hpp>
45 using namespace StateUtilFunctions;
55 impl->visitCounter = 0;
56 impl->context =
nullptr;
57 impl->manager =
nullptr;
59 setTag(std::string(
"Statechart"));
61 initialStateMapping =
nullptr;
67 (*
impl->stateInstancesPtr)[
impl->localUniqueId] =
this;
78 impl->__useRunFunction =
true;
79 impl->__parentState =
nullptr;
80 impl->visitCounter = 0;
81 impl->context =
nullptr;
82 impl->manager =
nullptr;
84 setTag(std::string(
"Statechart"));
85 initialStateMapping =
nullptr;
93 (*
impl->stateInstancesPtr)[
impl->localUniqueId] =
this;
107 for (
unsigned int i = 0; i < subStateList.size(); i++)
109 RemoteStatePtr remoteStatePtr = RemoteStatePtr::dynamicCast(subStateList.at(i));
111 if (remoteStatePtr &&
113 ->getArmarXManager())
119 remoteStatePtr->getArmarXManager()->removeObjectNonBlocking(
120 remoteStatePtr->getName());
131 impl->stateInstancesPtr->erase(
impl->localUniqueId);
144 hint =
"This function must be called in defineSubstates().";
148 hint =
"This function must be called in defineParameters().";
153 hint =
"This function must be called in defineState().";
158 hint =
"This function must be called in onEnter().";
166 std::stringstream typeStr;
168 throw LocalException(
169 "It is not allowed to call the function " + std::string(functionName) +
170 " here! (Current Phase/Allowed Phase): " + typeStr.str() +
") " + hint);
176 const char* functionName)
const
178 if (!std::any_of(allowedTypes.begin(),
184 for (
auto& allowedType : allowedTypes)
193 hint +=
"defineSubstates()";
197 hint +=
"defineParameters()";
202 hint +=
"defineState()";
218 hint =
"\nThis function must be called in " + hint;
221 std::stringstream typeStr;
223 throw LocalException(
"It is not allowed to call the function " +
224 std::string(functionName) +
225 " here! (Current Phase: " + typeStr.str() +
") " + hint);
234 std::stringstream typeStr;
236 throw LocalException(
237 "It is not allowed to call the function " + std::string(functionName) +
238 " here! (Current Phase/min. Allowed Phase): " + typeStr.str() +
") ");
254 impl->__parentState = parentState;
261 if (
impl->__parentState)
263 if (!
impl->__parentState->globalStateIdentifier.empty())
265 globalStateIdentifier =
266 impl->__parentState->getGlobalHierarchyString() +
"->" + stateName;
270 globalStateIdentifier =
276 globalStateIdentifier = stateName;
285 for (
unsigned int i = 0; i < subStateList.size(); i++)
287 StateBasePtr::dynamicCast(subStateList.at(i))->__updateGlobalStateIdRecursive();
295 initialized = enable;
296 impl->initCondition.notify_all();
302 if (subStateList.size() > 0)
313 boost::recursive_mutex::scoped_lock lock(
impl->__processEventMutex);
315 if (activeSubstate._ptr)
328 if (!sourceState.initialized)
339 if (sourceState.initialStateMapping)
341 initialStateMapping = PMPtr::dynamicCast(sourceState.initialStateMapping)->clone();
344 impl->__useRunFunction = sourceState.
impl->__useRunFunction;
346 impl->statePhase = sourceState.
impl->statePhase;
347 impl->__parentState =
nullptr;
348 activeSubstate =
nullptr;
350 impl->manager = sourceState.
impl->manager;
351 impl->cancelEnteringSubstates = sourceState.
impl->cancelEnteringSubstates;
353 impl->triggeredEndstateEvent = sourceState.
impl->triggeredEndstateEvent;
355 if (sourceState.subStateList.size() > 0)
357 for (
unsigned int i = 0; i < sourceState.subStateList.size(); i++)
360 StateBasePtr::dynamicCast(sourceState.subStateList.at(i))->clone();
361 subStateList.at(i) = curSubstate;
363 if (!curSubstate._ptr)
365 throw LocalException(
366 "StatePtrePtr::dynamicCast failed in deepCopy() in file " +
367 std::string(__FILE__));
370 curSubstate->impl->__parentState =
this;
372 if (sourceState.initState._ptr == sourceState.subStateList.at(i)._ptr)
374 initState = curSubstate;
377 if (sourceState.activeSubstate._ptr == sourceState.subStateList.at(i)._ptr)
379 activeSubstate = curSubstate;
384 for (
unsigned int j = 0; j < sourceState.transitions.size(); j++)
386 if (sourceState.transitions[j].mappingToNextStatesInput)
388 transitions[j].mappingToNextStatesInput =
390 sourceState.transitions[j].mappingToNextStatesInput)
394 if (sourceState.transitions[j].mappingToParentStatesLocal)
396 transitions[j].mappingToParentStatesLocal =
398 sourceState.transitions[j].mappingToParentStatesLocal)
402 if (sourceState.transitions[j].mappingToParentStatesOutput)
404 transitions[j].mappingToParentStatesOutput =
406 sourceState.transitions[j].mappingToParentStatesOutput)
410 if (sourceState.transitions[j].sourceState._ptr ==
411 sourceState.subStateList.at(i)._ptr)
413 transitions[j].sourceState = curSubstate;
416 if (sourceState.transitions[j].destinationState._ptr ==
417 sourceState.subStateList.at(i)._ptr)
419 transitions[j].destinationState = curSubstate;
426 activeSubstate =
nullptr;
445 ARMARX_WARNING <<
"The StatechartContext should not be null" << std::endl;
450 ARMARX_WARNING <<
"The StatechartManager should not be null" << std::endl;
453 this->
impl->manager = manager;
454 this->
impl->context = context;
459 setTag(
"State: " + stateName);
471 if (subStateList.size() > 0)
489 stateName +
"' was not set!");
493 activeSubstate =
nullptr;
501 if (!
impl->context && checkNULL)
506 return impl->context;
523 impl->__useRunFunction =
535 this->
impl->context = context;
541 return outputParameters;
553 return impl->localUniqueId;
559 return stateClassName;
565 StateIceBase* curParent =
impl->__parentState;
570 result = curParent->stateName +
"->" + result;
571 curParent = StateBasePtr::dynamicCast(curParent)->impl->__parentState;
582 return globalStateIdentifier;
593 if (!
impl->initCondition.timed_wait(lock,
594 boost::posix_time::milliseconds(timeoutMS)))
601 impl->initCondition.wait(lock);
616 const std::string& key,
624 VariantContainerBasePtr variantContainer =
626 VariantContainerBasePtr defaultContainer;
630 const auto&
data = *defaultValue;
635 paramMap, key, *variantContainer->getContainerType(), optional, defaultContainer);
640 const std::string& key,
641 const ContainerType& containerType,
643 VariantContainerBasePtr defaultValue)
const
647 throw LocalException(
"The key-string of a parameter must not be empty.");
650 const boost::regex e(
"^([a-zA-Z0-9_\\.]+)$");
652 if (!boost::regex_match(key, e))
654 throw LocalException(
"Invalid character in new key '" + key +
655 "'. Only a-zA-Z0-9_ are allowed.");
669 if (containerType.subType)
684 param->value->setContainerType(containerType.clone());
688 param->defaultValue = defaultValue->cloneContainer();
691 param->optionalParam = optional;
694 if (paramMap.find(key) != paramMap.end())
699 paramMap[key] = param;
705 const std::string& key,
708 StateParameterMap::iterator it = paramMap.find( key);
710 if (it == paramMap.end())
717 if ((it->second->value->getContainerType()->typeId !=
720 "Cannot assign the parameter '" + key +
"' with type '" +
722 it->second->value->getContainerType()->typeId +
")!");
725 it->second->set =
true;
730 const std::string& key,
731 const VariantContainerBasePtr& valueContainer)
738 const std::string& key,
739 const VariantContainerBase& valueContainer)
741 StateParameterMap::iterator it = paramMap.find( key);
743 if (it == paramMap.end())
748 if (valueContainer.getSize() > 0 &&
750 .find(::armarx::InvalidVariantData::ice_staticId()) == std::string::npos)
753 valueContainer.getContainerType()))
755 "Cannot assign the parameter container '" + key +
"' with type '" +
757 "' to another type of container (" +
761 auto type = it->second->value->getContainerType();
762 it->second->value = valueContainer.cloneContainer();
763 it->second->value->setContainerType(type);
764 it->second->set =
true;
769 const std::string& key,
770 VariantContainerBasePtr& valueContainer)
const
772 StateParameterMap::const_iterator it = paramMap.find(key);
774 if (it == paramMap.end())
779 if (!it->second->set)
781 throw LocalException(
"Requested parameter '" + key +
"' was not set in state " +
785 valueContainer = it->second->value;
791 StateParameterMap::const_iterator it = paramMap.find(key);
793 if (it == paramMap.end())
795 throw LocalException(
"Requested parameter '" + key +
"' not found in state " +
799 return it->second->set;
804 const std::string& key)
const
806 std::string parameters;
808 for (StateParameterMap::const_iterator it = paramMap.begin(); it != paramMap.end();
809 it++, parameters +=
",\n")
817 stateName, key,
"Available parameters:\n" + parameters);
823 for (
size_t i = 0; i <
impl->inputInheritance.size(); i++)
831 for (StateParameterMap::iterator it = substateInput.begin();
832 it != substateInput.end();
835 StateParameterIceBasePtr param = it->second;
837 impl->inputInheritance.at(i) +
"." + it->first,
838 *param->value->getContainerType(),
839 param->optionalParam);
848 for (StateParameterMap::iterator i = inputParameters.begin(); i != inputParameters.end();
851 StateParameterIceBasePtr p = i->second;
855 p->value = p->defaultValue->cloneContainer();
864 for (
unsigned int i = 0; i < subStateList.size(); i++)
866 if (StateBasePtr::dynamicCast(subStateList.at(i))->stateName == substateName)
868 return StateBasePtr::dynamicCast(subStateList.at(i));
877 const std::string& key,
880 StateParameterMap::const_iterator it = paramMap.find( key);
882 if (it == paramMap.end())
887 if (!it->second->set)
889 throw LocalException(
"Requested parameter '" + key +
"' was not set in state " +
896 throw InvalidTypeException(
"Parameter '" + key +
"' is not a single variant!");
906 stateClassName = className;
912 for (
auto s : subStateList)
915 state->refetchSubstates();
922 return impl->triggeredEndstateEvent;
929 return impl->statePhase;
936 impl->statePhase = newPhase;
939 StringVariantContainerBaseMap
943 StringVariantContainerBaseMap inputSetValues =
945 result.insert(inputSetValues.begin(), inputSetValues.end());
949 std::vector<StateBasePtr>
954 throw LocalException(
"The toplevelState must not be NULL");
957 std::vector<StateBasePtr> activeStates;
959 boost::recursive_mutex::scoped_lock lock(toplevelState->impl->__processEventMutex);
961 while (activeState->activeSubstate)
963 activeState = StateBasePtr::dynamicCast(activeState->activeSubstate);
966 activeStates.push_back(activeState);
973 impl->cancelEnteringSubstates =
false;
977 eventsDelayed =
false;
978 greedyInputDictionary =
false;
980 inputParameters.clear();
981 localParameters.clear();
982 outputParameters.clear();
983 subStateList.clear();
985 initialStateMapping =
nullptr;
987 activeSubstate =
nullptr;
988 impl->__parentState =
nullptr;
989 impl->triggeredEndstateEvent =
nullptr;