27 #include <SimoxUtility/algorithm/string/string_tools.h>
30 #include <QMessageBox>
32 #include <QFileDialog>
41 void onSuccess(viz::data::RecordingBatch
const& batch)
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, &QPushButton::clicked,
this, &This::onRefreshRecordings);
78 connect(widget.recordingList, &QListWidget::currentItemChanged,
this, &This::onRecordingSelectionChanged);
80 connect(widget.replayRevisionSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
this, &This::onReplaySpinChanged);
81 connect(widget.replayRevisionSlider, QOverload<int>::of(&QSlider::valueChanged),
this, &This::onReplaySliderChanged);
83 connect(widget.replayStartButton, &QPushButton::clicked,
this, &This::onReplayStart);
84 connect(widget.replayStopButton, &QPushButton::clicked,
this, &This::onReplayStop);
85 connect(widget.replayTimedButton, &QPushButton::toggled,
this, &This::onReplayTimedStart);
89 connect(widget.deselectButton, &QPushButton::clicked,
this, &This::onDeselectElement);
90 connect(widget.listInteractiveElements, &QListWidget::itemDoubleClicked,
this, &This::onInteractiveElementSelected);
92 connect(
this, &This::connectGui,
this, &This::onConnectGui, Qt::QueuedConnection);
93 connect(
this, &This::disconnectGui,
this, &This::onDisconnectGui, Qt::QueuedConnection);
97 connect(widget.layerTree, &QTreeWidget::currentItemChanged,
this, &This::updateSelectedLayer);
100 connect(widget.defaultShowLimitSpinBox, qOverload<int>(&QSpinBox::valueChanged),
104 layerInfoTree.
setWidget(widget.layerInfoTree);
105 layerInfoTree.
setEnabled(widget.layerInfoTreeGroupBox->isChecked());
113 layersChanged(layers);
116 replayTimer->start(33);
126 if (storageName.size() > 0)
130 if (debugObserverName.size() > 0)
136 callbackData->this_ =
this;
137 callback = viz::newCallback_StorageInterface_getRecordingBatch(
152 if (!debugObserverName.empty())
154 getProxy(debugObserver, debugObserverName,
false,
"",
false);
170 void ArVizWidgetController::onConnectGui()
172 onRefreshRecordings();
173 currentRecordingSelected =
false;
176 updateTimer->start(33);
179 void ArVizWidgetController::onDisconnectGui()
186 void ArVizWidgetController::layerTreeChanged(QTreeWidgetItem* item,
int )
189 int componentCount = widget.layerTree->topLevelItemCount();
190 for (
int compIndex = 0; compIndex < componentCount; ++compIndex)
192 QTreeWidgetItem* componentItem = widget.layerTree->topLevelItem(compIndex);
193 std::string
component = componentItem->text(0).toStdString();
194 Qt::CheckState componentCheck = componentItem->checkState(0);
195 int layerCount = componentItem->childCount();
197 if (componentItem == item)
201 for (
int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
203 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
204 if (layerItem->checkState(0) != componentCheck)
206 layerItem->setCheckState(0, componentCheck);
212 for (
int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
214 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
215 std::string layer = layerItem->text(0).toStdString();
216 bool layerVisible = (layerItem->checkState(0) == Qt::Checked);
217 ARMARX_VERBOSE <<
"Layer: " << layer <<
", Visible: " << layerVisible;
220 visualizer.
showLayer(layerID, layerVisible);
225 void ArVizWidgetController::layersChanged(std::vector<viz::CoinLayerID>
const& layers)
227 QTreeWidget* tree = widget.layerTree;
229 std::map<std::string, QTreeWidgetItem*> currentComponents;
230 std::map<viz::CoinLayerID, QTreeWidgetItem*> currentLayers;
231 int componentCount = widget.layerTree->topLevelItemCount();
232 for (
int compIndex = 0; compIndex < componentCount; ++compIndex)
234 QTreeWidgetItem* componentItem = widget.layerTree->topLevelItem(compIndex);
235 std::string
component = componentItem->text(0).toStdString();
236 currentComponents.emplace(component, componentItem);
238 int layerCount = componentItem->childCount();
239 for (
int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
241 QTreeWidgetItem* layerItem = componentItem->child(layerIndex);
242 std::string layer = layerItem->text(0).toStdString();
245 currentLayers.emplace(layerID, layerItem);
249 const QList<QTreeWidgetItem*> selectedItems = widget.layerTree->selectedItems();
252 QTreeWidgetItem* currentItem =
nullptr;
253 bool componentWasNew =
false;
254 std::string currentComponent;
255 for (
auto& entry : layers)
257 std::string
const&
component = entry.first;
258 if (component != currentComponent)
260 auto iter = currentComponents.find(component);
261 if (iter == currentComponents.end())
264 currentItem =
new QTreeWidgetItem(tree);
265 currentItem->setText(0, QString::fromStdString(component));
267 currentItem->setCheckState(0, Qt::Checked);
269 componentWasNew =
true;
274 currentItem = iter->second;
276 componentWasNew =
false;
282 auto iter = currentLayers.find(entry);
283 if (iter == currentLayers.end())
286 std::string
const& layer = entry.second;
287 QTreeWidgetItem* layerItem =
new QTreeWidgetItem;
288 layerItem->setText(0, QString::fromStdString(layer));
290 layerItem->setCheckState(0, Qt::Checked);
294 currentItem->addChild(layerItem);
299 tree->expandItem(currentItem);
305 <<
"Invalid component/layer ID: "
306 << entry.first <<
" / " << entry.second;
316 void ArVizWidgetController::updateSelectedLayer(QTreeWidgetItem* current, QTreeWidgetItem* previous)
320 if (!current->parent())
327 viz::CoinLayerID id(current->parent()->text(0).toStdString(), current->text(0).toStdString());
330 if (layer ==
nullptr)
332 ARMARX_WARNING <<
"Could not find layer (" <<
id.first <<
" / " <<
id.second <<
") in Visualizer.";
340 void ArVizWidgetController::onCollapseAll(
bool)
342 widget.layerTree->collapseAll();
345 void ArVizWidgetController::onExpandAll(
bool)
347 widget.layerTree->expandAll();
350 void ArVizWidgetController::onHideAll(
bool)
352 showAllLayers(
false);
355 void ArVizWidgetController::onShowAll(
bool)
360 void ArVizWidgetController::onHideFiltered(
bool)
362 showFilteredLayers(
false);
365 void ArVizWidgetController::onShowFiltered(
bool)
367 showFilteredLayers(
true);
370 void ArVizWidgetController::onFilterTextChanged(
const QString& filter)
374 QRegExp rx(filter, Qt::CaseInsensitive, QRegExp::Wildcard);
375 for (QTreeWidgetItemIterator iter(widget.layerTree); *iter; ++iter)
377 QTreeWidgetItem* item = *iter;
378 QString itemText = item->text(0);
379 bool matches = filter.size() == 0 || itemText.contains(rx);
384 item->parent()->setHidden(
false);
389 void ArVizWidgetController::showAllLayers(
bool visible)
391 widget.layerTree->blockSignals(
true);
393 for (QTreeWidgetItemIterator iter(widget.layerTree); *iter; ++iter)
395 QTreeWidgetItem* item = *iter;
396 item->setCheckState(0, visible ? Qt::Checked : Qt::Unchecked);
399 widget.layerTree->blockSignals(
false);
402 layerTreeChanged(
nullptr, 0);
405 void ArVizWidgetController::showFilteredLayers(
bool visible)
407 widget.layerTree->blockSignals(
true);
409 QString filter = widget.filterEdit->text();
410 QRegExp rx(filter, Qt::CaseInsensitive, QRegExp::Wildcard);
412 for (QTreeWidgetItemIterator iter(widget.layerTree); *iter; ++iter)
414 QTreeWidgetItem* item = *iter;
415 QString itemText = item->text(0);
416 bool matches = filter.size() == 0 || itemText.contains(rx);
419 item->setCheckState(0, visible ? Qt::Checked : Qt::Unchecked);
423 widget.layerTree->blockSignals(
false);
426 layerTreeChanged(
nullptr, 0);
429 void ArVizWidgetController::onDeselectElement()
436 void ArVizWidgetController::onContextMenuClicked()
439 if (selected ==
nullptr)
441 ARMARX_WARNING <<
"Selected element is null, but a context menu option was clicked!";
445 QPushButton* clickedButton =
static_cast<QPushButton*
>(sender());
447 QLayout* layout = widget.groupBoxContextMenu->layout();
448 int count = layout->count();
449 for (
int i = 0; i < count; ++i)
451 QPushButton* button =
static_cast<QPushButton*
>(layout->itemAt(i)->widget());
452 if (button == clickedButton)
458 interaction.type = viz::data::InteractionFeedbackType::CONTEXT_MENU_CHOSEN;
465 void ArVizWidgetController::onInteractiveElementSelected(QListWidgetItem* item)
467 int index = widget.listInteractiveElements->row(item);
478 std::string
id = inter.
layer.first +
"/"
479 + inter.
layer.second +
"/"
481 return QString::fromStdString(
id);
484 void ArVizWidgetController::onUpdate()
489 QString selectedElementName(
"<None>");
490 QLayout* contextMenuLayout = widget.groupBoxContextMenu->layout();
496 int currentCount = contextMenuLayout->count();
498 std::vector<std::string>
const& options = desc.contextMenuOptions;
500 if (desc.enableFlags & viz::data::InteractionEnableFlags::CONTEXT_MENU)
502 newCount = (int)options.size();
504 if (newCount != currentCount)
508 while ((item = contextMenuLayout->takeAt( 0 )) !=
nullptr)
510 delete item->widget();
514 for (std::string
const&
option : options)
516 QPushButton* button =
new QPushButton(
517 QString::fromStdString(
option),
518 widget.groupBoxContextMenu);
519 connect(button, &QPushButton::clicked,
this, &ArVizWidgetController::onContextMenuClicked);
520 contextMenuLayout->addWidget(button);
525 for (
int i = 0; i < currentCount; ++i)
527 QLayoutItem* item = contextMenuLayout->itemAt(i);
528 QPushButton* button =
static_cast<QPushButton*
>(item->widget());
529 button->setText(QString::fromStdString(options[i]));
536 while ((item = contextMenuLayout->takeAt( 0 )) !=
nullptr)
538 delete item->widget();
542 widget.labelSelectedElement->setText(selectedElementName);
545 int currentCount = widget.listInteractiveElements->count();
547 if (newCount != currentCount)
549 widget.listInteractiveElements->clear();
553 widget.listInteractiveElements->addItem(elementID);
557 onTimingObserverUpdate();
560 void ArVizWidgetController::onTimingObserverUpdate()
567 timingMap[
"0. pull (ms)"] =
new Variant(timing.
pull.toMilliSecondsDouble());
568 timingMap[
"1. apply (ms)"] =
new Variant(timing.
applyTotal.
total.toMilliSecondsDouble());
569 timingMap[
"1.1 apply, addLayer (ms)"] =
new Variant(timing.
applyTotal.
addLayer.toMilliSecondsDouble());
572 timingMap[
"2. layers (ms)"] =
new Variant(timing.
layersChanged.toMilliSecondsDouble());
573 timingMap[
"3. wait duration (ms)"] =
new Variant(timing.
waitDuration.toMilliSecondsDouble());
574 timingMap[
"4. update toggle"] =
new Variant(timing.
updateToggle);
575 timingMap[
"total (ms)"] =
new Variant(timing.
total.toMilliSecondsDouble());
577 timings.push_back(timing.
total.toMilliSecondsDouble());
579 if ((
int)timings.size() > numTimings)
581 timings.erase(timings.begin());
583 double averageTime = std::accumulate(timings.begin(), timings.end(), 0.0) / numTimings;
584 timingMap[
"total avg (ms)"] =
new Variant(averageTime);
586 debugObserver->begin_setDebugChannel(
"ArViz_Timing", timingMap);
591 void ArVizWidgetController::onStartRecording()
593 std::string recordingID = widget.recordingIdTextBox->text().toStdString();
595 std::string runningID = storage->startRecording(recordingID);
599 if (runningID.size() > 0)
601 std::string
message =
"There is already a recording running with ID '"
602 + runningID +
"'. \n"
603 +
"You have to stop the running recording first";
604 QMessageBox::information(widget.tabWidget,
606 QString::fromStdString(
message));
614 void ArVizWidgetController::onStopRecording()
616 storage->stopRecording();
618 onRefreshRecordings();
622 void ArVizWidgetController::onRefreshRecordings()
624 allRecordings = storage->getAllRecordings().recordings;
625 std::sort(allRecordings.begin(), allRecordings.end(),
628 return lhs.id < rhs.id;
631 std::string currentText;
632 QListWidgetItem* currentItem = widget.recordingList->currentItem();
635 currentText = currentItem->text().toStdString();
638 widget.recordingList->clear();
639 int currentTextIndex = -1;
641 for (
auto& recording : allRecordings)
643 if (recording.id == currentText)
645 currentTextIndex =
index;
647 widget.recordingList->addItem(QString::fromStdString(recording.id));
651 if (currentTextIndex > 0)
653 widget.recordingList->setCurrentRow(currentTextIndex);
657 void ArVizWidgetController::onRecordingSelectionChanged(QListWidgetItem* current, QListWidgetItem* previous)
664 std::string selectedID = current->text().toStdString();
667 if (recording.id == selectedID)
669 selectRecording(recording);
675 static std::string timestampToString(
long timestampInMicroSeconds,
bool showMS =
false)
677 IceUtil::Time time = IceUtil::Time::microSeconds(timestampInMicroSeconds);
678 std::string timeString = time.toDateTime();
681 timeString = timeString.substr(0, timeString.size() - 4);
686 void ArVizWidgetController::onReplaySpinChanged(
int newValue)
688 widget.replayRevisionSlider->setValue(newValue);
691 void ArVizWidgetController::onReplaySliderChanged(
int newValue)
693 if (currentRevision != newValue)
695 long timestamp = replayToRevision(newValue);
698 currentRevision = newValue;
699 currentTimestamp = timestamp;
700 widget.replayRevisionSpinBox->setValue(newValue);
703 widget.replayTimestampLabel->setText(QString::fromStdString(
704 timestampToString(timestamp,
true)
709 widget.replayRevisionSlider->setValue(currentRevision);
717 widget.recordingIdLabel->setText(QString::fromStdString(recording.id));
719 widget.recordingRevisionLabel->setText(QString::fromStdString(
724 std::string firstTimeString = timestampToString(recording.firstTimestampInMicroSeconds);
725 std::string lastTimeString = timestampToString(recording.lastTimestampInMicroSeconds);
727 widget.recordingTimestampLabel->setText(QString::fromStdString(
733 recording.lastTimestampInMicroSeconds -
734 recording.firstTimestampInMicroSeconds);
735 int durationSeconds = duration.toSeconds();
736 widget.recordingDurationLabel->setText(QString::fromStdString(
739 widget.recordingBatchesLabel->setText(QString::fromStdString(
744 currentRecording = recording;
745 currentRecordingSelected =
true;
746 enableWidgetAccordingToMode();
749 void ArVizWidgetController::onReplayStart(
bool)
751 if (!currentRecordingSelected)
753 ARMARX_WARNING <<
"No recording selected, so no replay can be started";
757 std::unique_lock<std::mutex> lock(recordingBatchCacheMutex);
758 recordingBatchCache.clear();
765 widget.replayRevisionSpinBox->blockSignals(
true);
766 widget.replayRevisionSpinBox->setMinimum(currentRecording.firstRevision);
767 widget.replayRevisionSpinBox->setMaximum(currentRecording.lastRevision);
768 widget.replayRevisionSpinBox->setValue(currentRecording.firstRevision);
769 widget.replayRevisionSpinBox->blockSignals(
false);
771 widget.replayRevisionSlider->blockSignals(
true);
772 widget.replayRevisionSlider->setMinimum(currentRecording.firstRevision);
773 widget.replayRevisionSlider->setMaximum(currentRecording.lastRevision);
774 widget.replayRevisionSlider->setValue(currentRecording.firstRevision);
775 widget.replayRevisionSlider->blockSignals(
false);
777 currentRevision = -1;
778 onReplaySliderChanged(widget.replayRevisionSlider->value());
781 void ArVizWidgetController::onReplayStop(
bool)
788 long ArVizWidgetController::replayToRevision(
long revision)
792 ARMARX_WARNING <<
"Cannot call replayToRevision, when not in replaying mode.\n"
793 <<
"Actual mode: " << int(mode);
797 viz::data::RecordingBatchHeader* matchingBatchHeader =
nullptr;
798 for (
auto& batchHeader : currentRecording.batchHeaders)
800 if (batchHeader.firstRevision <= revision &&
801 revision <= batchHeader.lastRevision)
803 matchingBatchHeader = &batchHeader;
807 if (matchingBatchHeader ==
nullptr)
809 ARMARX_WARNING <<
"Could not find batch for revision: " << revision;
813 viz::data::RecordingBatch
const& batch = getRecordingBatch(matchingBatchHeader->index);
816 <<
"\nGot batch: " << batch.header.firstRevision <<
" - " << batch.header.lastRevision
817 <<
"\nUpdates: " << batch.updates.size()
818 <<
"\nInitial state: " << batch.initialState.size();
821 auto revisionLess = [](viz::data::TimestampedLayerUpdate
const & lhs, viz::data::TimestampedLayerUpdate
const & rhs)
823 return lhs.revision < rhs.revision;
825 viz::data::TimestampedLayerUpdate pivot;
826 pivot.revision = revision;
827 auto updateBegin = std::lower_bound(batch.updates.begin(), batch.updates.end(), pivot, revisionLess);
828 auto updateEnd = std::upper_bound(updateBegin, batch.updates.end(), pivot, revisionLess);
831 std::map<std::string, viz::data::LayerUpdate const*> updates;
833 for (
auto&
update : batch.initialState)
837 for (
auto updateIter = batch.updates.begin(); updateIter != updateEnd; ++updateIter)
839 updates[updateIter->update.name] = &updateIter->update;
843 for (
auto& pair : updates)
845 visualizer.
apply(*pair.second);
848 if (layerIDsAfter != layerIDsBefore)
853 return updateBegin->timestampInMicroseconds;
856 long ArVizWidgetController::getRevisionForTimestamp(
long timestamp)
860 ARMARX_WARNING <<
"Cannot call replayToTimestamp, when not in replaying mode.\n"
861 <<
"Actual mode: " << int(mode);
865 if (timestamp < currentRecording.firstTimestampInMicroSeconds)
867 ARMARX_INFO <<
"Requested timestamp is earlier than recording: " << timestampToString(timestamp);
871 viz::data::RecordingBatchHeader* matchingBatchHeader =
nullptr;
872 for (
auto& batchHeader : currentRecording.batchHeaders)
874 matchingBatchHeader = &batchHeader;
875 if (timestamp <= batchHeader.lastTimestampInMicroSeconds)
881 viz::data::RecordingBatch
const& batch = getRecordingBatch(matchingBatchHeader->index);
883 auto timestampLess = [](viz::data::TimestampedLayerUpdate
const & lhs, viz::data::TimestampedLayerUpdate
const & rhs)
885 return lhs.timestampInMicroseconds < rhs.timestampInMicroseconds;
887 viz::data::TimestampedLayerUpdate pivot;
888 pivot.timestampInMicroseconds = timestamp;
889 auto updateEnd = std::lower_bound(batch.updates.begin(), batch.updates.end(), pivot, timestampLess);
890 if (updateEnd == batch.updates.end())
894 if (updateEnd != batch.updates.begin())
901 long revisionBeforeTimestamp = updateEnd->revision;
902 return revisionBeforeTimestamp;
905 void ArVizWidgetController::onReplayTimedStart(
bool checked)
911 replayCurrentTimestamp = currentTimestamp;
919 void ArVizWidgetController::onReplayTimerTick()
923 double replaySpeed = widget.replaySpeedSpinBox->value();
925 long currentRealTime = IceUtil::Time::now().toMicroSeconds();
926 long elapsedRealTime = currentRealTime - lastReplayRealTime;
928 replayCurrentTimestamp += elapsedRealTime * replaySpeed;
930 long revision = getRevisionForTimestamp(replayCurrentTimestamp);
933 if (widget.replayLoopbackCheckBox->checkState() == Qt::Checked)
935 replayCurrentTimestamp = currentRecording.firstTimestampInMicroSeconds;
939 revision = currentRecording.lastRevision;
944 widget.replayRevisionSlider->setValue(revision);
948 lastReplayRealTime = IceUtil::Time::now().toMicroSeconds();
955 enableWidgetAccordingToMode();
958 void ArVizWidgetController::enableWidgetAccordingToMode()
964 widget.recordingStartButton->setDisabled(
true);
965 widget.recordingStopButton->setDisabled(
true);
966 widget.replayStartButton->setDisabled(
true);
967 widget.replayStopButton->setDisabled(
true);
968 widget.replayControlGroupBox->setDisabled(
true);
973 widget.recordingStartButton->setDisabled(
false);
974 widget.recordingStopButton->setDisabled(
true);
975 widget.replayStartButton->setDisabled(
false);
976 widget.replayStopButton->setDisabled(
true);
977 widget.replayControlGroupBox->setDisabled(
true);
978 widget.recordingList->setDisabled(
false);
983 widget.recordingStartButton->setDisabled(
true);
984 widget.recordingStopButton->setDisabled(
false);
985 widget.replayStartButton->setDisabled(
true);
986 widget.replayStopButton->setDisabled(
true);
987 widget.replayControlGroupBox->setDisabled(
true);
992 widget.recordingStartButton->setDisabled(
true);
993 widget.recordingStopButton->setDisabled(
true);
994 widget.replayStartButton->setDisabled(
true);
995 widget.replayStopButton->setDisabled(
false);
996 widget.replayControlGroupBox->setDisabled(
false);
997 widget.replayRevisionSlider->setDisabled(
false);
998 widget.replayRevisionSpinBox->setDisabled(
false);
999 widget.recordingList->setDisabled(
true);
1004 widget.recordingStartButton->setDisabled(
true);
1005 widget.recordingStopButton->setDisabled(
true);
1006 widget.replayStartButton->setDisabled(
true);
1007 widget.replayStopButton->setDisabled(
false);
1008 widget.replayControlGroupBox->setDisabled(
false);
1009 widget.replayRevisionSlider->setDisabled(
true);
1010 widget.replayRevisionSpinBox->setDisabled(
true);
1011 widget.recordingList->setDisabled(
true);
1016 if (!currentRecordingSelected)
1018 widget.replayStartButton->setDisabled(
true);
1019 widget.replayStopButton->setDisabled(
true);
1026 ARMARX_INFO <<
"Received async batch: " << batch.header.index;
1027 std::unique_lock<std::mutex> lock(recordingBatchCacheMutex);
1029 auto& entry = recordingBatchCache[batch.header.index];
1031 entry.lastUsed = IceUtil::Time::now();
1033 limitRecordingBatchCacheSize();
1035 recordingWaitingForBatchIndex = -1;
1038 viz::data::RecordingBatch
const& ArVizWidgetController::getRecordingBatch(
long index)
1044 std::unique_lock<std::mutex> lock(recordingBatchCacheMutex);
1046 auto iter = recordingBatchCache.find(
index);
1047 if (iter != recordingBatchCache.end())
1050 bool asyncPrefetchIsRunning = callbackResult && !callbackResult->isCompleted();
1051 if (!asyncPrefetchIsRunning && recordingWaitingForBatchIndex == -1)
1053 if (
index + 1 <
long(currentRecording.batchHeaders.size())
1054 && recordingBatchCache.count(
index + 1) == 0)
1058 callbackResult = storage->begin_getRecordingBatch(currentRecording.id,
index + 1, callback);
1059 recordingWaitingForBatchIndex =
index + 1;
1060 ARMARX_INFO <<
"Now waiting for " << recordingWaitingForBatchIndex;
1062 else if (
index > 0 && recordingBatchCache.count(
index - 1) == 0)
1066 callbackResult = storage->begin_getRecordingBatch(currentRecording.id,
index - 1, callback);
1067 recordingWaitingForBatchIndex =
index - 1;
1072 TimestampedRecordingBatch& entry = iter->second;
1073 entry.lastUsed = now;
1078 if (
index == recordingWaitingForBatchIndex)
1083 while (recordingWaitingForBatchIndex != -1)
1085 QCoreApplication::processEvents();
1087 return getRecordingBatch(
index);
1090 ARMARX_INFO <<
"Batch #" <<
index <<
" is not in the cache. Getting synchronously, blocking GUI...";
1093 auto& newEntry = recordingBatchCache[
index];
1094 newEntry.lastUsed = now;
1095 newEntry.data = storage->getRecordingBatch(currentRecording.id,
index);
1097 limitRecordingBatchCacheSize();
1099 return newEntry.data;
1102 void ArVizWidgetController::limitRecordingBatchCacheSize()
1104 if (recordingBatchCache.size() > recordingBatchCacheMaxSize)
1107 auto oldestIter = recordingBatchCache.begin();
1108 for (
auto iter = recordingBatchCache.begin();
1109 iter != recordingBatchCache.end(); ++iter)
1111 TimestampedRecordingBatch& entry = iter->second;
1112 if (entry.lastUsed < oldestIter->second.lastUsed)
1118 recordingBatchCache.erase(oldestIter);
1124 return visualizer.
root;
1127 static const std::string CONFIG_KEY_STORAGE =
"Storage";
1128 static const std::string CONFIG_KEY_DEBUG_OBSERVER =
"DebugObserver";
1132 storageName = settings->value(QString::fromStdString(CONFIG_KEY_STORAGE),
1133 "ArVizStorage").toString().toStdString();
1134 debugObserverName = settings->value(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
1135 "DebugObserver").toString().toStdString();
1140 settings->setValue(QString::fromStdString(CONFIG_KEY_STORAGE),
1141 QString::fromStdString(storageName));
1142 settings->setValue(QString::fromStdString(CONFIG_KEY_DEBUG_OBSERVER),
1143 QString::fromStdString(debugObserverName));
1151 configDialog->addProxyFinder<armarx::viz::StorageInterfacePrx>({CONFIG_KEY_STORAGE,
"ArViz Storage",
"ArViz*"});
1154 return qobject_cast<QDialog*>(configDialog);
1161 storageName = configDialog->getProxyName(CONFIG_KEY_STORAGE);
1162 debugObserverName = configDialog->getProxyName(CONFIG_KEY_DEBUG_OBSERVER);
1170 QString fi = QFileDialog::getSaveFileName(Q_NULLPTR, tr(
"VRML 2.0 File"), QString(), tr(
"VRML Files (*.wrl)"));
1171 std::string
s = std::string(fi.toLatin1());