25 #include <QFileDialog>
27 #include <QMessageBox>
30 #include <SimoxUtility/algorithm/string/string_tools.h>
59 updateTimer =
new QTimer(
this);
60 connect(updateTimer, &QTimer::timeout,
this, QOverload<>::of(&This::onUpdate));
62 replayTimer =
new QTimer(
this);
63 connect(replayTimer, &QTimer::timeout,
this, QOverload<>::of(&This::onReplayTimerTick));
65 connect(widget.layerTree, &QTreeWidget::itemChanged,
this, &This::layerTreeChanged);
66 connect(widget.expandButton, &QPushButton::clicked,
this, &This::onExpandAll);
67 connect(widget.collapseButton, &QPushButton::clicked,
this, &This::onCollapseAll);
68 connect(widget.filterEdit, &QLineEdit::textChanged,
this, &This::onFilterTextChanged);
69 connect(widget.hideAllButton, &QPushButton::clicked,
this, &This::onHideAll);
70 connect(widget.showAllButton, &QPushButton::clicked,
this, &This::onShowAll);
71 connect(widget.hideFilteredButton, &QPushButton::clicked,
this, &This::onHideFiltered);
72 connect(widget.showFilteredButton, &QPushButton::clicked,
this, &This::onShowFiltered);
74 connect(widget.recordingStartButton, &QPushButton::clicked,
this, &This::onStartRecording);
75 connect(widget.recordingStopButton, &QPushButton::clicked,
this, &This::onStopRecording);
77 connect(widget.refreshRecordingsButton,
78 &QPushButton::clicked,
80 &This::onRefreshRecordings);
81 connect(widget.recordingList,
82 &QListWidget::currentItemChanged,
84 &This::onRecordingSelectionChanged);
86 connect(widget.replayRevisionSpinBox,
87 QOverload<int>::of(&QSpinBox::valueChanged),
89 &This::onReplaySpinChanged);
90 connect(widget.replayRevisionSlider,
91 QOverload<int>::of(&QSlider::valueChanged),
93 &This::onReplaySliderChanged);
95 connect(widget.replayStartButton, &QPushButton::clicked,
this, &This::onReplayStart);
96 connect(widget.replayStopButton, &QPushButton::clicked,
this, &This::onReplayStop);
97 connect(widget.replayTimedButton, &QPushButton::toggled,
this, &This::onReplayTimedStart);
101 connect(widget.deselectButton, &QPushButton::clicked,
this, &This::onDeselectElement);
102 connect(widget.listInteractiveElements,
103 &QListWidget::itemDoubleClicked,
105 &This::onInteractiveElementSelected);
107 connect(
this, &This::connectGui,
this, &This::onConnectGui, Qt::QueuedConnection);
108 connect(
this, &This::disconnectGui,
this, &This::onDisconnectGui, Qt::QueuedConnection);
112 widget.layerTree, &QTreeWidget::currentItemChanged,
this, &This::updateSelectedLayer);
114 connect(widget.layerInfoTreeGroupBox,
118 connect(widget.defaultShowLimitSpinBox,
119 qOverload<int>(&QSpinBox::valueChanged),
124 layerInfoTree.
setWidget(widget.layerInfoTree);
125 layerInfoTree.
setEnabled(widget.layerInfoTreeGroupBox->isChecked());
131 { layersChanged(layers); };
135 widget.verticalLayout->addWidget(arvizeProfileLayerWidget);
136 connect(arvizeProfileLayerWidget,
139 &This::updateLayersFromProfile);
140 connect(arvizeProfileLayerWidget,
143 &This::updateLayers);
145 replayTimer->start(33);
155 if (storageName.size() > 0)
159 if (debugObserverName.size() > 0)
165 callbackData->this_ =
this;
166 callback = viz::newCallback_StorageInterface_getRecordingBatch(
183 if (!debugObserverName.empty())
185 getProxy(debugObserver, debugObserverName,
false,
"",
false);
203 ArVizWidgetController::updateLayers()
206 layerTreeChanged(
nullptr, 0);
210 ArVizWidgetController::updateLayersFromProfile()
213 QSignalBlocker blocker(widget.layerTree);
216 for (
int compIndex = 0; compIndex < widget.layerTree->topLevelItemCount(); ++compIndex)
218 QTreeWidgetItem* componentItem = widget.layerTree->topLevelItem(compIndex);
219 bool parentChecked =
true;
220 const std::string component = componentItem->text(0).toStdString();
221 for (
int layerIndex = 0; layerIndex < componentItem->childCount(); ++layerIndex)
223 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
224 const std::string layer = layerItem->text(0).toStdString();
226 const bool visible = not arvizeProfileLayerWidget->
isHidden(layerID);
227 layerItem->setCheckState(
228 0, visible ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
229 parentChecked &= visible;
232 componentItem->setCheckState(
233 0, parentChecked ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
239 ArVizWidgetController::onConnectGui()
241 onRefreshRecordings();
242 currentRecordingSelected =
false;
245 updateTimer->start(33);
249 ArVizWidgetController::onDisconnectGui()
257 ArVizWidgetController::layerTreeChanged(QTreeWidgetItem* item,
int )
260 int componentCount = widget.layerTree->topLevelItemCount();
261 for (
int compIndex = 0; compIndex < componentCount; ++compIndex)
263 QTreeWidgetItem* componentItem = widget.layerTree->topLevelItem(compIndex);
264 std::string
component = componentItem->text(0).toStdString();
265 Qt::CheckState componentCheck = componentItem->checkState(0);
266 int layerCount = componentItem->childCount();
268 arvizeProfileLayerWidget->
update(component, componentCheck == Qt::Checked);
270 if (componentItem == item)
274 << (componentCheck == Qt::Checked);
275 for (
int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
277 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
278 if (layerItem->checkState(0) != componentCheck)
280 layerItem->setCheckState(0, componentCheck);
285 for (
int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
287 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
288 std::string layer = layerItem->text(0).toStdString();
289 bool layerVisible = (layerItem->checkState(0) == Qt::Checked);
290 ARMARX_VERBOSE <<
"Layer: " << layer <<
", Visible: " << layerVisible;
294 arvizeProfileLayerWidget->
update(layerID, layerVisible);
296 visualizer.
showLayer(layerID, layerVisible);
302 ArVizWidgetController::layersChanged(std::vector<viz::CoinLayerID>
const& layers)
304 QTreeWidget* tree = widget.layerTree;
306 std::map<std::string, QTreeWidgetItem*> currentComponents;
307 std::map<viz::CoinLayerID, QTreeWidgetItem*> currentLayers;
308 int componentCount = widget.layerTree->topLevelItemCount();
309 for (
int compIndex = 0; compIndex < componentCount; ++compIndex)
311 QTreeWidgetItem* componentItem = widget.layerTree->topLevelItem(compIndex);
312 std::string
component = componentItem->text(0).toStdString();
313 currentComponents.emplace(component, componentItem);
315 int layerCount = componentItem->childCount();
316 for (
int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
318 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
319 std::string layer = layerItem->text(0).toStdString();
322 currentLayers.emplace(layerID, layerItem);
326 const QList<QTreeWidgetItem*> selectedItems = widget.layerTree->selectedItems();
329 QTreeWidgetItem* currentItem =
nullptr;
330 bool componentWasNew =
false;
331 std::string currentComponent;
332 for (
auto& entry : layers)
334 std::string
const&
component = entry.first;
335 if (component != currentComponent)
337 auto iter = currentComponents.find(component);
338 if (iter == currentComponents.end())
341 QSignalBlocker blocker(
343 currentItem =
new QTreeWidgetItem(tree);
344 currentItem->setText(0, QString::fromStdString(component));
345 currentItem->setCheckState(0,
346 arvizeProfileLayerWidget->
isHidden(component)
350 componentWasNew =
true;
355 currentItem = iter->second;
357 componentWasNew =
false;
363 auto iter = currentLayers.find(entry);
364 if (iter == currentLayers.end())
367 std::string
const& layer = entry.second;
368 QTreeWidgetItem* layerItem =
new QTreeWidgetItem;
369 layerItem->setText(0, QString::fromStdString(layer));
370 layerItem->setCheckState(
371 0, arvizeProfileLayerWidget->
isHidden(entry) ? Qt::Unchecked : Qt::Checked);
375 currentItem->addChild(layerItem);
380 tree->expandItem(currentItem);
386 <<
"Invalid component/layer ID: " << entry.first <<
" / "
393 if (arvizeProfileLayerWidget->
isHidden(iter->first) or
394 iter->second->checkState(0) == Qt::Unchecked)
396 visualizer.
showLayer(iter->first,
false);
403 ArVizWidgetController::updateSelectedLayer(QTreeWidgetItem* current, QTreeWidgetItem* previous)
407 if (!current->parent())
415 current->text(0).toStdString());
418 if (layer ==
nullptr)
420 ARMARX_WARNING <<
"Could not find layer (" <<
id.first <<
" / " <<
id.second
421 <<
") in Visualizer.";
430 ArVizWidgetController::onCollapseAll(
bool)
432 widget.layerTree->collapseAll();
436 ArVizWidgetController::onExpandAll(
bool)
438 widget.layerTree->expandAll();
442 ArVizWidgetController::onHideAll(
bool)
444 showAllLayers(
false);
448 ArVizWidgetController::onShowAll(
bool)
454 ArVizWidgetController::onHideFiltered(
bool)
456 showFilteredLayers(
false);
460 ArVizWidgetController::onShowFiltered(
bool)
462 showFilteredLayers(
true);
466 ArVizWidgetController::onFilterTextChanged(
const QString& filter)
470 QRegExp rx(filter, Qt::CaseInsensitive, QRegExp::Wildcard);
471 for (QTreeWidgetItemIterator iter(widget.layerTree); *iter; ++iter)
473 QTreeWidgetItem* item = *iter;
474 QString itemText = item->text(0);
475 bool matches = filter.size() == 0 || itemText.contains(rx);
480 item->parent()->setHidden(
false);
486 ArVizWidgetController::showAllLayers(
bool visible)
488 widget.layerTree->blockSignals(
true);
490 for (QTreeWidgetItemIterator iter(widget.layerTree); *iter; ++iter)
492 QTreeWidgetItem* item = *iter;
493 item->setCheckState(0, visible ? Qt::Checked : Qt::Unchecked);
496 widget.layerTree->blockSignals(
false);
502 ArVizWidgetController::showFilteredLayers(
bool visible)
504 widget.layerTree->blockSignals(
true);
506 QString filter = widget.filterEdit->text();
507 QRegExp rx(filter, Qt::CaseInsensitive, QRegExp::Wildcard);
509 for (QTreeWidgetItemIterator iter(widget.layerTree); *iter; ++iter)
511 QTreeWidgetItem* item = *iter;
512 QString itemText = item->text(0);
513 bool matches = filter.size() == 0 || itemText.contains(rx);
516 item->setCheckState(0, visible ? Qt::Checked : Qt::Unchecked);
520 widget.layerTree->blockSignals(
false);
526 ArVizWidgetController::onDeselectElement()
534 ArVizWidgetController::onContextMenuClicked()
537 if (selected ==
nullptr)
539 ARMARX_WARNING <<
"Selected element is null, but a context menu option was clicked!";
543 QPushButton* clickedButton =
static_cast<QPushButton*
>(sender());
545 QLayout* layout = widget.groupBoxContextMenu->layout();
546 int count = layout->count();
547 for (
int i = 0; i < count; ++i)
549 QPushButton* button =
static_cast<QPushButton*
>(layout->itemAt(i)->widget());
550 if (button == clickedButton)
557 interaction.type = viz::data::InteractionFeedbackType::CONTEXT_MENU_CHOSEN;
565 ArVizWidgetController::onInteractiveElementSelected(QListWidgetItem* item)
567 int index = widget.listInteractiveElements->row(item);
579 std::string
id = inter.
layer.first +
"/" + inter.
layer.second +
"/" + inter.
element;
580 return QString::fromStdString(
id);
584 ArVizWidgetController::onUpdate()
589 QString selectedElementName(
"<None>");
590 QLayout* contextMenuLayout = widget.groupBoxContextMenu->layout();
596 int currentCount = contextMenuLayout->count();
598 std::vector<std::string>
const& options = desc.contextMenuOptions;
600 if (desc.enableFlags & viz::data::InteractionEnableFlags::CONTEXT_MENU)
602 newCount = (int)options.size();
604 if (newCount != currentCount)
608 while ((item = contextMenuLayout->takeAt(0)) !=
nullptr)
610 delete item->widget();
614 for (std::string
const&
option : options)
616 QPushButton* button =
617 new QPushButton(QString::fromStdString(
option), widget.groupBoxContextMenu);
619 &QPushButton::clicked,
621 &ArVizWidgetController::onContextMenuClicked);
622 contextMenuLayout->addWidget(button);
627 for (
int i = 0; i < currentCount; ++i)
629 QLayoutItem* item = contextMenuLayout->itemAt(i);
630 QPushButton* button =
static_cast<QPushButton*
>(item->widget());
631 button->setText(QString::fromStdString(options[i]));
638 while ((item = contextMenuLayout->takeAt(0)) !=
nullptr)
640 delete item->widget();
644 widget.labelSelectedElement->setText(selectedElementName);
647 int currentCount = widget.listInteractiveElements->count();
649 if (newCount != currentCount)
651 widget.listInteractiveElements->clear();
655 widget.listInteractiveElements->addItem(elementID);
659 onTimingObserverUpdate();
663 ArVizWidgetController::onTimingObserverUpdate()
670 timingMap[
"0. pull (ms)"] =
new Variant(timing.
pull.toMilliSecondsDouble());
671 timingMap[
"1. apply (ms)"] =
673 timingMap[
"1.1 apply, addLayer (ms)"] =
675 timingMap[
"1.2 apply, updateElements (ms)"] =
677 timingMap[
"1.3 apply, removeElements (ms)"] =
679 timingMap[
"2. layers (ms)"] =
681 timingMap[
"3. wait duration (ms)"] =
682 new Variant(timing.
waitDuration.toMilliSecondsDouble());
683 timingMap[
"4. update toggle"] =
new Variant(timing.
updateToggle);
684 timingMap[
"total (ms)"] =
new Variant(timing.
total.toMilliSecondsDouble());
686 timings.push_back(timing.
total.toMilliSecondsDouble());
688 if ((
int)timings.size() > numTimings)
690 timings.erase(timings.begin());
693 std::accumulate(timings.begin(), timings.end(), 0.0) / numTimings;
694 timingMap[
"total avg (ms)"] =
new Variant(averageTime);
696 debugObserver->begin_setDebugChannel(
"ArViz_Timing", timingMap);
702 ArVizWidgetController::onStartRecording()
704 std::string recordingID = widget.recordingIdTextBox->text().toStdString();
706 std::string runningID = storage->startRecording(recordingID);
710 if (runningID.size() > 0)
712 std::string
message =
"There is already a recording running with ID '" + runningID +
713 "'. \n" +
"You have to stop the running recording first";
714 QMessageBox::information(
715 widget.tabWidget,
"Recording running", QString::fromStdString(
message));
723 ArVizWidgetController::onStopRecording()
725 storage->stopRecording();
727 onRefreshRecordings();
732 ArVizWidgetController::onRefreshRecordings()
734 allRecordings = storage->getAllRecordings().recordings;
735 std::sort(allRecordings.begin(),
738 { return lhs.id < rhs.id; });
740 std::string currentText;
741 QListWidgetItem* currentItem = widget.recordingList->currentItem();
744 currentText = currentItem->text().toStdString();
747 widget.recordingList->clear();
748 int currentTextIndex = -1;
750 for (
auto& recording : allRecordings)
752 if (recording.id == currentText)
754 currentTextIndex =
index;
756 widget.recordingList->addItem(QString::fromStdString(recording.id));
760 if (currentTextIndex > 0)
762 widget.recordingList->setCurrentRow(currentTextIndex);
767 ArVizWidgetController::onRecordingSelectionChanged(QListWidgetItem* current,
768 QListWidgetItem* previous)
775 std::string selectedID = current->text().toStdString();
778 if (recording.id == selectedID)
780 selectRecording(recording);
787 timestampToString(
long timestampInMicroSeconds,
bool showMS =
false)
789 IceUtil::Time time = IceUtil::Time::microSeconds(timestampInMicroSeconds);
790 std::string timeString = time.toDateTime();
793 timeString = timeString.substr(0, timeString.size() - 4);
799 ArVizWidgetController::onReplaySpinChanged(
int newValue)
801 widget.replayRevisionSlider->setValue(newValue);
805 ArVizWidgetController::onReplaySliderChanged(
int newValue)
807 if (currentRevision != newValue)
809 long timestamp = replayToRevision(newValue);
812 currentRevision = newValue;
813 currentTimestamp = timestamp;
814 widget.replayRevisionSpinBox->setValue(newValue);
817 widget.replayTimestampLabel->setText(
818 QString::fromStdString(timestampToString(timestamp,
true)));
822 widget.replayRevisionSlider->setValue(currentRevision);
831 widget.recordingIdLabel->setText(QString::fromStdString(recording.id));
833 widget.recordingRevisionLabel->setText(
834 QString::fromStdString(
std::to_string(recording.firstRevision) +
" - " +
837 std::string firstTimeString = timestampToString(recording.firstTimestampInMicroSeconds);
838 std::string lastTimeString = timestampToString(recording.lastTimestampInMicroSeconds);
840 widget.recordingTimestampLabel->setText(
841 QString::fromStdString(firstTimeString +
" - " + lastTimeString));
844 recording.lastTimestampInMicroSeconds - recording.firstTimestampInMicroSeconds);
845 int durationSeconds = duration.toSeconds();
846 widget.recordingDurationLabel->setText(
849 widget.recordingBatchesLabel->setText(
850 QString::fromStdString(
std::to_string(recording.batchHeaders.size())));
853 currentRecording = recording;
854 currentRecordingSelected =
true;
855 enableWidgetAccordingToMode();
859 ArVizWidgetController::onReplayStart(
bool)
861 if (!currentRecordingSelected)
863 ARMARX_WARNING <<
"No recording selected, so no replay can be started";
867 std::unique_lock<std::mutex> lock(recordingBatchCacheMutex);
868 recordingBatchCache.clear();
875 widget.replayRevisionSpinBox->blockSignals(
true);
876 widget.replayRevisionSpinBox->setMinimum(currentRecording.firstRevision);
877 widget.replayRevisionSpinBox->setMaximum(currentRecording.lastRevision);
878 widget.replayRevisionSpinBox->setValue(currentRecording.firstRevision);
879 widget.replayRevisionSpinBox->blockSignals(
false);
881 widget.replayRevisionSlider->blockSignals(
true);
882 widget.replayRevisionSlider->setMinimum(currentRecording.firstRevision);
883 widget.replayRevisionSlider->setMaximum(currentRecording.lastRevision);
884 widget.replayRevisionSlider->setValue(currentRecording.firstRevision);
885 widget.replayRevisionSlider->blockSignals(
false);
887 currentRevision = -1;
888 onReplaySliderChanged(widget.replayRevisionSlider->value());
892 ArVizWidgetController::onReplayStop(
bool)
900 ArVizWidgetController::replayToRevision(
long revision)
904 ARMARX_WARNING <<
"Cannot call replayToRevision, when not in replaying mode.\n"
905 <<
"Actual mode: " << int(mode);
909 viz::data::RecordingBatchHeader* matchingBatchHeader =
nullptr;
910 for (
auto& batchHeader : currentRecording.batchHeaders)
912 if (batchHeader.firstRevision <= revision && revision <= batchHeader.lastRevision)
914 matchingBatchHeader = &batchHeader;
918 if (matchingBatchHeader ==
nullptr)
920 ARMARX_WARNING <<
"Could not find batch for revision: " << revision;
924 viz::data::RecordingBatch
const& batch = getRecordingBatch(matchingBatchHeader->index);
927 <<
"\nGot batch: " << batch.header.firstRevision <<
" - "
928 << batch.header.lastRevision <<
"\nUpdates: " << batch.updates.size()
929 <<
"\nInitial state: " << batch.initialState.size();
932 auto revisionLess = [](viz::data::TimestampedLayerUpdate
const& lhs,
933 viz::data::TimestampedLayerUpdate
const& rhs)
934 {
return lhs.revision < rhs.revision; };
935 viz::data::TimestampedLayerUpdate pivot;
936 pivot.revision = revision;
938 std::lower_bound(batch.updates.begin(), batch.updates.end(), pivot, revisionLess);
939 auto updateEnd = std::upper_bound(updateBegin, batch.updates.end(), pivot, revisionLess);
942 std::map<std::string, viz::data::LayerUpdate const*> updates;
944 for (
auto&
update : batch.initialState)
948 for (
auto updateIter = batch.updates.begin(); updateIter != updateEnd; ++updateIter)
950 updates[updateIter->update.name] = &updateIter->update;
954 for (
auto& pair : updates)
956 visualizer.
apply(*pair.second);
959 if (layerIDsAfter != layerIDsBefore)
964 return updateBegin->timestampInMicroseconds;
968 ArVizWidgetController::getRevisionForTimestamp(
long timestamp)
972 ARMARX_WARNING <<
"Cannot call replayToTimestamp, when not in replaying mode.\n"
973 <<
"Actual mode: " << int(mode);
977 if (timestamp < currentRecording.firstTimestampInMicroSeconds)
979 ARMARX_INFO <<
"Requested timestamp is earlier than recording: "
980 << timestampToString(timestamp);
984 viz::data::RecordingBatchHeader* matchingBatchHeader =
nullptr;
985 for (
auto& batchHeader : currentRecording.batchHeaders)
987 matchingBatchHeader = &batchHeader;
988 if (timestamp <= batchHeader.lastTimestampInMicroSeconds)
994 viz::data::RecordingBatch
const& batch = getRecordingBatch(matchingBatchHeader->index);
996 auto timestampLess = [](viz::data::TimestampedLayerUpdate
const& lhs,
997 viz::data::TimestampedLayerUpdate
const& rhs)
998 {
return lhs.timestampInMicroseconds < rhs.timestampInMicroseconds; };
999 viz::data::TimestampedLayerUpdate pivot;
1000 pivot.timestampInMicroseconds = timestamp;
1002 std::lower_bound(batch.updates.begin(), batch.updates.end(), pivot, timestampLess);
1003 if (updateEnd == batch.updates.end())
1007 if (updateEnd != batch.updates.begin())
1014 long revisionBeforeTimestamp = updateEnd->revision;
1015 return revisionBeforeTimestamp;
1019 ArVizWidgetController::onReplayTimedStart(
bool checked)
1025 replayCurrentTimestamp = currentTimestamp;
1034 ArVizWidgetController::onReplayTimerTick()
1038 double replaySpeed = widget.replaySpeedSpinBox->value();
1040 long currentRealTime = IceUtil::Time::now().toMicroSeconds();
1041 long elapsedRealTime = currentRealTime - lastReplayRealTime;
1043 replayCurrentTimestamp += elapsedRealTime * replaySpeed;
1045 long revision = getRevisionForTimestamp(replayCurrentTimestamp);
1048 if (widget.replayLoopbackCheckBox->checkState() == Qt::Checked)
1050 replayCurrentTimestamp = currentRecording.firstTimestampInMicroSeconds;
1054 revision = currentRecording.lastRevision;
1059 widget.replayRevisionSlider->setValue(revision);
1063 lastReplayRealTime = IceUtil::Time::now().toMicroSeconds();
1071 enableWidgetAccordingToMode();
1075 ArVizWidgetController::enableWidgetAccordingToMode()
1081 widget.recordingStartButton->setDisabled(
true);
1082 widget.recordingStopButton->setDisabled(
true);
1083 widget.replayStartButton->setDisabled(
true);
1084 widget.replayStopButton->setDisabled(
true);
1085 widget.replayControlGroupBox->setDisabled(
true);
1090 widget.recordingStartButton->setDisabled(
false);
1091 widget.recordingStopButton->setDisabled(
true);
1092 widget.replayStartButton->setDisabled(
false);
1093 widget.replayStopButton->setDisabled(
true);
1094 widget.replayControlGroupBox->setDisabled(
true);
1095 widget.recordingList->setDisabled(
false);
1100 widget.recordingStartButton->setDisabled(
true);
1101 widget.recordingStopButton->setDisabled(
false);
1102 widget.replayStartButton->setDisabled(
true);
1103 widget.replayStopButton->setDisabled(
true);
1104 widget.replayControlGroupBox->setDisabled(
true);
1109 widget.recordingStartButton->setDisabled(
true);
1110 widget.recordingStopButton->setDisabled(
true);
1111 widget.replayStartButton->setDisabled(
true);
1112 widget.replayStopButton->setDisabled(
false);
1113 widget.replayControlGroupBox->setDisabled(
false);
1114 widget.replayRevisionSlider->setDisabled(
false);
1115 widget.replayRevisionSpinBox->setDisabled(
false);
1116 widget.recordingList->setDisabled(
true);
1121 widget.recordingStartButton->setDisabled(
true);
1122 widget.recordingStopButton->setDisabled(
true);
1123 widget.replayStartButton->setDisabled(
true);
1124 widget.replayStopButton->setDisabled(
false);
1125 widget.replayControlGroupBox->setDisabled(
false);
1126 widget.replayRevisionSlider->setDisabled(
true);
1127 widget.replayRevisionSpinBox->setDisabled(
true);
1128 widget.recordingList->setDisabled(
true);
1133 if (!currentRecordingSelected)
1135 widget.replayStartButton->setDisabled(
true);
1136 widget.replayStopButton->setDisabled(
true);
1144 ARMARX_INFO <<
"Received async batch: " << batch.header.index;
1145 std::unique_lock<std::mutex> lock(recordingBatchCacheMutex);
1147 auto& entry = recordingBatchCache[batch.header.index];
1149 entry.lastUsed = IceUtil::Time::now();
1151 limitRecordingBatchCacheSize();
1153 recordingWaitingForBatchIndex = -1;
1156 viz::data::RecordingBatch
const&
1157 ArVizWidgetController::getRecordingBatch(
long index)
1163 std::unique_lock<std::mutex> lock(recordingBatchCacheMutex);
1165 auto iter = recordingBatchCache.find(
index);
1166 if (iter != recordingBatchCache.end())
1169 bool asyncPrefetchIsRunning = callbackResult && !callbackResult->isCompleted();
1170 if (!asyncPrefetchIsRunning && recordingWaitingForBatchIndex == -1)
1172 if (
index + 1 <
long(currentRecording.batchHeaders.size()) &&
1173 recordingBatchCache.count(
index + 1) == 0)
1178 storage->begin_getRecordingBatch(currentRecording.id,
index + 1, callback);
1179 recordingWaitingForBatchIndex =
index + 1;
1180 ARMARX_INFO <<
"Now waiting for " << recordingWaitingForBatchIndex;
1182 else if (
index > 0 && recordingBatchCache.count(
index - 1) == 0)
1187 storage->begin_getRecordingBatch(currentRecording.id,
index - 1, callback);
1188 recordingWaitingForBatchIndex =
index - 1;
1192 TimestampedRecordingBatch& entry = iter->second;
1193 entry.lastUsed = now;
1198 if (
index == recordingWaitingForBatchIndex)
1203 while (recordingWaitingForBatchIndex != -1)
1205 QCoreApplication::processEvents();
1207 return getRecordingBatch(
index);
1211 <<
" is not in the cache. Getting synchronously, blocking GUI...";
1214 auto& newEntry = recordingBatchCache[
index];
1215 newEntry.lastUsed = now;
1216 newEntry.data = storage->getRecordingBatch(currentRecording.id,
index);
1218 limitRecordingBatchCacheSize();
1220 return newEntry.data;
1224 ArVizWidgetController::limitRecordingBatchCacheSize()
1226 if (recordingBatchCache.size() > recordingBatchCacheMaxSize)
1229 auto oldestIter = recordingBatchCache.begin();
1230 for (
auto iter = recordingBatchCache.begin(); iter != recordingBatchCache.end(); ++iter)
1232 TimestampedRecordingBatch& entry = iter->second;
1233 if (entry.lastUsed < oldestIter->second.lastUsed)
1239 recordingBatchCache.erase(oldestIter);
1246 return visualizer.
root;
1249 static const std::string CONFIG_KEY_STORAGE =
"Storage";
1250 static const std::string CONFIG_KEY_DEBUG_OBSERVER =
"DebugObserver";
1255 storageName = settings->value(QString::fromStdString(CONFIG_KEY_STORAGE),
"ArVizStorage")
1259 settings->value(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
"DebugObserver")
1267 settings->setValue(QString::fromStdString(CONFIG_KEY_STORAGE),
1268 QString::fromStdString(storageName));
1269 settings->setValue(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
1270 QString::fromStdString(debugObserverName));
1279 configDialog->addProxyFinder<armarx::viz::StorageInterfacePrx>(
1280 {CONFIG_KEY_STORAGE,
"ArViz Storage",
"ArViz*"});
1282 {CONFIG_KEY_DEBUG_OBSERVER,
"Debug observer",
"DebugObserver"});
1284 return qobject_cast<QDialog*>(configDialog);
1292 storageName = configDialog->getProxyName(CONFIG_KEY_STORAGE);
1293 debugObserverName = configDialog->getProxyName(CONFIG_KEY_DEBUG_OBSERVER);
1301 QString fi = QFileDialog::getSaveFileName(
1302 Q_NULLPTR, tr(
"VRML 2.0 File"), QString(), tr(
"VRML Files (*.wrl)"));
1303 std::string
s = std::string(fi.toLatin1());