Skip to content

Commit

Permalink
#6030: Add interface to update a material from a given source text. W…
Browse files Browse the repository at this point in the history
…hen the source view contents in the MaterialEditor changes, the material will try to update itself from the source.

Fix a crash when trying to acquire an editable shader layer with the "Global Settings" item selected.
  • Loading branch information
codereader committed Aug 15, 2022
1 parent f543b45 commit 2810846
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 5 deletions.
6 changes: 6 additions & 0 deletions include/ishaders.h
Expand Up @@ -444,6 +444,12 @@ class Material
// Reloads the textures used by this material from disk
virtual void refreshImageMaps() = 0;

// Attempts to redefine this material from the given source text, which is
// just the block contents, exlcuding the outermost curly braces of the decl.
// Returns true on success, returns false if the source text could not
// be successfully parsed (e.g. due to malformed syntax).
virtual bool updateFromSourceText(const std::string& sourceText) = 0;

// Signal emitted when this material is modified
virtual sigc::signal<void>& sig_materialChanged() = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion libs/wxutil/sourceview/SourceView.cpp
Expand Up @@ -128,7 +128,7 @@ D3MaterialSourceViewCtrl::D3MaterialSourceViewCtrl(wxWindow* parent) :
D3DeclarationViewCtrl(parent)
{
SetKeyWords(0, "diffusemap qer_editorimage bumpmap specularmap map if description polygonOffset "
"noshadows noselfshadow forceshadows nooverlays forceoverlays translucent clamp zeroclamp "
"noshadows noShadows noselfshadow forceshadows nooverlays forceoverlays translucent clamp zeroclamp "
"alphazeroclamp forceopaque twosided backsided mirror nofog unsmoothedTangents guisurf sort "
"decal reflect spectrum deform decalInfo renderbump DECAL_MACRO sprite tube flare expand move "
"turbulent eyeBall particle particle2 noportalfog fogLight blendLight ambientLight lightFallOffImage "
Expand Down
23 changes: 21 additions & 2 deletions radiant/ui/materials/editor/MaterialEditor.cpp
Expand Up @@ -134,7 +134,8 @@ MaterialEditor::MaterialEditor() :
_stageView(nullptr),
_stageUpdateInProgress(false),
_materialUpdateInProgress(false),
_previewSceneUpdateInProgress(false)
_previewSceneUpdateInProgress(false),
_updateFromSourceTextInProgress(false)
{
loadNamedPanel(this, "MaterialEditorMainPanel");

Expand Down Expand Up @@ -312,6 +313,8 @@ void MaterialEditor::setupSourceTextPanel(wxWindow* previewPanel)
_sourceView = new wxutil::D3MaterialSourceViewCtrl(sourceTextPanel->GetPane());
_sourceView->SetMinSize(wxSize(-1, 400));

_sourceView->Bind(wxEVT_TEXT, &MaterialEditor::_onSourceTextChanged, this);

sourceTextPanel->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, [=](wxCollapsiblePaneEvent& ev)
{
previewPanel->Layout();
Expand Down Expand Up @@ -420,6 +423,20 @@ void MaterialEditor::_onReloadImages(wxCommandEvent& ev)
updateBasicImagePreview();
}

void MaterialEditor::_onSourceTextChanged(wxCommandEvent& ev)
{
if (!_material) return;

// Block source text updates
util::ScopedBoolLock lock(_updateFromSourceTextInProgress);

if (_material->updateFromSourceText(_sourceView->GetValue().ToStdString()))
{
// Update the controls on success
updateControlsFromMaterial();
}
}

bool MaterialEditor::okToCloseDialog()
{
// Check all unsaved materials
Expand Down Expand Up @@ -2359,6 +2376,8 @@ void MaterialEditor::updateMaterialPropertiesFromMaterial()

void MaterialEditor::updateSourceView()
{
if (_updateFromSourceTextInProgress) return; // avoid feedback loops

if (_material)
{
// Surround the definition with curly braces, these are not included
Expand Down Expand Up @@ -2415,7 +2434,7 @@ IEditableShaderLayer::Ptr MaterialEditor::getEditableStageForSelection()
wxutil::TreeModel::Row stageRow(selectedStageItem, *_stageList);
int stageIndex = stageRow[STAGE_COLS().index].getInteger();

return _material->getEditableLayer(stageIndex);
return stageIndex != -1 ? _material->getEditableLayer(stageIndex) : IEditableShaderLayer::Ptr();
}

void MaterialEditor::updateStageBlendControls()
Expand Down
2 changes: 2 additions & 0 deletions radiant/ui/materials/editor/MaterialEditor.h
Expand Up @@ -87,6 +87,7 @@ class MaterialEditor :
bool _stageUpdateInProgress;
bool _materialUpdateInProgress;
bool _previewSceneUpdateInProgress;
bool _updateFromSourceTextInProgress;

std::string _materialToPreselect;

Expand Down Expand Up @@ -208,6 +209,7 @@ class MaterialEditor :
void _onBasicTestFrobStages(wxMouseEvent& ev);
void _onClose(wxCommandEvent& ev);
void _onReloadImages(wxCommandEvent& ev);
void _onSourceTextChanged(wxCommandEvent& ev);

void applyMapExpressionToStage(const IEditableShaderLayer::Ptr& stage, const std::string& value);
void toggleSelectedStage();
Expand Down
5 changes: 5 additions & 0 deletions radiantcore/shaders/CShader.cpp
Expand Up @@ -674,4 +674,9 @@ void CShader::refreshImageMaps()
_sigMaterialModified.emit();
}

bool CShader::updateFromSourceText(const std::string& sourceText)
{
return false;
}

} // namespace shaders
4 changes: 2 additions & 2 deletions radiantcore/shaders/CShader.h
Expand Up @@ -147,11 +147,11 @@ class CShader final :

void refreshImageMaps() override;

bool updateFromSourceText(const std::string& sourceText) override;

// Returns the current template (including any modifications) of this material
const ShaderTemplate::Ptr& getTemplate();



private:
void ensureTemplateCopy();
void subscribeToTemplateChanges();
Expand Down

0 comments on commit 2810846

Please sign in to comment.