Skip to content

Commit

Permalink
#5534: EntityClassChooser is no longer a static singleton
Browse files Browse the repository at this point in the history
Since populating the tree for this dialog is very quick, there is no benefit in
keeping a singleton around. Creating a new dialog each time requires much less
code and also fixes the major issue described in #5534, namely that the dialog
is always empty on its second showing.

There is still a problem with the search feature (at least on Linux), which
results in the tree view becoming empty as soon as any text is entered in the
search box. However it is at least now possible to resume normal service by
closing the dialog and showing another one.
  • Loading branch information
Matthew Mott authored and codereader committed Feb 11, 2021
1 parent a362d0f commit fd4b5f9
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 55 deletions.
48 changes: 7 additions & 41 deletions libs/wxutil/EntityClassChooser.cpp
Expand Up @@ -89,7 +89,7 @@ class EntityClassTreePopulator:
// of the DISPLAY_FOLDER_KEY.
addPath(
eclass->getModName() + folderPath + "/" + eclass->getName(),
[&](TreeModel::Row& row, const std::string& path,
[&](TreeModel::Row& row, const std::string& path,
const std::string& leafName, bool isFolder)
{
bool isFavourite = !isFolder && _favourites.count(leafName) > 0;
Expand Down Expand Up @@ -144,7 +144,7 @@ class ThreadedEntityClassLoader final :
};

// Main constructor
EntityClassChooser::EntityClassChooser() :
EntityClassChooser::EntityClassChooser() :
DialogBase(_(ECLASS_CHOOSER_TITLE)),
_treeView(nullptr),
_selectedName("")
Expand Down Expand Up @@ -203,57 +203,23 @@ EntityClassChooser::EntityClassChooser() :
// Display the singleton instance
std::string EntityClassChooser::chooseEntityClass(const std::string& preselectEclass)
{
EntityClassChooser instance;

if (!preselectEclass.empty())
{
Instance().setSelectedEntityClass(preselectEclass);
instance.setSelectedEntityClass(preselectEclass);
}

if (Instance().ShowModal() == wxID_OK)
if (instance.ShowModal() == wxID_OK)
{
return Instance().getSelectedEntityClass();
return instance.getSelectedEntityClass();
}
else
{
return ""; // Empty selection on cancel
}
}

EntityClassChooser& EntityClassChooser::Instance()
{
EntityClassChooserPtr& instancePtr = InstancePtr();

if (!instancePtr)
{
// Not yet instantiated, do it now
instancePtr.reset(new EntityClassChooser);

// Pre-destruction cleanup
GlobalMainFrame().signal_MainFrameShuttingDown().connect(
sigc::mem_fun(*instancePtr, &EntityClassChooser::onMainFrameShuttingDown)
);
}

return *instancePtr;
}

EntityClassChooserPtr& EntityClassChooser::InstancePtr()
{
static EntityClassChooserPtr _instancePtr;
return _instancePtr;
}

void EntityClassChooser::onMainFrameShuttingDown()
{
rMessage() << "EntityClassChooser shutting down." << std::endl;

_modelPreview.reset();
_defsReloaded.disconnect();

// Final step at shutdown, release the shared ptr
Instance().SendDestroyEvent();
InstancePtr().reset();
}

void EntityClassChooser::loadEntityClasses()
{
_treeView->Populate(std::make_shared<ThreadedEntityClassLoader>(_columns));
Expand Down
24 changes: 10 additions & 14 deletions libs/wxutil/EntityClassChooser.h
Expand Up @@ -61,31 +61,27 @@ class EntityClassChooser :
void onOK(wxCommandEvent& ev);
void onSelectionChanged(wxDataViewEvent& ev);
void onDeleteEvent(wxCloseEvent& ev);

void onMainFrameShuttingDown();

// This is where the static shared_ptr of the singleton instance is held.
static EntityClassChooserPtr& InstancePtr();

public:
// Public accessor to the singleton instance
static EntityClassChooser& Instance();

// Sets the tree selection to the given entity class
void setSelectedEntityClass(const std::string& eclass);

// Sets the tree selection to the given entity class
const std::string& getSelectedEntityClass() const;

// Overridden from wxDialog
int ShowModal() override;

public:

/**
* Convenience function:
* Display the dialog and block awaiting the selection of an entity class,
* which is returned to the caller. If the dialog is cancelled or no
* selection is made, and empty string will be returned.
* \brief Construct and show the dialog to choose an entity class,
* returning the result.
*
* \param preselectEclass
* Optional initial class to locate and highlight in the tree after the
* dialog is shown.
*/
static std::string chooseEntityClass(const std::string& preselectEclass = std::string());
static std::string chooseEntityClass(const std::string& preselectEclass = {});
};

} // namespace

0 comments on commit fd4b5f9

Please sign in to comment.