27 #include <IceUtil/UUID.h>
40 margin(30, 140, 30, 30),
46 UUID = uuid.isEmpty() ? QString::fromStdString(IceUtil::generateUUID()) : uuid;
74 for (StateInstanceMap::const_iterator i =
substates.begin(); i !=
substates.end(); ++i)
76 std::shared_ptr<RegularState> regularState =
77 std::dynamic_pointer_cast<RegularState>(*i);
79 if (regularState && !regularState->getStateClass())
81 const QString& substateUUID = regularState->getClassUUID();
83 if (uuidStateMap.contains(substateUUID))
85 regularState->setStateClass(uuidStateMap[substateUUID]);
101 result.insert(p.first, p.second);
113 if (withStartTransition || t->sourceState)
155 if (substate->getType() == eFinalState)
160 if (event->name == substate->getInstanceName())
169 evt->name = substate->getInstanceName();
170 events.push_back(evt);
210 if (instance->getStateClass())
212 connect(instance->getStateClass().get(),
218 Qt::UniqueConnection);
263 QSizeF adjustedNewSize(newSize.width() +
margin.left() +
margin.width(),
284 if (instanceName.length() == 0)
286 instanceName = newSubstate->getStateName();
300 if (pos.x() != 0 && pos.y() != 0)
302 instance->setPosition(pos);
305 connect(newSubstate.get(),
311 Qt::UniqueConnection);
312 addDetachedTransitions(instance);
320 const QString& remoteStateOffererName,
321 QString instanceName,
331 if (instanceName.length() == 0)
333 instanceName = newRemoteSubstate->getStateName();
337 newRemoteSubstate, instanceName, remoteStateOffererName, shared_from_this()));
344 if (pos.x() != 0 && pos.y() != 0)
346 instance->setPosition(pos);
349 connect(newRemoteSubstate.get(),
355 Qt::UniqueConnection);
356 addDetachedTransitions(instance);
372 if (instanceName.length() == 0)
374 instanceName = state->getStateName();
387 if (newstateInstance)
390 if (pos.x() != 0 && pos.y() != 0)
392 newstateInstance->setPosition(pos);
395 connect(newstateInstance->getStateClass().get(),
399 Qt::UniqueConnection);
401 addDetachedTransitions(newstateInstance);
404 return newstateInstance;
415 if (pos.x() != 0 && pos.y() != 0)
417 instance->setPosition(pos);
433 if (stateInstance->getStateClass() && !
checkSubstate(stateInstance->getStateClass()))
438 substates.insert(stateInstance->getInstanceName(), stateInstance);
448 return stateInstance;
462 if (t->destinationState == newStartState)
468 t->destinationState = newStartState;
469 t->supportPoints.controlPoints.clear();
470 t->supportPoints.endPoint.reset();
471 t->supportPoints.startPoint.reset();
487 if (t->mappingToNextStatesInput == newStartStateInputMapping)
493 t->mappingToNextStatesInput = newStartStateInputMapping;
506 StateInstanceMap::iterator it =
substates.find(oldName);
510 EndStatePtr endState = std::dynamic_pointer_cast<EndState>(it.value());
515 endState->getEventName(), shared_from_this(),
eRemoved);
518 it.value()->setInstanceName(newName);
519 StateInstanceMap::iterator newIt =
substates.insert(newName, it.value());
525 endState->getEventName(), shared_from_this(),
eAdded);
550 if (evt->name == eventName)
561 StateInstanceMap::iterator it =
substates.find(stateInstanceName);
567 if (t->sourceState &&
570 && t->destinationState == it.value())
574 else if (t->destinationState == it.value() && t->sourceState)
577 t, calcDetachedTransitionLastControlPoint(t->sourceState));
579 else if (t->destinationState == it.value())
583 else if (t->sourceState == it.value())
588 EndStatePtr endState = std::dynamic_pointer_cast<EndState>(it.value());
593 endState->getEventName(), shared_from_this(),
eRemoved);
609 StateInstanceMap::iterator it =
substates.find(stateInstanceName);
614 if (newInstance->getStateClass() && !
checkSubstate(newInstance->getStateClass()))
619 newInstance->setPosition(it.value()->getTopLeft());
638 if (instance->getStateClass())
640 connect(instance->getStateClass().get(),
646 Qt::UniqueConnection);
650 addDetachedTransitions(instance);
699 auto keys = newInputParameters.keys();
701 for (
const auto& key : keys)
705 throw LocalException(
"Key ")
706 << key <<
" is already used in localParameters in state " <<
stateName;
718 auto keys = newLocalParameters.keys();
720 for (
const auto& key : keys)
724 throw LocalException(
"Key ")
725 << key <<
" is already used in inputParameters in state " <<
stateName;
763 t->mappingToNextStatesInput = mappingToNextStateInput;
764 t->mappingToParentStatesLocal = mappingToParentLocal;
765 t->mappingToParentStatesOutput = mappingToParentOutput;
770 throw LocalException(
"Could not find transition in state");
784 auto oldPoints = t->supportPoints.toPointList();
786 bool changed = newPoints.size() != oldPoints.size();
790 int size = oldPoints.size();
792 for (
int i = 0; i <
size; ++i)
794 if ((oldPoints.at(i) - newPoints.at(i)).manhattanLength() > 2)
801 t->labelCenterPosition = labelCenterPosition;
802 t->labelFontPointSize = labelFontPointSize;
803 t->supportPoints = points;
808 throw LocalException(
"Could not find transition in state");
825 t->transitionUserCode =
enabled;
830 throw LocalException(
"Could not find transition in state");
843 t->sourceState = sourceState;
844 t->eventName = eventName;
846 QPointF lastControlPoint = calcDetachedTransitionLastControlPoint(sourceState);
847 t->supportPoints.controlPoints.append(lastControlPoint);
848 t->supportPoints.endPoint = std::make_shared<QPointF>(
849 calcDetachedTransitionEndPoint(sourceState, lastControlPoint));
860 if (t.get() == transition.get())
862 if (transition->destinationState == newDest)
868 t->destinationState = newDest;
870 if (t->destinationState == t->sourceState)
872 QPointF p = calcDetachedTransitionLastControlPoint(t->sourceState);
874 controlPoints.push_back(p - QPointF(30, 30));
875 controlPoints.push_back(p);
876 controlPoints.push_back(p + QPointF(30, 30));
878 t->supportPoints.controlPoints = controlPoints;
882 t->supportPoints.controlPoints.clear();
883 t->supportPoints.endPoint.reset();
884 t->supportPoints.startPoint.reset();
888 if (!t->destinationState->getStateClass())
907 ARMARX_INFO <<
"Detaching transition " << t->eventName;
911 t->supportPoints.endPoint = std::make_shared<QPointF>(
912 calcDetachedTransitionEndPoint(t->sourceState, floatingEndPoint));
914 t->destinationState.reset();
915 t->labelCenterPosition.reset();
923 if (transition->sourceState)
926 transition, calcDetachedTransitionLastControlPoint(transition->sourceState));
990 auto checkEventExistsInSubstates = [&,
this](
EventPtr& e)
994 if (substate->getType() == eFinalState)
996 EndStateCPtr endstate = std::dynamic_pointer_cast<const EndState>(substate);
998 if (endstate && endstate->getEventName() == e->name)
1017 foreach (
EventPtr ev, outgoingEvents)
1020 foreach (
EventPtr evOld, oldTransitions)
1022 if (evOld->name == ev->name)
1028 if (!found && !checkEventExistsInSubstates(ev))
1034 foreach (
EventPtr evOld, oldTransitions)
1037 foreach (
EventPtr ev, outgoingEvents)
1039 if (evOld->name == ev->name)
1045 if (!found && !checkEventExistsInSubstates(evOld))
1060 << stateClass->getStateName();
1067 QList<StateInstancePtr> instances =
getInstances(stateClass);
1077 ARMARX_INFO_S <<
"Removing transitions for event " << eventName;
1078 QList<StateInstancePtr> instances =
getInstances(stateClass);
1126 State::setDirty(
bool dirty)
1128 if (this->dirty !=
dirty)
1133 this->dirty =
dirty;
1136 QList<StateInstancePtr>
1139 QList<StateInstancePtr> result;
1143 if (
s.value()->getStateClass() == stateClass)
1145 result.push_back(
s.value());
1157 if (t->eventName == eventName && t->sourceState == sourceInstance)
1196 ARMARX_WARNING <<
"Transition with event " << transition->eventName <<
" for state "
1197 << transition->sourceState->getInstanceName() <<
" already exists";
1201 if (!transition->destinationState && transition->supportPoints.controlPoints.size() == 0)
1204 <<
"If no destination is set for a transition, it must have 1 support point";
1208 if (!transition->sourceState)
1222 if (
getUUID() == newState->getUUID())
1245 const QString& transitionSourceName,
1246 const QString& transitionDestinationName)
const
1250 if (t->eventName == eventName &&
1251 t->sourceState->getInstanceName() == transitionSourceName &&
1252 t->destinationState->getInstanceName() == transitionDestinationName)
1275 if (!state->getStateClass())
1280 if (state->getStateClass()->getUUID() == sC->getUUID())
1285 if (state->getStateClass()->hasDescendant(sC))
1299 return "Normal State";
1303 return "Remote State";
1306 case eDynamicRemoteState:
1307 return "Dynamic Remote State";
1311 return "Final State";
1319 return "Unknown State Type";
1326 if (!instance->getStateClass())
1331 QList<EventPtr> events = instance->getStateClass()->getAllEvents();
1333 float angleStep = 20;
1334 float length = instance->getClassSize().width() * instance->getScale() * 0.8f;
1335 QPointF center = instance->getBounds().center();
1336 int count = events.size();
1337 float startAngle = angleStep * (count - 1) / 2.0f;
1339 float angle = startAngle;
1344 t->sourceState = instance;
1345 t->eventName =
event->name;
1346 t->supportPoints.append(center + QPointF(cos(
angle / 180.0 *
M_PI) * length,
1354 State::calcDetachedTransitionLastControlPoint(
StateInstancePtr instance)
const
1357 float angle = ((double)(rand() % 360));
1359 std::max(instance->getClassSize().width(), instance->getClassSize().height());
1360 length *= instance->getScale() * 0.8;
1362 p = instance->getBounds().center();
1365 p.setX(p.x() + cos(
angle / 180.0 *
M_PI) * length);
1366 p.setY(p.y() + sin(
angle / 180.0 *
M_PI) * length);
1372 const QPointF& lastControlPoint)
const
1374 QPointF line = lastControlPoint - instance->getBounds().center();
1375 QPointF p = line * 0.1 + lastControlPoint;
1385 if (t && t->sourceState && t->destinationState)
1388 QPointF p1 = t->sourceState->getBounds().center();
1389 QPointF p2 = t->destinationState->getBounds().center();
1392 QPointF dirU = p2 - p1;
1393 QPointF dirV = QPointF(dirU.y(), -dirU.x());
1394 supportPoints.push_back(p1 + dirU * u / 100 + dirV *
v / 100);
1395 t->supportPoints.setControlPoints(supportPoints);