25 #include <ArmarXCore/interface/statechart/RemoteStateOffererIce.h>
32 #include <ArmarXGui/gui-plugins/StatechartViewerPlugin/ui_StatechartViewer.h>
46 #include <IceUtil/UUID.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(), SIGNAL(currentIndexChanged(QString)),
this, SLOT(updateStateComboBox()), Qt::UniqueConnection);
84 std::unique_lock lock(mutex);
96 qRegisterMetaType<statechartmodel::TransitionCPtr>(
"statechartmodel::TransitionCPtr");
97 qRegisterMetaType<statechartmodel::SignalType>(
"statechartmodel::SignalType");
99 getArmarXManager()->addObject(watcher,
false,
"StateWatcher" + IceUtil::generateUUID());
118 int size = settings->beginReadArray(
"StatechartViewers");
119 for (
int i = 0; i < size; ++i)
121 settings->setArrayIndex(i);
122 QString proxyName = settings->value(
"proxyName").toString();
123 QString globalStateName = settings->value(
"globalStateName").toString();
124 delayedConverterAdding.push_back(qMakePair(proxyName, globalStateName));
126 settings->endArray();
131 settings->beginWriteArray(
"StatechartViewers");
133 for (RemoteStateData&
data : converters)
135 settings->setArrayIndex(i);
136 settings->setValue(
"globalStateName",
data.globalStateName);
137 settings->setValue(
"proxyName",
data.proxyName);
140 settings->endArray();
143 void StatechartViewerController::connectToIce()
145 for (QPair<QString, QString>& pair : delayedConverterAdding)
147 addNewStateView(pair.first, pair.second);
149 if (!ui->tabWidget->currentStateview())
151 addNewStateView(
"RobotControlStateOfferer",
"RobotStatechart->RobotControl");
154 ui->tabWidget->currentStateview()->viewAll();
157 void StatechartViewerController::updateStatechartView(StateIceBasePtr stateptr,
IceStateConverterPtr converter)
159 std::unique_lock lock(mutex);
160 auto start = IceUtil::Time::now();
161 converter->convert(stateptr);
162 ARMARX_DEBUG <<
deactivateSpam(3) <<
"converting instance took : " << (IceUtil::Time::now() - start).toMilliSecondsDouble() <<
" ms";
171 QMap<QPointer<StatechartView>, RemoteStateData> tempConverters;
173 std::unique_lock lock(mutex);
174 tempConverters = converters;
176 for (RemoteStateData& stateData : tempConverters)
178 RemoteStateOffererInterfacePrx statechartHandler;
181 statechartHandler = getProxy<RemoteStateOffererInterfacePrx>(stateData.proxyName.toStdString(),
false,
"",
false);
182 if (!statechartHandler)
186 auto start = IceUtil::Time::now();
189 start = IceUtil::Time::now();
191 auto asyncResult = statechartHandler->begin_getStatechartInstanceByGlobalIdStr(stateData.globalStateName.toStdString());
192 while (!asyncResult->isCompleted())
201 armarx::StateIceBasePtr stateptr = statechartHandler->end_getStatechartInstanceByGlobalIdStr(asyncResult);
204 ARMARX_WARNING_S <<
"Could not find state with name " << stateData.globalStateName.toStdString();
209 QMetaObject::invokeMethod(
this,
"updateStatechartView", Q_ARG(StateIceBasePtr, stateptr), Q_ARG(
IceStateConverterPtr, stateData.converter));
213 catch (Ice::NotRegisteredException&)
229 QList<QTreeWidgetItem*> items;
230 if (selectedStateInstance && watcher)
232 auto paramContainerTypes = {
"inputParameters",
"localParameters",
"outputParameters"};
233 ui->paramView->clear();
236 for (
auto& type : paramContainerTypes)
238 QTreeWidgetItem* item =
new QTreeWidgetItem();
239 item->setText(0, type);
243 map = watcher->getStateParameterMap(selectedStateInstance->getStateClass(), type);
253 for (
auto& elem : map)
255 QTreeWidgetItem* subItem =
new QTreeWidgetItem();
256 StateParameterIceBasePtr param = elem.second;
257 subItem->setText(0, elem.first.c_str());
258 subItem->setText(1, param->value->output().c_str());
259 item->addChild(subItem);
262 items.push_back(item);
266 ui->paramView->addTopLevelItems(items);
267 for (
auto& item : items)
269 ui->paramView->expandItem(item);
276 if (items.size() == 0)
278 QTreeWidgetItem* item =
new QTreeWidgetItem();
279 item->setText(0,
"No data available yet");
280 ui->paramView->addTopLevelItem(item);
286 QTreeWidgetItem* item =
new QTreeWidgetItem();
287 item->setText(0,
"No data available yet");
288 ui->paramView->addTopLevelItem(item);
293 void StatechartViewerController::addNewStateView(QString proxyName, QString stateName)
295 auto view = ui->tabWidget->addEmptyStateTab();
301 converters[view].converter.reset(
new IceStateConverter());
302 converters[view].converter->setStateWatcher(watcher);
303 view->setState(converters[view].converter->getTopState()->getStateClass());
304 converters[view].proxyName = proxyName;
305 converters[view].globalStateName = stateName;
306 QString instanceName;
307 if (stateName.lastIndexOf(
"->") >= 0)
309 instanceName = stateName.right(stateName.size() - stateName.lastIndexOf(
"->") - 2);
313 instanceName = stateName;
315 ui->tabWidget->setTabText(ui->tabWidget->currentIndex(), instanceName);
317 view->getLayoutController().enableLayouting();
323 void StatechartViewerController::addNewStateView()
325 addNewStateView(proxyFinder->getSelectedProxyName(), ui->comboBoxStateInstances->currentText());
328 void StatechartViewerController::followActiveState()
330 auto view = ui->tabWidget->currentStateview();
338 void StatechartViewerController::updateStateComboBox()
340 if (proxyFinder->getSelectedProxyName().isEmpty())
344 if (
getState() < eManagedIceObjectStarting)
348 auto proxy = getProxy<RemoteStateOffererInterfacePrx>(proxyFinder->getSelectedProxyName().toStdString(),
false,
"",
false);
350 ui->comboBoxStateInstances->clear();
353 QStringList stateInstances;
354 for (
auto& elem : proxy->getAvailableStateInstances())
356 stateInstances << (elem.second.c_str());
358 stateInstances.removeDuplicates();
359 ui->comboBoxStateInstances->addItems(stateInstances);
361 ui->btnAddViewer->setEnabled(ui->comboBoxStateInstances->count() > 0);
364 void StatechartViewerController::updateStateFollower()
366 auto view = ui->tabWidget->currentStateview();
374 void StatechartViewerController::removeTab(
int index)
376 QPointer<StatechartView> view = qobject_cast<StatechartView*>(ui->tabWidget->widget(
index));
379 converters.remove(view);
391 if (parent != customToolbar->parent())
393 customToolbar->setParent(parent);
396 return qobject_cast<QToolBar*>(customToolbar);
399 customToolbar =
new QToolBar(parent);
400 customToolbar->setIconSize(QSize(16, 16));
401 autoFollowAction = customToolbar->addAction(QIcon(
":/icons/magic-wand-icon.png"),
"Auto follow active state");
402 autoFollowAction->setCheckable(
true);
403 autoFollowAction->setChecked(
true);
405 connect(autoFollowAction, SIGNAL(toggled(
bool)), follower, SLOT(toggle(
bool)));
407 centerActiveStateAction = customToolbar->addAction(QIcon(
":/icons/zoom-original-2.png"),
"Center on active state");
408 connect(centerActiveStateAction, SIGNAL(triggered(
bool)), follower, SLOT(centerOnCurrentState(
bool)));
409 return qobject_cast<QToolBar*>(customToolbar);
415 if (
index != -1 && ui->tabWidget->currentStateview() && ui->tabWidget->currentStateview()->getScene())
426 QAction* triggerTransition = menu.addAction(
"Trigger Transition " + transition->eventName);
427 if (transition->sourceState != state->getActiveSubstate())
429 triggerTransition->setEnabled(
false);
433 QAction* result = menu.exec(mouseScreenPos);
438 if (result == triggerTransition)
440 std::unique_lock lock(mutex);
442 for (RemoteStateData&
data : converters)
444 std::set<std::string> proxyNames;
445 std::string globalId;
446 auto states =
data.converter->getCompleteStateMap();
447 for (
auto& statepair : states)
449 proxyNames.insert(
data.proxyName.toStdString());
450 if (state == statepair.second.first->getStateClass())
452 globalId = statepair.first;
455 StateIceBasePtr iceState = statepair.second.second;
456 RemoteStateIceBasePtr remoteState = RemoteStateIceBasePtr::dynamicCast(iceState);
459 proxyNames.insert(remoteState->proxyName);
462 if (!globalId.empty())
464 RemoteStateOffererInterfacePrx correctOffererproxy;
466 std::map<RemoteStateOffererInterfacePrx, Ice::AsyncResultPtr> proxyResultPtrs;
467 for (
auto proxyName : proxyNames)
469 RemoteStateOffererInterfacePrx proxy;
472 proxy = getProxy<RemoteStateOffererInterfacePrx>(proxyName,
false,
"",
false);
475 proxyResultPtrs[proxy] = proxy->begin_isHostOfStateByGlobalIdStr(globalId);
483 for (
auto& proxyPair : proxyResultPtrs)
485 RemoteStateOffererInterfacePrx proxy;
488 proxy = proxyPair.first;
489 if (proxy->end_isHostOfStateByGlobalIdStr(proxyPair.second))
491 correctOffererproxy = proxy;
502 if (correctOffererproxy)
504 ARMARX_INFO <<
"Sending event " << transition->eventName <<
" to " << transition->sourceState->getInstanceName();
505 correctOffererproxy->begin_issueEventWithGlobalIdStr(globalId,
new Event(transition->sourceState->getInstanceName().toStdString(), transition->eventName.toStdString()));