From 7b950b9628e3e3d6e88e10ddf7cba5827c720bfd Mon Sep 17 00:00:00 2001 From: codereader Date: Mon, 6 Nov 2017 05:51:01 +0100 Subject: [PATCH] Start factoring out the Gui interface to igui.h. --- include/igui.h | 83 +++++++++++++++++++++++++ plugins/dm.gui/GuiSelector.cpp | 2 +- plugins/dm.gui/ReadableEditorDialog.cpp | 4 +- plugins/dm.gui/ReadablePopulator.h | 4 +- plugins/dm.gui/ReadableReloader.h | 8 +-- plugins/dm.gui/gui/GuiManager.cpp | 31 ++++++++- plugins/dm.gui/gui/GuiManager.h | 62 ++++++------------ plugins/dm.gui/gui/GuiView.h | 2 +- plugins/dm.gui/plugin.cpp | 9 +-- tools/msvc/include.vcxproj | 1 + 10 files changed, 143 insertions(+), 63 deletions(-) create mode 100644 include/igui.h diff --git a/include/igui.h b/include/igui.h new file mode 100644 index 0000000000..312b8e99d2 --- /dev/null +++ b/include/igui.h @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include "imodule.h" + +namespace gui +{ + +class Gui; +typedef std::shared_ptr GuiPtr; + +enum GuiType +{ + NOT_LOADED_YET, // no attempt to load the GUI has been made + UNDETERMINED, // not checked yet for type + ONE_SIDED_READABLE, // 1-sided + TWO_SIDED_READABLE, // 2-sided + NO_READABLE, // not a readable + IMPORT_FAILURE, // failed to load + FILE_NOT_FOUND, // file doesn't exist +}; + +/** +* greebo: Interface managing the idTech4 GUI files, +* keeping track of all the loaded GUIs, +* parsing the .gui files on demand. +*/ +class IGuiManager : + public RegisterableModule +{ +public: + typedef std::vector StringList; + + // A visitor class used to traverse all known GUIs by path + class Visitor + { + public: + virtual ~Visitor() {} + + virtual void visit(const std::string& guiPath, const GuiType& guiType) = 0; + }; + +public: + virtual ~IGuiManager() {} + + // Gets a GUI from the given VFS path, parsing it on demand + // Returns NULL if the GUI couldn't be found or loaded. + virtual GuiPtr getGui(const std::string& guiPath) = 0; + + // Returns the number of known GUIs (or GUI paths) + virtual std::size_t getNumGuis() = 0; + + // Traverse all known GUIs using the given Visitor + virtual void foreachGui(Visitor& visitor) = 0; + + // Returns the GUI appearance type for the given GUI path + virtual GuiType getGuiType(const std::string& guiPath) = 0; + + // Reload the gui + virtual void reloadGui(const std::string& guiPath) = 0; + + // Returns the _errorList for use in a GUI. + virtual const StringList& getErrorList() = 0; + + // Clears out the GUIs and reloads them + virtual void reloadGuis() = 0; +}; + +} + +const char* const MODULE_GUIMANAGER("GuiManager"); + +// Application-wide Accessor to the global GUI manager +inline gui::IGuiManager& GlobalGuiManager() +{ + // Cache the reference locally + static gui::IGuiManager& _manager( + *std::static_pointer_cast( + module::GlobalModuleRegistry().getModule(MODULE_GUIMANAGER)) + ); + return _manager; +} diff --git a/plugins/dm.gui/GuiSelector.cpp b/plugins/dm.gui/GuiSelector.cpp index 0f7650265e..30d8bb750c 100644 --- a/plugins/dm.gui/GuiSelector.cpp +++ b/plugins/dm.gui/GuiSelector.cpp @@ -112,7 +112,7 @@ void GuiSelector::fillTrees() wxutil::VFSTreePopulator popTwo(_twoSidedStore); ReadablePopulator walker(popOne, popTwo); - gui::GuiManager::Instance().foreachGui(walker); + GlobalGuiManager().foreachGui(walker); popOne.forEachNode(*this); popTwo.forEachNode(*this); diff --git a/plugins/dm.gui/ReadableEditorDialog.cpp b/plugins/dm.gui/ReadableEditorDialog.cpp index 50bb2020d7..e18785f2d4 100644 --- a/plugins/dm.gui/ReadableEditorDialog.cpp +++ b/plugins/dm.gui/ReadableEditorDialog.cpp @@ -1151,7 +1151,7 @@ void ReadableEditorDialog::checkGuiLayout() std::string msg; - gui::GuiType type = gui::GuiManager::Instance().getGuiType(guiName); + gui::GuiType type = GlobalGuiManager().getGuiType(guiName); switch (type) { @@ -1264,7 +1264,7 @@ void ReadableEditorDialog::showXdImportSummary() void ReadableEditorDialog::showGuiImportSummary() { - XData::StringList errors = gui::GuiManager::Instance().getErrorList(); + XData::StringList errors = GlobalGuiManager().getErrorList(); if (errors.empty()) { wxutil::Messagebox::ShowError(_("No import summary available. Browse Gui Definitions first."), this); diff --git a/plugins/dm.gui/ReadablePopulator.h b/plugins/dm.gui/ReadablePopulator.h index f81e056854..c56a336e9c 100644 --- a/plugins/dm.gui/ReadablePopulator.h +++ b/plugins/dm.gui/ReadablePopulator.h @@ -34,7 +34,7 @@ class ReadablePopulator : _popTwo(popTwo), _progress(_("Analysing Guis")), _count(0), - _numGuis(gui::GuiManager::Instance().getNumGuis()), + _numGuis(GlobalGuiManager().getNumGuis()), _evLimiter(50) {} @@ -51,7 +51,7 @@ class ReadablePopulator : gui::GuiType type; if (guiType == gui::NOT_LOADED_YET || guiType == gui::UNDETERMINED) { - type = gui::GuiManager::Instance().getGuiType(guiPath); + type = GlobalGuiManager().getGuiType(guiPath); } else { diff --git a/plugins/dm.gui/ReadableReloader.h b/plugins/dm.gui/ReadableReloader.h index 82f15317c9..6a8cb84d82 100644 --- a/plugins/dm.gui/ReadableReloader.h +++ b/plugins/dm.gui/ReadableReloader.h @@ -31,7 +31,7 @@ class ReadableReloader : _count(0), _evLimiter(50) { - _numGuis = gui::GuiManager::Instance().getNumGuis(); + _numGuis = GlobalGuiManager().getNumGuis(); } void visit(const std::string& guiPath, const gui::GuiType& guiType) @@ -46,7 +46,7 @@ class ReadableReloader : if (guiType != gui::NOT_LOADED_YET) { - gui::GuiManager::Instance().reloadGui(guiPath); + GlobalGuiManager().reloadGui(guiPath); } } @@ -54,10 +54,10 @@ class ReadableReloader : { try { - gui::GuiManager::Instance().reloadGuis(); + GlobalGuiManager().reloadGuis(); ReadableReloader reloader; - gui::GuiManager::Instance().foreachGui(reloader); + GlobalGuiManager().foreachGui(reloader); } catch (wxutil::ModalProgressDialog::OperationAbortedException&) {} diff --git a/plugins/dm.gui/gui/GuiManager.cpp b/plugins/dm.gui/gui/GuiManager.cpp index 75be31470b..3ac6806610 100644 --- a/plugins/dm.gui/gui/GuiManager.cpp +++ b/plugins/dm.gui/gui/GuiManager.cpp @@ -192,10 +192,35 @@ GuiPtr GuiManager::loadGui(const std::string& guiPath) } } -GuiManager& GuiManager::Instance() +const std::string& GuiManager::getName() const { - static GuiManager _instance; - return _instance; + static std::string _name(MODULE_GUIMANAGER); + return _name; +} + +const StringSet& GuiManager::getDependencies() const +{ + static StringSet _dependencies; + + if (_dependencies.empty()) + { + _dependencies.insert(MODULE_VIRTUALFILESYSTEM); + } + + return _dependencies; +} + +void GuiManager::initialiseModule(const ApplicationContext& ctx) +{ + rMessage() << getName() << "::initialiseModule called." << std::endl; + + // Search the VFS for GUIs + init(); +} + +void GuiManager::shutdownModule() +{ + clear(); } } // namespace gui diff --git a/plugins/dm.gui/gui/GuiManager.h b/plugins/dm.gui/gui/GuiManager.h index 5f90ca5f9c..24b996f623 100644 --- a/plugins/dm.gui/gui/GuiManager.h +++ b/plugins/dm.gui/gui/GuiManager.h @@ -1,11 +1,10 @@ #pragma once +#include "igui.h" #include "util/Noncopyable.h" -#include #include #include "ifilesystem.h" #include "string/string.h" -#include #include "ThreadedDefLoader.h" namespace gui @@ -17,17 +16,6 @@ namespace const std::string GUI_EXT("gui"); } -enum GuiType -{ - NOT_LOADED_YET, // no attempt to load the GUI has been made - UNDETERMINED, // not checked yet for type - ONE_SIDED_READABLE, // 1-sided - TWO_SIDED_READABLE, // 2-sided - NO_READABLE, // not a readable - IMPORT_FAILURE, // failed to load - FILE_NOT_FOUND, // file doesn't exist -}; - class Gui; typedef std::shared_ptr GuiPtr; @@ -36,20 +24,9 @@ typedef std::shared_ptr GuiPtr; * including parsing the .gui files on demand. */ class GuiManager : - public util::Noncopyable + public IGuiManager, + public util::Noncopyable { -public: - typedef std::vector StringList; - - // A visitor class used to traverse all known GUIs by path - class Visitor - { - public: - virtual ~Visitor() {} - - virtual void visit(const std::string& guiPath, const GuiType& guiType) = 0; - }; - private: struct GuiInfo { @@ -78,40 +55,41 @@ class GuiManager : // A List of all the errors occuring lastly. StringList _errorList; - GuiManager(); - public: + GuiManager(); + // Gets a GUI from the given VFS path, parsing it on demand // Returns NULL if the GUI couldn't be found or loaded. - GuiPtr getGui(const std::string& guiPath); + GuiPtr getGui(const std::string& guiPath) override; // Returns the number of known GUIs (or GUI paths) - std::size_t getNumGuis(); + std::size_t getNumGuis() override; // Traverse all known GUIs using the given Visitor - void foreachGui(Visitor& visitor); + void foreachGui(Visitor& visitor) override; // Returns the GUI appearance type for the given GUI path - GuiType getGuiType(const std::string& guiPath); + GuiType getGuiType(const std::string& guiPath) override; // Reload the gui - void reloadGui(const std::string& guiPath); + void reloadGui(const std::string& guiPath) override; // Returns the _errorList for use in a GUI. - const StringList& getErrorList() { return _errorList; } - - // Provides access to the singleton - static GuiManager& Instance(); - - void init(); + const StringList& getErrorList() override { return _errorList; } // Clears out the GUIs and reloads them - void reloadGuis(); + void reloadGuis() override; - // Clears all internal objects - void clear(); + // RegisterableModule + const std::string& GuiManager::getName() const override; + const StringSet& GuiManager::getDependencies() const override; + void initialiseModule(const ApplicationContext& ctx) override; + void shutdownModule() override; private: + void init(); + void clear(); + // Searches the VFS for all available GUI definitions void findGuis(); diff --git a/plugins/dm.gui/gui/GuiView.h b/plugins/dm.gui/gui/GuiView.h index 093e8e5637..d22dcfd6f2 100644 --- a/plugins/dm.gui/gui/GuiView.h +++ b/plugins/dm.gui/gui/GuiView.h @@ -36,7 +36,7 @@ class GuiView : // Sets the GUI to render (by VFS path) void setGui(const std::string& gui) { - setGui(GuiManager::Instance().getGui(gui)); + setGui(GlobalGuiManager().getGui(gui)); } // Sets the GUI to render (can be NULL to clear this view) diff --git a/plugins/dm.gui/plugin.cpp b/plugins/dm.gui/plugin.cpp index e27580a3e9..d27d93f2b5 100644 --- a/plugins/dm.gui/plugin.cpp +++ b/plugins/dm.gui/plugin.cpp @@ -76,9 +76,6 @@ class GuiModule : sigc::mem_fun(this, &GuiModule::onRadiantStartup) ); - // Search the VFS for GUIs - gui::GuiManager::Instance().init(); - // Create the Readable Editor Preferences constructPreferences(); } @@ -119,11 +116,6 @@ class GuiModule : page.appendPathEntry(_("Custom Folder"), ui::RKEY_READABLES_CUSTOM_FOLDER, true); } - - void shutdownModule() - { - gui::GuiManager::Instance().clear(); - } }; typedef std::shared_ptr GuiModulePtr; @@ -132,4 +124,5 @@ extern "C" void DARKRADIANT_DLLEXPORT RegisterModule(IModuleRegistry& registry) module::performDefaultInitialisation(registry); registry.registerModule(GuiModulePtr(new GuiModule)); + registry.registerModule(std::make_shared()); } diff --git a/tools/msvc/include.vcxproj b/tools/msvc/include.vcxproj index 5d9dfaa858..7d97a0b289 100644 --- a/tools/msvc/include.vcxproj +++ b/tools/msvc/include.vcxproj @@ -133,6 +133,7 @@ +