32 #include <IceUtil/UUID.h>
36 #include <ArmarXCore/interface/statechart/RemoteStateOffererIce.h>
43 #include <ArmarXGui/gui-plugins/StatechartViewerPlugin/ui_StatechartViewer.h>
57 setlocale(LC_ALL,
"C");
59 ui =
new Ui::StatechartViewer();
62 qRegisterMetaType<LockableGraphPtr>(
"LockableGraphPtr");
63 qRegisterMetaType<MediatorPtr>(
"MediatorPtr");
64 qRegisterMetaType<size_t>(
"size_t");
65 qRegisterMetaType<IceStateConverterPtr>(
"IceStateConverterPtr");
66 qRegisterMetaType<StateIceBasePtr>(
"StateIceBasePtr");
70 ui->gridLayout_2->addWidget(proxyFinder, 0, 0, 2, 1);
71 proxyFinder->setSearchMask(
"*RemoteStateOfferer");
73 connect(ui->btnRefreshStateInstances, SIGNAL(clicked()),
this, SLOT(updateStateComboBox()));
74 connect(ui->tabWidget, SIGNAL(currentChanged(
int)),
this, SLOT(updateStateFollower()));
75 connect(ui->tabWidget, SIGNAL(tabCloseRequested(
int)),
this, SLOT(removeTab(
int)));
76 connect(ui->btnAddViewer, SIGNAL(clicked()),
this, SLOT(addNewStateView()));
77 connect(proxyFinder->getProxyNameComboBox(),
78 SIGNAL(currentIndexChanged(QString)),
80 SLOT(updateStateComboBox()),
81 Qt::UniqueConnection);
87 std::unique_lock lock(mutex);
98 "StatechartViewerRefetch");
104 qRegisterMetaType<statechartmodel::TransitionCPtr>(
"statechartmodel::TransitionCPtr");
105 qRegisterMetaType<statechartmodel::SignalType>(
"statechartmodel::SignalType");
107 getArmarXManager()->addObject(watcher,
false,
"StateWatcher" + IceUtil::generateUUID());
129 int size = settings->beginReadArray(
"StatechartViewers");
130 for (
int i = 0; i < size; ++i)
132 settings->setArrayIndex(i);
133 QString proxyName = settings->value(
"proxyName").toString();
134 QString globalStateName = settings->value(
"globalStateName").toString();
135 delayedConverterAdding.push_back(qMakePair(proxyName, globalStateName));
137 settings->endArray();
143 settings->beginWriteArray(
"StatechartViewers");
145 for (RemoteStateData&
data : converters)
147 settings->setArrayIndex(i);
148 settings->setValue(
"globalStateName",
data.globalStateName);
149 settings->setValue(
"proxyName",
data.proxyName);
152 settings->endArray();
156 StatechartViewerController::connectToIce()
158 for (QPair<QString, QString>& pair : delayedConverterAdding)
160 addNewStateView(pair.first, pair.second);
162 if (!ui->tabWidget->currentStateview())
164 addNewStateView(
"RobotControlStateOfferer",
"RobotStatechart->RobotControl");
167 ui->tabWidget->currentStateview()->viewAll();
171 StatechartViewerController::updateStatechartView(StateIceBasePtr stateptr,
174 std::unique_lock lock(mutex);
175 auto start = IceUtil::Time::now();
176 converter->convert(stateptr);
178 << (IceUtil::Time::now() - start).toMilliSecondsDouble() <<
" ms";
188 QMap<QPointer<StatechartView>, RemoteStateData> tempConverters;
190 std::unique_lock lock(mutex);
191 tempConverters = converters;
193 for (RemoteStateData& stateData : tempConverters)
195 RemoteStateOffererInterfacePrx statechartHandler;
198 statechartHandler = getProxy<RemoteStateOffererInterfacePrx>(
199 stateData.proxyName.toStdString(),
false,
"",
false);
200 if (!statechartHandler)
204 auto start = IceUtil::Time::now();
207 start = IceUtil::Time::now();
209 auto asyncResult = statechartHandler->begin_getStatechartInstanceByGlobalIdStr(
210 stateData.globalStateName.toStdString());
211 while (!asyncResult->isCompleted())
220 armarx::StateIceBasePtr stateptr =
221 statechartHandler->end_getStatechartInstanceByGlobalIdStr(asyncResult);
225 << stateData.globalStateName.toStdString();
230 <<
" took : " << (IceUtil::Time::now() - start).toMilliSecondsDouble()
232 QMetaObject::invokeMethod(
this,
233 "updateStatechartView",
234 Q_ARG(StateIceBasePtr, stateptr),
238 catch (Ice::NotRegisteredException&)
242 <<
"No ice ID 'RobotControlStateOfferer' registered";
252 StatechartViewerController::displayParameters(
257 QList<QTreeWidgetItem*> items;
258 if (selectedStateInstance && watcher)
260 auto paramContainerTypes = {
261 "inputParameters",
"localParameters",
"outputParameters"};
262 ui->paramView->clear();
265 for (
auto& type : paramContainerTypes)
267 QTreeWidgetItem* item =
new QTreeWidgetItem();
268 item->setText(0, type);
272 map = watcher->getStateParameterMap(selectedStateInstance->getStateClass(),
282 for (
auto& elem : map)
284 QTreeWidgetItem* subItem =
new QTreeWidgetItem();
285 StateParameterIceBasePtr param = elem.second;
286 subItem->setText(0, elem.first.c_str());
287 subItem->setText(1, param->value->output().c_str());
288 item->addChild(subItem);
290 items.push_back(item);
293 ui->paramView->addTopLevelItems(items);
294 for (
auto& item : items)
296 ui->paramView->expandItem(item);
303 if (items.size() == 0)
305 QTreeWidgetItem* item =
new QTreeWidgetItem();
306 item->setText(0,
"No data available yet");
307 ui->paramView->addTopLevelItem(item);
312 QTreeWidgetItem* item =
new QTreeWidgetItem();
313 item->setText(0,
"No data available yet");
314 ui->paramView->addTopLevelItem(item);
320 StatechartViewerController::addNewStateView(QString proxyName, QString stateName)
322 auto view = ui->tabWidget->addEmptyStateTab();
331 converters[view].converter.reset(
new IceStateConverter());
332 converters[view].converter->setStateWatcher(watcher);
333 view->setState(converters[view].converter->getTopState()->getStateClass());
334 converters[view].proxyName = proxyName;
335 converters[view].globalStateName = stateName;
336 QString instanceName;
337 if (stateName.lastIndexOf(
"->") >= 0)
339 instanceName = stateName.right(stateName.size() - stateName.lastIndexOf(
"->") - 2);
343 instanceName = stateName;
345 ui->tabWidget->setTabText(ui->tabWidget->currentIndex(), instanceName);
347 view->getLayoutController().enableLayouting();
353 StatechartViewerController::addNewStateView()
355 addNewStateView(proxyFinder->getSelectedProxyName(),
356 ui->comboBoxStateInstances->currentText());
360 StatechartViewerController::followActiveState()
362 auto view = ui->tabWidget->currentStateview();
371 StatechartViewerController::updateStateComboBox()
373 if (proxyFinder->getSelectedProxyName().isEmpty())
377 if (
getState() < eManagedIceObjectStarting)
381 auto proxy = getProxy<RemoteStateOffererInterfacePrx>(
382 proxyFinder->getSelectedProxyName().toStdString(),
false,
"",
false);
384 ui->comboBoxStateInstances->clear();
387 QStringList stateInstances;
388 for (
auto& elem : proxy->getAvailableStateInstances())
390 stateInstances << (elem.second.c_str());
392 stateInstances.removeDuplicates();
393 ui->comboBoxStateInstances->addItems(stateInstances);
395 ui->btnAddViewer->setEnabled(ui->comboBoxStateInstances->count() > 0);
399 StatechartViewerController::updateStateFollower()
401 auto view = ui->tabWidget->currentStateview();
410 StatechartViewerController::removeTab(
int index)
412 QPointer<StatechartView> view = qobject_cast<StatechartView*>(ui->tabWidget->widget(
index));
415 converters.remove(view);
428 if (parent != customToolbar->parent())
430 customToolbar->setParent(parent);
433 return qobject_cast<QToolBar*>(customToolbar);
436 customToolbar =
new QToolBar(parent);
437 customToolbar->setIconSize(QSize(16, 16));
438 autoFollowAction = customToolbar->addAction(QIcon(
":/icons/magic-wand-icon.png"),
439 "Auto follow active state");
440 autoFollowAction->setCheckable(
true);
441 autoFollowAction->setChecked(
true);
443 connect(autoFollowAction, SIGNAL(toggled(
bool)), follower, SLOT(toggle(
bool)));
445 centerActiveStateAction = customToolbar->addAction(QIcon(
":/icons/zoom-original-2.png"),
446 "Center on active state");
447 connect(centerActiveStateAction,
448 SIGNAL(triggered(
bool)),
450 SLOT(centerOnCurrentState(
bool)));
451 return qobject_cast<QToolBar*>(customToolbar);
458 if (
index != -1 && ui->tabWidget->currentStateview() &&
459 ui->tabWidget->currentStateview()->getScene())
462 ui->tabWidget->currentStateview()->getScene(),
463 SIGNAL(transitionContextMenuRequested(
468 Qt::UniqueConnection);
476 QPoint mouseScreenPos,
477 QPointF mouseItemPos)
481 QAction* triggerTransition = menu.addAction(
"Trigger Transition " + transition->eventName);
482 if (transition->sourceState != state->getActiveSubstate())
484 triggerTransition->setEnabled(
false);
488 QAction* result = menu.exec(mouseScreenPos);
491 if (result == triggerTransition)
493 std::unique_lock lock(mutex);
495 for (RemoteStateData&
data : converters)
497 std::set<std::string> proxyNames;
498 std::string globalId;
499 auto states =
data.converter->getCompleteStateMap();
500 for (
auto& statepair : states)
502 proxyNames.insert(
data.proxyName.toStdString());
503 if (state == statepair.second.first->getStateClass())
505 globalId = statepair.first;
508 StateIceBasePtr iceState = statepair.second.second;
509 RemoteStateIceBasePtr remoteState =
510 RemoteStateIceBasePtr::dynamicCast(iceState);
513 proxyNames.insert(remoteState->proxyName);
516 if (!globalId.empty())
518 RemoteStateOffererInterfacePrx correctOffererproxy;
520 <<
VAROUT(Ice::StringSeq(proxyNames.begin(), proxyNames.end()));
521 std::map<RemoteStateOffererInterfacePrx, Ice::AsyncResultPtr> proxyResultPtrs;
522 for (
auto proxyName : proxyNames)
524 RemoteStateOffererInterfacePrx proxy;
527 proxy = getProxy<RemoteStateOffererInterfacePrx>(
528 proxyName,
false,
"",
false);
531 proxyResultPtrs[proxy] =
532 proxy->begin_isHostOfStateByGlobalIdStr(globalId);
540 for (
auto& proxyPair : proxyResultPtrs)
542 RemoteStateOffererInterfacePrx proxy;
545 proxy = proxyPair.first;
546 if (proxy->end_isHostOfStateByGlobalIdStr(proxyPair.second))
548 correctOffererproxy = proxy;
558 if (correctOffererproxy)
560 ARMARX_INFO <<
"Sending event " << transition->eventName <<
" to "
561 << transition->sourceState->getInstanceName();
562 correctOffererproxy->begin_issueEventWithGlobalIdStr(
564 new Event(transition->sourceState->getInstanceName().toStdString(),
565 transition->eventName.toStdString()));