30 #include <IceUtil/UUID.h>
38 margin(30, 140, 30, 30),
44 UUID = uuid.isEmpty() ? QString::fromStdString(IceUtil::generateUUID()) : uuid;
59 for (StateInstanceMap::const_iterator i =
substates.begin(); i !=
substates.end(); ++i)
61 std::shared_ptr<RegularState> regularState = std::dynamic_pointer_cast<RegularState>(*i);
63 if (regularState && !regularState->getStateClass())
65 const QString& substateUUID = regularState->getClassUUID();
67 if (uuidStateMap.contains(substateUUID))
69 regularState->setStateClass(uuidStateMap[substateUUID]);
84 result.insert(p.first, p.second);
95 if (withStartTransition || t->sourceState)
133 if (substate->getType() == eFinalState)
138 if (event->name == substate->getInstanceName())
147 evt->name = substate->getInstanceName();
148 events.push_back(evt);
187 if (instance->getStateClass())
232 QSizeF adjustedNewSize(newSize.width() +
margin.left() +
margin.width(),
251 if (instanceName.length() == 0)
253 instanceName = newSubstate->getStateName();
267 if (pos.x() != 0 && pos.y() != 0)
269 instance->setPosition(pos);
273 addDetachedTransitions(instance);
288 if (instanceName.length() == 0)
290 instanceName = newRemoteSubstate->getStateName();
301 if (pos.x() != 0 && pos.y() != 0)
303 instance->setPosition(pos);
307 addDetachedTransitions(instance);
322 if (instanceName.length() == 0)
324 instanceName = state->getStateName();
336 if (newstateInstance)
339 if (pos.x() != 0 && pos.y() != 0)
341 newstateInstance->setPosition(pos);
346 addDetachedTransitions(newstateInstance);
349 return newstateInstance;
360 if (pos.x() != 0 && pos.y() != 0)
362 instance->setPosition(pos);
377 if (stateInstance->getStateClass() && !
checkSubstate(stateInstance->getStateClass()))
382 substates.insert(stateInstance->getInstanceName(), stateInstance);
393 return stateInstance;
407 if (t->destinationState == newStartState)
413 t->destinationState = newStartState;
414 t->supportPoints.controlPoints.clear();
415 t->supportPoints.endPoint.reset();
416 t->supportPoints.startPoint.reset();
431 if (t->mappingToNextStatesInput == newStartStateInputMapping)
437 t->mappingToNextStatesInput = newStartStateInputMapping;
449 StateInstanceMap::iterator it =
substates.find(oldName);
453 EndStatePtr endState = std::dynamic_pointer_cast<EndState>(it.value());
460 it.value()->setInstanceName(newName);
461 StateInstanceMap::iterator newIt =
substates.insert(newName, it.value());
489 if (evt->name == eventName)
499 StateInstanceMap::iterator it =
substates.find(stateInstanceName);
506 && t->sourceState == it.value()
507 && t->destinationState == it.value()
512 else if (t->destinationState == it.value() && t->sourceState)
516 else if (t->destinationState == it.value())
520 else if (t->sourceState == it.value())
526 EndStatePtr endState = std::dynamic_pointer_cast<EndState>(it.value());
546 StateInstanceMap::iterator it =
substates.find(stateInstanceName);
551 if (newInstance->getStateClass() && !
checkSubstate(newInstance->getStateClass()))
556 newInstance->setPosition(it.value()->getTopLeft());
574 if (instance->getStateClass())
580 addDetachedTransitions(instance);
628 auto keys = newInputParameters.keys();
630 for (
const auto& key : keys)
634 throw LocalException(
"Key ") << key <<
" is already used in localParameters in state " <<
stateName;
645 auto keys = newLocalParameters.keys();
647 for (
const auto& key : keys)
651 throw LocalException(
"Key ") << key <<
" is already used in inputParameters in state " <<
stateName;
687 t->mappingToNextStatesInput = mappingToNextStateInput;
688 t->mappingToParentStatesLocal = mappingToParentLocal;
689 t->mappingToParentStatesOutput = mappingToParentOutput;
694 throw LocalException(
"Could not find transition in state");
704 auto oldPoints = t->supportPoints.toPointList();
706 bool changed = newPoints.size() != oldPoints.size();
710 int size = oldPoints.size();
712 for (
int i = 0; i <
size; ++i)
714 if ((oldPoints.at(i) - newPoints.at(i)).manhattanLength() > 2)
722 t->labelCenterPosition = labelCenterPosition;
723 t->labelFontPointSize = labelFontPointSize;
724 t->supportPoints = points;
729 throw LocalException(
"Could not find transition in state");
744 t->transitionUserCode =
enabled;
749 throw LocalException(
"Could not find transition in state");
761 t->sourceState = sourceState;
762 t->eventName = eventName;
764 QPointF lastControlPoint = calcDetachedTransitionLastControlPoint(sourceState);
765 t->supportPoints.controlPoints.append(lastControlPoint);
766 t->supportPoints.endPoint = std::make_shared<QPointF>(calcDetachedTransitionEndPoint(sourceState, lastControlPoint));
774 if (t.get() == transition.get())
776 if (transition->destinationState == newDest)
782 t->destinationState = newDest;
784 if (t->destinationState == t->sourceState)
786 QPointF p = calcDetachedTransitionLastControlPoint(t->sourceState);
788 controlPoints.push_back(p - QPointF(30, 30));
789 controlPoints.push_back(p);
790 controlPoints.push_back(p + QPointF(30, 30));
792 t->supportPoints.controlPoints = controlPoints;
796 t->supportPoints.controlPoints.clear();
797 t->supportPoints.endPoint.reset();
798 t->supportPoints.startPoint.reset();
802 if (!t->destinationState->getStateClass())
821 ARMARX_INFO <<
"Detaching transition " << t->eventName;
825 t->supportPoints.endPoint = std::make_shared<QPointF>(calcDetachedTransitionEndPoint(t->sourceState, floatingEndPoint));
827 t->destinationState.reset();
828 t->labelCenterPosition.reset();
836 if (transition->sourceState)
899 auto checkEventExistsInSubstates = [&,
this](
EventPtr & e)
903 if (substate->getType() == eFinalState)
905 EndStateCPtr endstate = std::dynamic_pointer_cast<const EndState>(substate);
907 if (endstate && endstate->getEventName() == e->name)
926 foreach (
EventPtr ev, outgoingEvents)
929 foreach (
EventPtr evOld, oldTransitions)
931 if (evOld->name == ev->name)
937 if (!found && !checkEventExistsInSubstates(ev))
943 foreach (
EventPtr evOld, oldTransitions)
946 foreach (
EventPtr ev, outgoingEvents)
948 if (evOld->name == ev->name)
954 if (!found && !checkEventExistsInSubstates(evOld))
974 QList<StateInstancePtr> instances =
getInstances(stateClass);
984 ARMARX_INFO_S <<
"Removing transitions for event " << eventName;
985 QList<StateInstancePtr> instances =
getInstances(stateClass);
1030 void State::setDirty(
bool dirty)
1032 if (this->dirty !=
dirty)
1037 this->dirty =
dirty;
1042 QList<StateInstancePtr> result;
1046 if (
s.value()->getStateClass() == stateClass)
1048 result.push_back(
s.value());
1059 if (t->eventName == eventName && t->sourceState == sourceInstance)
1098 ARMARX_WARNING <<
"Transition with event " << transition->eventName <<
" for state " << transition->sourceState->getInstanceName() <<
" already exists";
1102 if (!transition->destinationState && transition->supportPoints.controlPoints.size() == 0)
1104 ARMARX_WARNING <<
"If no destination is set for a transition, it must have 1 support point";
1108 if (!transition->sourceState)
1121 if (
getUUID() == newState->getUUID())
1147 if (t->eventName == eventName && t->sourceState->getInstanceName() == transitionSourceName && t->destinationState->getInstanceName() == transitionDestinationName)
1169 if (!state->getStateClass())
1174 if (state->getStateClass()->getUUID() == sC->getUUID())
1179 if (state->getStateClass()->hasDescendant(sC))
1193 return "Normal State";
1197 return "Remote State";
1200 case eDynamicRemoteState:
1201 return "Dynamic Remote State";
1205 return "Final State";
1213 return "Unknown State Type";
1219 if (!instance->getStateClass())
1224 QList<EventPtr> events = instance->getStateClass()->getAllEvents();
1226 float angleStep = 20;
1227 float length = instance->getClassSize().width() * instance->getScale() * 0.8f;
1228 QPointF center = instance->getBounds().center();
1229 int count = events.size();
1230 float startAngle = angleStep * (count - 1) / 2.0f;
1232 float angle = startAngle;
1237 t->sourceState = instance;
1238 t->eventName =
event->name;
1239 t->supportPoints.append(center + QPointF(cos(
angle / 180.0 *
M_PI) * length, sin(
angle / 180.0 *
M_PI) * length));
1245 QPointF State::calcDetachedTransitionLastControlPoint(
StateInstancePtr instance)
const
1248 float angle = ((double)(rand() % 360));
1249 float length =
std::max(instance->getClassSize().width(), instance->getClassSize().height());
1250 length *= instance->getScale() * 0.8;
1252 p = instance->getBounds().center();
1255 p.setX(p.x() + cos(
angle / 180.0 *
M_PI) * length);
1256 p.setY(p.y() + sin(
angle / 180.0 *
M_PI) * length);
1260 QPointF State::calcDetachedTransitionEndPoint(
StateInstancePtr instance,
const QPointF& lastControlPoint)
const
1262 QPointF line = lastControlPoint - instance->getBounds().center();
1263 QPointF p = line * 0.1 + lastControlPoint;
1272 if (t && t->sourceState && t->destinationState)
1275 QPointF p1 = t->sourceState->getBounds().center();
1276 QPointF p2 = t->destinationState->getBounds().center();
1279 QPointF dirU = p2 - p1;
1280 QPointF dirV = QPointF(dirU.y(), -dirU.x());
1281 supportPoints.push_back(p1 + dirU * u / 100 + dirV *
v / 100);
1282 t->supportPoints.setControlPoints(supportPoints);