--Bug fixes

-Rapidly stopping and starting sequence preview generation would either freeze or crash the program.
This commit is contained in:
Person 2019-06-28 18:51:36 -07:00
parent 4929017987
commit afa6dea68a
3 changed files with 13 additions and 27 deletions

View File

@ -400,11 +400,14 @@ void TreePreviewRenderer<T>::PreviewRenderFunc(uint start, uint end)
//It is critical that Qt::BlockingQueuedConnection is passed because this is running on a different thread than the UI. //It is critical that Qt::BlockingQueuedConnection is passed because this is running on a different thread than the UI.
//This ensures the events are processed in order as each preview is updated, and that control does not return here //This ensures the events are processed in order as each preview is updated, and that control does not return here
//until the update is complete. //until the update is complete.
QMetaObject::invokeMethod(f, "SetLibraryTreeItemData", Qt::BlockingQueuedConnection, if (m_PreviewRun)
Q_ARG(EmberTreeWidgetItemBase*, treeItem), {
Q_ARG(vv4F&, m_PreviewFinalImage), QMetaObject::invokeMethod(f, "SetLibraryTreeItemData", Qt::DirectConnection,
Q_ARG(uint, PREVIEW_SIZE), Q_ARG(EmberTreeWidgetItemBase*, treeItem),
Q_ARG(uint, PREVIEW_SIZE)); Q_ARG(vv4F&, m_PreviewFinalImage),
Q_ARG(uint, PREVIEW_SIZE),
Q_ARG(uint, PREVIEW_SIZE));
}
} }
} }
} }

View File

@ -625,7 +625,6 @@ public:
{ {
m_PreviewRun = false; m_PreviewRun = false;
m_PreviewRenderer.Abort(); m_PreviewRenderer.Abort();
m_PreviewResult.cancel();
m_PreviewResult.waitForFinished(); m_PreviewResult.waitForFinished();
} }

View File

@ -132,7 +132,6 @@ void FractoriumEmberController<T>::SyncLibrary(eLibraryUpdate update)
{ {
auto it = m_EmberFile.m_Embers.begin(); auto it = m_EmberFile.m_Embers.begin();
auto tree = m_Fractorium->ui.LibraryTree; auto tree = m_Fractorium->ui.LibraryTree;
tree->blockSignals(true);
if (auto top = tree->topLevelItem(0)) if (auto top = tree->topLevelItem(0))
{ {
@ -154,8 +153,6 @@ void FractoriumEmberController<T>::SyncLibrary(eLibraryUpdate update)
} }
} }
} }
tree->blockSignals(false);
} }
/// <summary> /// <summary>
@ -173,8 +170,7 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
vector<byte> v(size * size * 4); vector<byte> v(size * size * 4);
StopAllPreviewRenderers(); StopAllPreviewRenderers();
tree->clear(); tree->clear();
QCoreApplication::flush(); QCoreApplication::processEvents();
tree->blockSignals(true);
auto fileItem = new QTreeWidgetItem(tree); auto fileItem = new QTreeWidgetItem(tree);
QFileInfo info(m_EmberFile.m_Filename); QFileInfo info(m_EmberFile.m_Filename);
fileItem->setText(0, info.fileName()); fileItem->setText(0, info.fileName());
@ -194,13 +190,10 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
emberItem->SetImage(v, size, size); emberItem->SetImage(v, size, size);
} }
tree->blockSignals(false);
if (selectIndex != -1) if (selectIndex != -1)
m_Fractorium->SelectLibraryItem(selectIndex); m_Fractorium->SelectLibraryItem(selectIndex);
m_Fractorium->SyncFileCountToSequenceCount(); m_Fractorium->SyncFileCountToSequenceCount();
QCoreApplication::flush();
RenderLibraryPreviews(0, uint(m_EmberFile.Size())); RenderLibraryPreviews(0, uint(m_EmberFile.Size()));
tree->expandAll(); tree->expandAll();
} }
@ -220,7 +213,6 @@ void FractoriumEmberController<T>::UpdateLibraryTree()
{ {
int origChildCount = top->childCount(); int origChildCount = top->childCount();
int i = origChildCount; int i = origChildCount;
tree->blockSignals(true);
for (auto it = Advance(m_EmberFile.m_Embers.begin(), i); it != m_EmberFile.m_Embers.end(); ++it) for (auto it = Advance(m_EmberFile.m_Embers.begin(), i); it != m_EmberFile.m_Embers.end(); ++it)
{ {
@ -238,7 +230,6 @@ void FractoriumEmberController<T>::UpdateLibraryTree()
//When adding elements, ensure all indices are sequential. //When adding elements, ensure all indices are sequential.
SyncLibrary(eLibraryUpdate::INDEX); SyncLibrary(eLibraryUpdate::INDEX);
m_Fractorium->SyncFileCountToSequenceCount(); m_Fractorium->SyncFileCountToSequenceCount();
tree->blockSignals(false);
RenderLibraryPreviews(origChildCount, uint(m_EmberFile.Size())); RenderLibraryPreviews(origChildCount, uint(m_EmberFile.Size()));
} }
} }
@ -277,7 +268,6 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
if (oldName == newName)//If nothing changed, nothing to do. if (oldName == newName)//If nothing changed, nothing to do.
return; return;
tree->blockSignals(true);
emberItem->UpdateEmberName();//Copy edit text to the ember's name variable. emberItem->UpdateEmberName();//Copy edit text to the ember's name variable.
m_EmberFile.MakeNamesUnique();//Ensure all names remain unique. m_EmberFile.MakeNamesUnique();//Ensure all names remain unique.
SyncLibrary(eLibraryUpdate::NAME);//Copy all ember names to the tree items since some might have changed to be made unique. SyncLibrary(eLibraryUpdate::NAME);//Copy all ember names to the tree items since some might have changed to be made unique.
@ -289,7 +279,6 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
m_LastSaveCurrent = "";//Reset will force the dialog to show on the next save current since the user probably wants a different name. m_LastSaveCurrent = "";//Reset will force the dialog to show on the next save current since the user probably wants a different name.
} }
tree->blockSignals(false);
} }
else if (auto parentItem = dynamic_cast<QTreeWidgetItem*>(item)) else if (auto parentItem = dynamic_cast<QTreeWidgetItem*>(item))
{ {
@ -433,8 +422,6 @@ void FractoriumEmberController<T>::RenderPreviews(QTreeWidget* tree, TreePreview
if (start == UINT_MAX && end == UINT_MAX) if (start == UINT_MAX && end == UINT_MAX)
{ {
tree->blockSignals(true);
if (auto top = tree->topLevelItem(0)) if (auto top = tree->topLevelItem(0))
{ {
int childCount = top->childCount(); int childCount = top->childCount();
@ -445,7 +432,6 @@ void FractoriumEmberController<T>::RenderPreviews(QTreeWidget* tree, TreePreview
treeItem->SetImage(emptyPreview, PREVIEW_SIZE, PREVIEW_SIZE); treeItem->SetImage(emptyPreview, PREVIEW_SIZE, PREVIEW_SIZE);
} }
tree->blockSignals(false);
renderer->Render(0, uint(file.Size())); renderer->Render(0, uint(file.Size()));
} }
else else
@ -490,8 +476,7 @@ void FractoriumEmberController<T>::FillSequenceTree()
vector<byte> v(size * size * 4); vector<byte> v(size * size * 4);
m_SequencePreviewRenderer->Stop(); m_SequencePreviewRenderer->Stop();
tree->clear(); tree->clear();
QCoreApplication::flush(); QCoreApplication::processEvents();//Having to flush events is usually a sign of poor design. However, in this case, it's critical to have this here, else rapid button clicks will crash.
tree->blockSignals(true);
auto fileItem = new QTreeWidgetItem(tree); auto fileItem = new QTreeWidgetItem(tree);
QFileInfo info(m_SequenceFile.m_Filename); QFileInfo info(m_SequenceFile.m_Filename);
fileItem->setText(0, info.fileName()); fileItem->setText(0, info.fileName());
@ -503,19 +488,18 @@ void FractoriumEmberController<T>::FillSequenceTree()
auto emberItem = new EmberTreeWidgetItemBase(fileItem); auto emberItem = new EmberTreeWidgetItemBase(fileItem);
if (it.m_Name.empty()) if (it.m_Name.empty())
emberItem->setText(0, ToString(i++)); emberItem->setText(0, ToString(i));
else else
emberItem->setText(0, it.m_Name.c_str()); emberItem->setText(0, it.m_Name.c_str());
i++;
emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
emberItem->setToolTip(0, emberItem->text(0)); emberItem->setToolTip(0, emberItem->text(0));
emberItem->SetImage(v, size, size); emberItem->SetImage(v, size, size);
} }
tree->blockSignals(false);
QCoreApplication::flush();
RenderSequencePreviews(0, uint(m_SequenceFile.Size()));
tree->expandAll(); tree->expandAll();
RenderSequencePreviews(0, uint(m_SequenceFile.Size()));
} }
/// <summary> /// <summary>