Skip to content

Commit

Permalink
#5127: Another abstraction to allow for non-threaded populator implem…
Browse files Browse the repository at this point in the history
…entations. The ResourceTreeView is planned to work with the IResourceTreePopulator only.
  • Loading branch information
codereader committed Jan 2, 2021
1 parent 4b479e6 commit a8498d4
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 24 deletions.
34 changes: 34 additions & 0 deletions libs/wxutil/dataview/IResourceTreePopulator.h
@@ -0,0 +1,34 @@
#pragma once

#include "ResourceTreeView.h"

namespace wxutil
{

/**
* TreeView populator interface, used to load data
* into a TreeModel instance used by ResourceTreeView.
*
* It provides an interface to deal with threaded implementations:
* - Populate(): will at least start the population, might return
* before or after the work is done.
* - EnsurePopulated(): will ensure that the population has been
* started and will block until it's done.
*/
class IResourceTreePopulator
{
public:
using Ptr = std::shared_ptr<IResourceTreePopulator>;

virtual ~IResourceTreePopulator() {}

// Will start the population and block until population is done.
virtual void EnsurePopulated() = 0;

// Start the population process, unless it's already running
// This might spawn a worker thread which performs the
// population in the background - use EnsurePopulated to synchronise.
virtual void Populate() = 0;
};

}
2 changes: 1 addition & 1 deletion libs/wxutil/dataview/ResourceTreeView.h
Expand Up @@ -27,7 +27,7 @@ class ResourceTreeView :
// The base structure defining a few needed default column.
// Subclasses may derive from this struct to expand it
struct Columns :
public wxutil::TreeModel::ColumnRecord
public TreeModel::ColumnRecord
{
Columns() :
iconAndName(add(TreeModel::Column::IconText)),
Expand Down
Expand Up @@ -3,16 +3,18 @@
#include <wx/thread.h>
#include <wx/event.h>
#include "TreeModel.h"
#include "IResourceTreePopulator.h"

namespace wxutil
{

/**
* Threaded helper class to load data into a ResourceTreeView.
* Threaded resource tree populator implementation class.
* Subclasses need to implement the abstract members to add
* the needed insertion or sorting logic.
*/
class ResourceTreePopulator :
class ThreadedResourceTreePopulator :
public IResourceTreePopulator,
protected wxThread
{
private:
Expand All @@ -26,6 +28,9 @@ class ResourceTreePopulator :
// updating the target tree store from a different thread isn't safe
TreeModel::Ptr _treeStore;

// Whether this thread has been started at all
bool _started;

protected:

// Needed method to load data into the allocated tree model
Expand Down Expand Up @@ -60,38 +65,47 @@ class ResourceTreePopulator :

public:
// Construct and initialise variables
ResourceTreePopulator(const TreeModel::ColumnRecord& columns, wxEvtHandler* finishedHandler) :
ThreadedResourceTreePopulator(const TreeModel::ColumnRecord& columns, wxEvtHandler* finishedHandler) :
wxThread(wxTHREAD_JOINABLE),
_finishedHandler(finishedHandler),
_columns(columns)
_columns(columns),
_started(false)
{}

~ResourceTreePopulator()
~ThreadedResourceTreePopulator()
{
if (IsRunning())
if (IsAlive())
{
Delete(); // cancel the running thread
}
}

// Blocks until the worker thread is done.
// Returns immediately if the thread is not running
void WaitUntilFinished()
void EnsurePopulated() override
{
// Start the thread now if we have to
if (!_started)
{
Populate();
}

// Wait for any running thread
if (IsRunning())
{
Wait();
}
}

// Start the thread, if it isn't already running
void Run()
void Populate() override
{
if (IsRunning())
{
return;
}

// Set the latch
_started = true;
wxThread::Run();
}
};
Expand Down
15 changes: 5 additions & 10 deletions radiant/ui/mediabrowser/MediaBrowserTreeView.cpp
Expand Up @@ -161,7 +161,7 @@ struct ShaderNameFunctor
};

class Populator :
public wxutil::ResourceTreePopulator
public wxutil::ThreadedResourceTreePopulator
{
private:
const MediaBrowserTreeView::TreeColumns& _columns;
Expand All @@ -172,7 +172,7 @@ class Populator :
public:
// Construct and initialise variables
Populator(const MediaBrowserTreeView::TreeColumns& columns, wxEvtHandler* finishedHandler) :
ResourceTreePopulator(columns, finishedHandler),
ThreadedResourceTreePopulator(columns, finishedHandler),
_columns(columns)
{
_favourites = GlobalFavouritesManager().getFavourites(decl::Type::Material);
Expand Down Expand Up @@ -315,7 +315,7 @@ void MediaBrowserTreeView::populate()

// Start the background thread
_populator.reset(new Populator(_columns, this));
_populator->Run();
_populator->Populate();
}

void MediaBrowserTreeView::clear()
Expand All @@ -334,13 +334,8 @@ void MediaBrowserTreeView::_onTreeStorePopulationFinished(wxutil::TreeModel::Pop

void MediaBrowserTreeView::setSelection(const std::string& fullName)
{
if (!_isPopulated)
{
populate();
}

// Make sure the treestore is finished loading
_populator->WaitUntilFinished();
// Make sure the treestore is loaded
_populator->EnsurePopulated();

ResourceTreeView::setSelection(fullName);
}
Expand Down
4 changes: 2 additions & 2 deletions radiant/ui/mediabrowser/MediaBrowserTreeView.h
@@ -1,7 +1,7 @@
#pragma once

#include "wxutil/dataview/ResourceTreeView.h"
#include "wxutil/dataview/ResourceTreePopulator.h"
#include "wxutil/dataview/ThreadedResourceTreePopulator.h"
#include "wxutil/menu/IconTextMenuItem.h"
#include "wxutil/dataview/TreeModelFilter.h"

Expand All @@ -25,7 +25,7 @@ class MediaBrowserTreeView :

private:
// Populates the Media Browser in its own thread
std::unique_ptr<wxutil::ResourceTreePopulator> _populator;
std::unique_ptr<wxutil::ThreadedResourceTreePopulator> _populator;

// false, if the tree is not yet initialised.
bool _isPopulated;
Expand Down
3 changes: 2 additions & 1 deletion tools/msvc/wxutillib.vcxproj
Expand Up @@ -139,9 +139,10 @@
<ClInclude Include="..\..\libs\wxutil\ChoiceHelper.h" />
<ClInclude Include="..\..\libs\wxutil\ConsoleView.h" />
<ClInclude Include="..\..\libs\wxutil\ControlButton.h" />
<ClInclude Include="..\..\libs\wxutil\dataview\IResourceTreePopulator.h" />
<ClInclude Include="..\..\libs\wxutil\dataview\KeyValueTable.h" />
<ClInclude Include="..\..\libs\wxutil\dataview\ResourceTreePopulator.h" />
<ClInclude Include="..\..\libs\wxutil\dataview\ResourceTreeView.h" />
<ClInclude Include="..\..\libs\wxutil\dataview\ThreadedResourceTreePopulator.h" />
<ClInclude Include="..\..\libs\wxutil\dataview\TreeModel.h" />
<ClInclude Include="..\..\libs\wxutil\dataview\TreeModelFilter.h" />
<ClInclude Include="..\..\libs\wxutil\dataview\TreeView.h" />
Expand Down
5 changes: 4 additions & 1 deletion tools/msvc/wxutillib.vcxproj.filters
Expand Up @@ -133,7 +133,10 @@
<ClInclude Include="..\..\libs\wxutil\dataview\VFSTreePopulator.h">
<Filter>dataview</Filter>
</ClInclude>
<ClInclude Include="..\..\libs\wxutil\dataview\ResourceTreePopulator.h">
<ClInclude Include="..\..\libs\wxutil\dataview\IResourceTreePopulator.h">
<Filter>dataview</Filter>
</ClInclude>
<ClInclude Include="..\..\libs\wxutil\dataview\ThreadedResourceTreePopulator.h">
<Filter>dataview</Filter>
</ClInclude>
</ItemGroup>
Expand Down

0 comments on commit a8498d4

Please sign in to comment.