From 8a5542c34514c796cfd52ea56efaec27180da554 Mon Sep 17 00:00:00 2001 From: codereader Date: Fri, 25 Jun 2021 12:32:22 +0200 Subject: [PATCH] #5107: Prevent the renderer getting into the way of DEF parsing (or vice versa). Block screen updates until the DEFs are fully loaded. Now with this change, the deadlock problem as reported in the issue 5107 is occurring in a resonably large map. This has to be fixed seperately. --- include/ieclass.h | 3 +++ radiant/ui/mainframe/MainFrame.cpp | 21 ++++++++++++++++++--- radiant/ui/mainframe/MainFrame.h | 1 + radiantcore/eclass/EClassManager.cpp | 7 +++++++ radiantcore/eclass/EClassManager.h | 2 ++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/include/ieclass.h b/include/ieclass.h index 18def3b2b3..66b3eedf58 100644 --- a/include/ieclass.h +++ b/include/ieclass.h @@ -330,6 +330,9 @@ class IEntityClassManager : public RegisterableModule { public: + /// Signal emitted when starting to parse DEFs + virtual sigc::signal defsLoadingSignal() const = 0; + /// Signal emitted when all DEFs have been loaded (after module initialisation) virtual sigc::signal defsLoadedSignal() const = 0; diff --git a/radiant/ui/mainframe/MainFrame.cpp b/radiant/ui/mainframe/MainFrame.cpp index 77e9290d1d..c645bd659e 100644 --- a/radiant/ui/mainframe/MainFrame.cpp +++ b/radiant/ui/mainframe/MainFrame.cpp @@ -6,6 +6,7 @@ #include "ieventmanager.h" #include "ipreferencesystem.h" #include "ientityinspector.h" +#include "ieclass.h" #include "iorthoview.h" #include "iregistry.h" #include "iradiant.h" @@ -48,7 +49,8 @@ namespace ui MainFrame::MainFrame() : _topLevelWindow(NULL), - _screenUpdatesEnabled(false) // not enabled until constructed + _screenUpdatesEnabled(false), // not enabled until constructed + _defLoadingBlocksUpdates(false) {} // RegisterableModule implementation @@ -70,6 +72,7 @@ const StringSet& MainFrame::getDependencies() const _dependencies.insert(MODULE_EVENTMANAGER); _dependencies.insert(MODULE_COMMANDSYSTEM); _dependencies.insert(MODULE_ORTHOVIEWMANAGER); + _dependencies.insert(MODULE_ECLASSMANAGER); _dependencies.insert(MODULE_MAP); } @@ -145,6 +148,17 @@ void MainFrame::initialiseModule(const IApplicationContext& ctx) sigc::mem_fun(this, &MainFrame::updateTitle) ); + // When the eclass defs are in progress of being loaded, block all updates + GlobalEntityClassManager().defsLoadingSignal().connect( + [this]() { _defLoadingBlocksUpdates = true; } + ); + + GlobalEntityClassManager().defsLoadedSignal().connect([this]() + { + _defLoadingBlocksUpdates = false; + } + ); + // Subscribe for the post-module init event module::GlobalModuleRegistry().signal_allModulesInitialised().connect( sigc::mem_fun(this, &MainFrame::postModuleInitialisation)); @@ -483,8 +497,9 @@ void MainFrame::saveWindowPosition() } } -bool MainFrame::screenUpdatesEnabled() { - return _screenUpdatesEnabled; +bool MainFrame::screenUpdatesEnabled() +{ + return _screenUpdatesEnabled && !_defLoadingBlocksUpdates; } void MainFrame::enableScreenUpdates() { diff --git a/radiant/ui/mainframe/MainFrame.h b/radiant/ui/mainframe/MainFrame.h index 402cbcb731..e2bb25a161 100644 --- a/radiant/ui/mainframe/MainFrame.h +++ b/radiant/ui/mainframe/MainFrame.h @@ -19,6 +19,7 @@ class MainFrame : TopLevelFrame* _topLevelWindow; bool _screenUpdatesEnabled; + bool _defLoadingBlocksUpdates; wxutil::WindowPosition _windowPosition; diff --git a/radiantcore/eclass/EClassManager.cpp b/radiantcore/eclass/EClassManager.cpp index e1d2788bf8..626b119828 100644 --- a/radiantcore/eclass/EClassManager.cpp +++ b/radiantcore/eclass/EClassManager.cpp @@ -28,6 +28,11 @@ EClassManager::EClassManager() : _curParseStamp(0) {} +sigc::signal EClassManager::defsLoadingSignal() const +{ + return _defsLoadingSignal; +} + sigc::signal EClassManager::defsLoadedSignal() const { return _defsLoadedSignal; @@ -181,6 +186,8 @@ void EClassManager::ensureDefsLoaded() void EClassManager::loadDefAndResolveInheritance() { + _defsLoadingSignal.emit(); + parseDefFiles(); resolveInheritance(); applyColours(); diff --git a/radiantcore/eclass/EClassManager.h b/radiantcore/eclass/EClassManager.h index 9d43fce281..bf171e6285 100644 --- a/radiantcore/eclass/EClassManager.h +++ b/radiantcore/eclass/EClassManager.h @@ -49,6 +49,7 @@ class EClassManager : // definitions have been parsed std::size_t _curParseStamp; + sigc::signal _defsLoadingSignal; sigc::signal _defsLoadedSignal; sigc::signal _defsReloadedSignal; @@ -59,6 +60,7 @@ class EClassManager : EClassManager(); // IEntityClassManager implementation + sigc::signal defsLoadingSignal() const override; sigc::signal defsLoadedSignal() const override; sigc::signal defsReloadedSignal() const override; virtual IEntityClassPtr findOrInsert(const std::string& name,