Skip to content

Commit

Permalink
Fix #5114, which is a regression caused by the lazy-loading introduce…
Browse files Browse the repository at this point in the history
…d to fix the GL context issues in the skin selector preview. Since the model node is not immediately loaded when calling ModelPreview::setModel(), the client code needs to rely on the newly exposed signal_ModelLoaded.
  • Loading branch information
codereader committed Jan 7, 2020
1 parent a40214d commit 6a41c6d
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 32 deletions.
21 changes: 21 additions & 0 deletions libs/wxutil/preview/ModelPreview.cpp
Expand Up @@ -34,6 +34,16 @@ ModelPreview::ModelPreview(wxWindow* parent) :
_defaultCamDistanceFactor(2.8f)
{}

const std::string& ModelPreview::getModel() const
{
return _model;
}

const std::string& ModelPreview::getSkin() const
{
return _skin;
}

void ModelPreview::setModel(const std::string& model)
{
// Remember the name and mark the scene as "not ready"
Expand Down Expand Up @@ -130,6 +140,9 @@ void ModelPreview::prepareScene()
}

_modelNode.reset();

// Emit the signal carrying an empty pointer
_modelLoadedSignal.emit(model::ModelNodePtr());
return;
}

Expand Down Expand Up @@ -175,6 +188,9 @@ void ModelPreview::prepareScene()
}

_lastModel = _model;

// Done loading, emit the signal
_modelLoadedSignal.emit(model);
}
}

Expand Down Expand Up @@ -232,4 +248,9 @@ RenderStateFlags ModelPreview::getRenderFlagsFill()
return RenderPreview::getRenderFlagsFill() | RENDER_DEPTHWRITE | RENDER_DEPTHTEST;
}

sigc::signal<void, const model::ModelNodePtr&>& ModelPreview::signal_ModelLoaded()
{
return _modelLoadedSignal;
}

} // namespace ui
12 changes: 12 additions & 0 deletions libs/wxutil/preview/ModelPreview.h
Expand Up @@ -5,6 +5,7 @@
#include "imodel.h"
#include "imap.h"

#include <sigc++/signal.h>
#include <string>
#include <map>

Expand Down Expand Up @@ -49,6 +50,8 @@ class ModelPreview

float _defaultCamDistanceFactor;

sigc::signal<void, const model::ModelNodePtr&> _modelLoadedSignal;

private:

// Creates parent entity etc.
Expand All @@ -67,6 +70,12 @@ class ModelPreview
/// Construct a ModelPreview widget.
ModelPreview(wxWindow* parent);

// Returns the name of the current model
const std::string& getModel() const;

// Returns the name of the current skin
const std::string& getSkin() const;

/**
* Set the widget to display the given model. If the model name is the
* empty string, the widget will release the currently displayed model.
Expand All @@ -88,6 +97,9 @@ class ModelPreview
{
return _modelNode;
}

// Signal emitted when the preview is done loading a new model
sigc::signal<void, const model::ModelNodePtr&>& signal_ModelLoaded();
};
typedef std::shared_ptr<ModelPreview> ModelPreviewPtr;

Expand Down
61 changes: 29 additions & 32 deletions radiant/ui/modelselector/ModelSelector.cpp
Expand Up @@ -112,6 +112,8 @@ ModelSelector::ModelSelector() :

_skinsReloadedConn = GlobalModelSkinCache().signal_skinsReloaded().connect(
sigc::mem_fun(this, &ModelSelector::onSkinsOrModelsReloaded));

_modelPreview->signal_ModelLoaded().connect(sigc::mem_fun(this, &ModelSelector::onModelLoaded));
}

void ModelSelector::setupAdvancedPanel(wxWindow* parent)
Expand Down Expand Up @@ -340,6 +342,33 @@ void ModelSelector::onSkinsOrModelsReloaded()
}
}

void ModelSelector::onModelLoaded(const model::ModelNodePtr& modelNode)
{
if (!modelNode)
{
return;
}

// Update the text in the info table
const model::IModel& model = modelNode->getIModel();

_infoTable->Append(_("Model name"), _modelPreview->getModel());
_infoTable->Append(_("Skin name"), _modelPreview->getSkin());
_infoTable->Append(_("Total vertices"), string::to_string(model.getVertexCount()));
_infoTable->Append(_("Total polys"), string::to_string(model.getPolyCount()));
_infoTable->Append(_("Material surfaces"), string::to_string(model.getSurfaceCount()));

// Add the list of active materials
_materialsList->clear();

const model::StringList& matList(model.getActiveMaterials());

for (const auto& material : matList)
{
_materialsList->addMaterial(material);
}
}

// Helper function to create the TreeView
void ModelSelector::setupTreeView(wxWindow* parent)
{
Expand Down Expand Up @@ -427,38 +456,6 @@ void ModelSelector::showInfoForSelectedModel()
// Pass the model and skin to the preview widget
_modelPreview->setModel(mName);
_modelPreview->setSkin(skinName);

// Check that the model is actually valid by querying the IModelPtr
// returned from the preview widget.
scene::INodePtr mdl = _modelPreview->getModelNode();
if (!mdl) {
return; // no valid model
}

model::ModelNodePtr modelNode = Node_getModel(mdl);

if (!modelNode)
{
return;
}

// Update the text in the info table
const model::IModel& model = modelNode->getIModel();
_infoTable->Append(_("Model name"), mName);
_infoTable->Append(_("Skin name"), skinName);
_infoTable->Append(_("Total vertices"), string::to_string(model.getVertexCount()));
_infoTable->Append(_("Total polys"), string::to_string(model.getPolyCount()));
_infoTable->Append(_("Material surfaces"), string::to_string(model.getSurfaceCount()));

// Add the list of active materials
_materialsList->clear();

const model::StringList& matList(model.getActiveMaterials());

std::for_each(
matList.begin(), matList.end(),
std::bind(&MaterialsList::addMaterial, _materialsList, std::placeholders::_1)
);
}

void ModelSelector::onOK(wxCommandEvent& ev)
Expand Down
2 changes: 2 additions & 0 deletions radiant/ui/modelselector/ModelSelector.h
Expand Up @@ -164,6 +164,8 @@ class ModelSelector :
// Connected to the ModelCache/SkinCache signal, fires after the refresh commands are done
void onSkinsOrModelsReloaded();

void onModelLoaded(const model::ModelNodePtr& modelNode);

protected:
void _onDeleteEvent(wxCloseEvent& ev);

Expand Down

0 comments on commit 6a41c6d

Please sign in to comment.