Skip to content

Commit

Permalink
#5127: It's easier to break an outer loop with an exception, use this…
Browse files Browse the repository at this point in the history
… in the MediaBrowserTreeView populator.
  • Loading branch information
codereader committed Jan 2, 2021
1 parent b13ba22 commit 06b3bb8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
42 changes: 33 additions & 9 deletions libs/wxutil/dataview/ThreadedResourceTreePopulator.h
@@ -1,5 +1,6 @@
#pragma once

#include <stdexcept>
#include <wx/thread.h>
#include <wx/event.h>
#include "TreeModel.h"
Expand All @@ -25,6 +26,14 @@ class ThreadedResourceTreePopulator :
protected wxThread
{
private:
// Custom exception type thrown when a thread is cancelled
struct ThreadAbortedException : public std::runtime_error
{
ThreadAbortedException() :
runtime_error("Thread aborted")
{}
};

// The event handler to notify on completion
wxEvtHandler* _finishedHandler;

Expand All @@ -39,6 +48,15 @@ class ThreadedResourceTreePopulator :
bool _started;

protected:
// Wrapper around TestDestroy that escalated by throwing a
// ThreadAbortedException when cancellation has been requested
void ThrowIfCancellationRequested()
{
if (TestDestroy())
{
throw ThreadAbortedException();
}
}

// Needed method to load data into the allocated tree model
// This is called from within the worker thread
Expand All @@ -51,21 +69,27 @@ class ThreadedResourceTreePopulator :
// The worker function that will run in a separate thread
virtual wxThread::ExitCode Entry() override
{
// Create new treestore
_treeStore = new TreeModel(_columns);
_treeStore->SetHasDefaultCompare(false);
try
{
// Create new treestore
_treeStore = new TreeModel(_columns);
_treeStore->SetHasDefaultCompare(false);

PopulateModel(_treeStore);
PopulateModel(_treeStore);

if (TestDestroy()) return static_cast<ExitCode>(0);
ThrowIfCancellationRequested();

// Sort the model while we're still in the worker thread
SortModel(_treeStore);
// Sort the model while we're still in the worker thread
SortModel(_treeStore);

ThrowIfCancellationRequested();

if (!TestDestroy())
{
wxQueueEvent(_finishedHandler, new TreeModel::PopulationFinishedEvent(_treeStore));
}
catch (const ThreadAbortedException&)
{
// Thread aborted due to Cancel request, exit now
}

return static_cast<ExitCode>(0);
}
Expand Down
6 changes: 5 additions & 1 deletion radiant/ui/mediabrowser/MediaBrowserTreeView.cpp
Expand Up @@ -191,7 +191,11 @@ class MediaPopulator final :
model->SetHasDefaultCompare(false);

ShaderNameFunctor functor(*model, _columns, _favourites);
GlobalMaterialManager().foreachShaderName(std::bind(&ShaderNameFunctor::visit, &functor, std::placeholders::_1));
GlobalMaterialManager().foreachShaderName([&](const std::string& name)
{
ThrowIfCancellationRequested();
functor.visit(name);
});
}

// Special sort algorithm to sort the "Other Materials" separately
Expand Down

0 comments on commit 06b3bb8

Please sign in to comment.