From fd7adb152f573af834911994622c6368b3fc8b53 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Wed, 10 Jun 2015 17:47:56 +0100 Subject: [PATCH] LootState object is no longer global. g_app_state has been replaced by a member variable in LootApp. For #450. --- src/gui/handler.cpp | 178 +++++++++++++++++++-------------------- src/gui/handler.h | 5 +- src/gui/loot_app.cpp | 5 +- src/gui/loot_app.h | 4 + src/gui/loot_handler.cpp | 15 ++-- src/gui/loot_handler.h | 6 +- src/gui/loot_state.cpp | 2 - src/gui/loot_state.h | 2 - src/gui/main_win.cpp | 2 +- 9 files changed, 112 insertions(+), 107 deletions(-) diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index 908bd56f..7089f7e6 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -25,7 +25,7 @@ #include "handler.h" #include "resource.h" #include "loot_app.h" -#include "loot_state.h" +#include "loot_handler.h" #include "../backend/error.h" #include "../backend/globals.h" @@ -55,7 +55,7 @@ namespace fs = boost::filesystem; namespace loc = boost::locale; namespace loot { - Handler::Handler() {} + Handler::Handler(LootState& lootState) : _lootState(lootState) {} // Called due to cefQuery execution in binding.html. bool Handler::OnQuery(CefRefPtr browser, @@ -129,7 +129,7 @@ namespace loot { else if (request == "redatePlugins") { BOOST_LOG_TRIVIAL(debug) << "Redating plugins."; try { - g_app_state.CurrentGame().RedatePlugins(); + _lootState.CurrentGame().RedatePlugins(); callback->Success(""); } catch (error &e) { @@ -150,7 +150,7 @@ namespace loot { return CefPostTask(TID_FILE, base::Bind(&Handler::SortPlugins, base::Unretained(this), frame, callback)); } else if (request == "getInitErrors") { - YAML::Node node(g_app_state.InitErrors()); + YAML::Node node(_lootState.InitErrors()); if (node.size() > 0) callback->Success(JSON::stringify(node)); else @@ -158,12 +158,12 @@ namespace loot { return true; } else if (request == "cancelSort") { - --g_app_state.numUnappliedChanges; + --_lootState.numUnappliedChanges; callback->Success(""); return true; } else if (request == "editorOpened") { - ++g_app_state.numUnappliedChanges; + ++_lootState.numUnappliedChanges; callback->Success(""); return true; } @@ -171,7 +171,7 @@ namespace loot { // This version of the editorClosed query has no arguments as it is // sent when editing is cancelled. Just update the unapplied changes // counter. - --g_app_state.numUnappliedChanges; + --_lootState.numUnappliedChanges; callback->Success(""); return true; } @@ -203,7 +203,7 @@ namespace loot { if (requestName == "changeGame") { try { // Has one arg, which is the folder name of the new game. - g_app_state.ChangeGame(request["args"][0].as()); + _lootState.ChangeGame(request["args"][0].as()); CefPostTask(TID_FILE, base::Bind(&Handler::GetGameData, base::Unretained(this), frame, callback)); } @@ -247,20 +247,20 @@ namespace loot { BOOST_LOG_TRIVIAL(debug) << "Editor for plugin closed."; // One argument, which is the plugin metadata that has changed (+ its name). callback->Success(ApplyUserEdits(request["args"][0])); - --g_app_state.numUnappliedChanges; + --_lootState.numUnappliedChanges; return true; } else if (requestName == "closeSettings") { BOOST_LOG_TRIVIAL(trace) << "Settings dialog closed and changes accepted, updating settings object."; // Update the game details and settings. - g_app_state.UpdateSettings(request["args"][0]); + _lootState.UpdateSettings(request["args"][0]); // If the user has deleted a default game, we don't want to restore it now. // It will be restored when LOOT is next loaded. try { BOOST_LOG_TRIVIAL(trace) << "Updating games object."; list games(request["args"][0]["games"].as< list >()); - g_app_state.UpdateGames(games); + _lootState.UpdateGames(games); // Also enable/disable debug logging as required. if (request["args"][0]["enableDebugLogging"] && request["args"][0]["enableDebugLogging"].as()) @@ -279,10 +279,10 @@ namespace loot { return true; } else if (requestName == "applySort") { - --g_app_state.numUnappliedChanges; + --_lootState.numUnappliedChanges; BOOST_LOG_TRIVIAL(trace) << "User has accepted sorted load order, applying it."; try { - g_app_state.CurrentGame().SetLoadOrder(request["args"][0].as>()); + _lootState.CurrentGame().SetLoadOrder(request["args"][0].as>()); callback->Success(""); } catch (error &e) { @@ -333,7 +333,7 @@ namespace loot { } size_t i = 0; for (const auto& plugin : plugins) { - if (g_app_state.CurrentGame().IsActive(plugin)) { + if (_lootState.CurrentGame().IsActive(plugin)) { ss << setw(decLength) << i << " " << hex << setw(2) << i << dec << " "; ++i; } @@ -359,11 +359,11 @@ namespace loot { // Has two args: the first is the filter ID, the second is the value. BOOST_LOG_TRIVIAL(trace) << "Saving filter states."; try { - YAML::Node settings = g_app_state.GetSettings(); + YAML::Node settings = _lootState.GetSettings(); settings["filters"][request["args"][0].as()] = request["args"][1]; - g_app_state.UpdateSettings(settings); + _lootState.UpdateSettings(settings); callback->Success(""); } catch (exception &e) { @@ -378,23 +378,23 @@ namespace loot { void Handler::GetConflictingPlugins(const std::string& pluginName, CefRefPtr frame, CefRefPtr callback) { BOOST_LOG_TRIVIAL(debug) << "Searching for plugins that conflict with " << pluginName; - auto pluginIt = g_app_state.CurrentGame().plugins.find(boost::locale::to_lower(pluginName)); + auto pluginIt = _lootState.CurrentGame().plugins.find(boost::locale::to_lower(pluginName)); // Checking for FormID overlap will only work if the plugins have been loaded, so check if // the plugins have been fully loaded, and if not load all plugins. - if (!g_app_state.CurrentGame().HasBeenLoaded()) { + if (!_lootState.CurrentGame().HasBeenLoaded()) { SendProgressUpdate(frame, loc::translate("Loading plugin contents...")); - g_app_state.CurrentGame().LoadPlugins(false); + _lootState.CurrentGame().LoadPlugins(false); } SendProgressUpdate(frame, loc::translate("Checking for conflicting plugins...")); YAML::Node node; - for (const auto& pluginPair : g_app_state.CurrentGame().plugins) { + for (const auto& pluginPair : _lootState.CurrentGame().plugins) { YAML::Node pluginNode; pluginNode["crc"] = pluginPair.second.Crc(); pluginNode["isEmpty"] = pluginPair.second.IsEmpty(); - if (pluginIt != g_app_state.CurrentGame().plugins.end() && pluginIt->second.DoFormIDsOverlap(pluginPair.second)) { + if (pluginIt != _lootState.CurrentGame().plugins.end() && pluginIt->second.DoFormIDsOverlap(pluginPair.second)) { BOOST_LOG_TRIVIAL(debug) << "Found conflicting plugin: " << pluginPair.second.Name(); pluginNode["conflicts"] = true; } @@ -422,8 +422,8 @@ namespace loot { BOOST_LOG_TRIVIAL(debug) << "Copying metadata for plugin " << pluginName; // Get metadata from masterlist and userlist. - Plugin plugin = g_app_state.CurrentGame().masterlist.FindPlugin(pluginName); - plugin.MergeMetadata(g_app_state.CurrentGame().userlist.FindPlugin(pluginName)); + Plugin plugin = _lootState.CurrentGame().masterlist.FindPlugin(pluginName); + plugin.MergeMetadata(_lootState.CurrentGame().userlist.FindPlugin(pluginName)); // Generate text representation. string text; @@ -443,10 +443,10 @@ namespace loot { std::string Handler::ClearPluginMetadata(const std::string& pluginName) { BOOST_LOG_TRIVIAL(debug) << "Clearing user metadata for plugin " << pluginName; - g_app_state.CurrentGame().userlist.ErasePlugin(Plugin(pluginName)); + _lootState.CurrentGame().userlist.ErasePlugin(Plugin(pluginName)); // Save userlist edits. - g_app_state.CurrentGame().userlist.Save(g_app_state.CurrentGame().UserlistPath()); + _lootState.CurrentGame().userlist.Save(_lootState.CurrentGame().UserlistPath()); // Now rederive the displayed metadata from the masterlist. YAML::Node derivedMetadata = GenerateDerivedMetadata(pluginName); @@ -462,7 +462,7 @@ namespace loot { Plugin newUserlistEntry(pluginMetadata["name"].as()); // Find existing userlist entry. - Plugin ulistPlugin = g_app_state.CurrentGame().userlist.FindPlugin(newUserlistEntry); + Plugin ulistPlugin = _lootState.CurrentGame().userlist.FindPlugin(newUserlistEntry); // First sort out the priority value. This is only given if it was changed. BOOST_LOG_TRIVIAL(trace) << "Calculating userlist metadata priority value from Javascript variables."; @@ -515,33 +515,33 @@ namespace loot { // For cleanliness, only data that does not duplicate masterlist and plugin data should be retained, so diff that. BOOST_LOG_TRIVIAL(trace) << "Removing any user metadata that duplicates masterlist metadata."; - auto pluginIt = g_app_state.CurrentGame().plugins.find(boost::locale::to_lower(newUserlistEntry.Name())); - if (pluginIt != g_app_state.CurrentGame().plugins.end()) { + auto pluginIt = _lootState.CurrentGame().plugins.find(boost::locale::to_lower(newUserlistEntry.Name())); + if (pluginIt != _lootState.CurrentGame().plugins.end()) { Plugin tempPlugin(pluginIt->second); - tempPlugin.MergeMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(newUserlistEntry)); + tempPlugin.MergeMetadata(_lootState.CurrentGame().masterlist.FindPlugin(newUserlistEntry)); newUserlistEntry = newUserlistEntry.NewMetadata(tempPlugin); } else - newUserlistEntry = newUserlistEntry.NewMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(newUserlistEntry)); + newUserlistEntry = newUserlistEntry.NewMetadata(_lootState.CurrentGame().masterlist.FindPlugin(newUserlistEntry)); // Now replace existing userlist entry with the new one. if (!ulistPlugin.HasNameOnly()) { BOOST_LOG_TRIVIAL(trace) << "Replacing existing userlist entry with new metadata."; if (newUserlistEntry.HasNameOnly()) - g_app_state.CurrentGame().userlist.ErasePlugin(ulistPlugin); + _lootState.CurrentGame().userlist.ErasePlugin(ulistPlugin); else { // Set members are static, so just erase and add the new data. - g_app_state.CurrentGame().userlist.ErasePlugin(ulistPlugin); - g_app_state.CurrentGame().userlist.AddPlugin(newUserlistEntry); + _lootState.CurrentGame().userlist.ErasePlugin(ulistPlugin); + _lootState.CurrentGame().userlist.AddPlugin(newUserlistEntry); } } else { BOOST_LOG_TRIVIAL(trace) << "Adding new metadata to new userlist entry."; - g_app_state.CurrentGame().userlist.AddPlugin(newUserlistEntry); + _lootState.CurrentGame().userlist.AddPlugin(newUserlistEntry); } // Save edited userlist. - g_app_state.CurrentGame().userlist.Save(g_app_state.CurrentGame().UserlistPath()); + _lootState.CurrentGame().userlist.Save(_lootState.CurrentGame().UserlistPath()); // Now rederive the derived metadata. BOOST_LOG_TRIVIAL(trace) << "Returning newly derived display metadata."; @@ -576,7 +576,7 @@ namespace loot { std::string Handler::GetSettings() { BOOST_LOG_TRIVIAL(info) << "Getting LOOT settings."; - return JSON::stringify(g_app_state.GetSettings()); + return JSON::stringify(_lootState.GetSettings()); } std::string Handler::GetLanguages() { @@ -604,7 +604,7 @@ namespace loot { std::string Handler::GetInstalledGames() { BOOST_LOG_TRIVIAL(info) << "Getting LOOT's detected games."; - YAML::Node temp = YAML::Node(g_app_state.InstalledGames()); + YAML::Node temp = YAML::Node(_lootState.InstalledGames()); if (temp.size() > 0) return JSON::stringify(temp); else @@ -625,48 +625,48 @@ namespace loot { SendProgressUpdate(frame, loc::translate("Loading plugin headers...")); // First clear CRC and condition caches, otherwise they could lead to incorrect evaluations. - g_app_state.CurrentGame().conditionCache.clear(); - g_app_state.CurrentGame().crcCache.clear(); + _lootState.CurrentGame().conditionCache.clear(); + _lootState.CurrentGame().crcCache.clear(); // Also refresh active plugins list. - g_app_state.CurrentGame().RefreshActivePluginsList(); + _lootState.CurrentGame().RefreshActivePluginsList(); - bool isFirstLoad = g_app_state.CurrentGame().plugins.empty(); - g_app_state.CurrentGame().LoadPlugins(true); + bool isFirstLoad = _lootState.CurrentGame().plugins.empty(); + _lootState.CurrentGame().LoadPlugins(true); //Sort plugins into their load order. list installed; list loadOrder; - g_app_state.CurrentGame().GetLoadOrder(loadOrder); + _lootState.CurrentGame().GetLoadOrder(loadOrder); for (const auto &pluginName : loadOrder) { - const auto pos = g_app_state.CurrentGame().plugins.find(boost::locale::to_lower(pluginName)); + const auto pos = _lootState.CurrentGame().plugins.find(boost::locale::to_lower(pluginName)); - if (pos != g_app_state.CurrentGame().plugins.end()) + if (pos != _lootState.CurrentGame().plugins.end()) installed.push_back(pos->second); } if (isFirstLoad) { //Parse masterlist, don't update it. - if (fs::exists(g_app_state.CurrentGame().MasterlistPath())) { + if (fs::exists(_lootState.CurrentGame().MasterlistPath())) { SendProgressUpdate(frame, loc::translate("Parsing masterlist...")); BOOST_LOG_TRIVIAL(debug) << "Parsing masterlist."; try { - g_app_state.CurrentGame().masterlist.MetadataList::Load(g_app_state.CurrentGame().MasterlistPath()); + _lootState.CurrentGame().masterlist.MetadataList::Load(_lootState.CurrentGame().MasterlistPath()); } catch (exception &e) { - g_app_state.CurrentGame().masterlist.messages.push_back(Message(Message::error, (boost::format(loc::translate("An error occurred while parsing the masterlist: %1%")) % e.what()).str())); + _lootState.CurrentGame().masterlist.messages.push_back(Message(Message::error, (boost::format(loc::translate("An error occurred while parsing the masterlist: %1%")) % e.what()).str())); } } //Parse userlist. - if (fs::exists(g_app_state.CurrentGame().UserlistPath())) { + if (fs::exists(_lootState.CurrentGame().UserlistPath())) { SendProgressUpdate(frame, loc::translate("Parsing userlist...")); BOOST_LOG_TRIVIAL(debug) << "Parsing userlist."; try { - g_app_state.CurrentGame().userlist.Load(g_app_state.CurrentGame().UserlistPath()); + _lootState.CurrentGame().userlist.Load(_lootState.CurrentGame().UserlistPath()); } catch (exception &e) { - g_app_state.CurrentGame().userlist.messages.push_back(Message(Message::error, (boost::format(loc::translate("An error occurred while parsing the userlist: %1%")) % e.what()).str())); + _lootState.CurrentGame().userlist.messages.push_back(Message(Message::error, (boost::format(loc::translate("An error occurred while parsing the userlist: %1%")) % e.what()).str())); } } } @@ -678,12 +678,12 @@ namespace loot { YAML::Node gameNode; // ID the game using its folder value. - gameNode["folder"] = g_app_state.CurrentGame().FolderName(); + gameNode["folder"] = _lootState.CurrentGame().FolderName(); // Store the masterlist revision and date. try { - gameNode["masterlist"]["revision"] = g_app_state.CurrentGame().masterlist.GetRevision(g_app_state.CurrentGame().MasterlistPath(), true); - gameNode["masterlist"]["date"] = g_app_state.CurrentGame().masterlist.GetDate(g_app_state.CurrentGame().MasterlistPath()); + gameNode["masterlist"]["revision"] = _lootState.CurrentGame().masterlist.GetRevision(_lootState.CurrentGame().MasterlistPath(), true); + gameNode["masterlist"]["date"] = _lootState.CurrentGame().masterlist.GetDate(_lootState.CurrentGame().MasterlistPath()); } catch (error &e) { gameNode["masterlist"]["revision"] = e.what(); @@ -701,18 +701,18 @@ namespace loot { // description as part of it. BOOST_LOG_TRIVIAL(trace) << "Getting masterlist metadata for: " << plugin.Name(); Plugin mlistPlugin(plugin); - mlistPlugin.MergeMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(plugin)); + mlistPlugin.MergeMetadata(_lootState.CurrentGame().masterlist.FindPlugin(plugin)); // Now do the same again for any userlist data. BOOST_LOG_TRIVIAL(trace) << "Getting userlist metadata for: " << plugin.Name(); - Plugin ulistPlugin(g_app_state.CurrentGame().userlist.FindPlugin(plugin)); + Plugin ulistPlugin(_lootState.CurrentGame().userlist.FindPlugin(plugin)); pluginNode["__type"] = "Plugin"; // For conversion back into a JS typed object. pluginNode["name"] = plugin.Name(); - pluginNode["isActive"] = g_app_state.CurrentGame().IsActive(plugin.Name()); + pluginNode["isActive"] = _lootState.CurrentGame().IsActive(plugin.Name()); pluginNode["isEmpty"] = plugin.IsEmpty(); pluginNode["isMaster"] = plugin.IsMaster(); - pluginNode["loadsBSA"] = plugin.LoadsBSA(g_app_state.CurrentGame()); + pluginNode["loadsBSA"] = plugin.LoadsBSA(_lootState.CurrentGame()); pluginNode["crc"] = IntToHexString(plugin.Crc()); pluginNode["version"] = plugin.Version(); @@ -759,20 +759,20 @@ namespace loot { SendProgressUpdate(frame, loc::translate("Loading general messages...")); //Set language. unsigned int language; - if (g_app_state.GetSettings()["language"]) - language = Language(g_app_state.GetSettings()["language"].as()).Code(); + if (_lootState.GetSettings()["language"]) + language = Language(_lootState.GetSettings()["language"].as()).Code(); else language = Language::any; BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name(); //Evaluate any conditions in the global messages. BOOST_LOG_TRIVIAL(debug) << "Evaluating global message conditions."; - list messages = g_app_state.CurrentGame().masterlist.messages; - messages.insert(messages.end(), g_app_state.CurrentGame().userlist.messages.begin(), g_app_state.CurrentGame().userlist.messages.end()); + list messages = _lootState.CurrentGame().masterlist.messages; + messages.insert(messages.end(), _lootState.CurrentGame().userlist.messages.begin(), _lootState.CurrentGame().userlist.messages.end()); try { list::iterator it = messages.begin(); while (it != messages.end()) { - if (!it->EvalCondition(g_app_state.CurrentGame(), language)) + if (!it->EvalCondition(_lootState.CurrentGame(), language)) it = messages.erase(it); else ++it; @@ -804,8 +804,8 @@ namespace loot { //Set language. unsigned int language; - if (g_app_state.GetSettings()["language"]) - language = Language(g_app_state.GetSettings()["language"].as()).Code(); + if (_lootState.GetSettings()["language"]) + language = Language(_lootState.GetSettings()["language"].as()).Code(); else language = Language::any; BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name(); @@ -814,14 +814,14 @@ namespace loot { bool wasChanged = true; try { SendProgressUpdate(frame, loc::translate("Updating and parsing masterlist...")); - wasChanged = g_app_state.CurrentGame().masterlist.Load(g_app_state.CurrentGame(), language); + wasChanged = _lootState.CurrentGame().masterlist.Load(_lootState.CurrentGame(), language); } catch (loot::error &e) { if (e.code() == loot::error::ok) { // There was a parsing error, but roll-back was successful, so the process // should still complete. - g_app_state.CurrentGame().masterlist.messages.push_back(Message(Message::error, e.what())); + _lootState.CurrentGame().masterlist.messages.push_back(Message(Message::error, e.what())); wasChanged = true; } else @@ -836,17 +836,17 @@ namespace loot { // Store the masterlist revision and date. try { - gameNode["masterlist"]["revision"] = g_app_state.CurrentGame().masterlist.GetRevision(g_app_state.CurrentGame().MasterlistPath(), true); - gameNode["masterlist"]["date"] = g_app_state.CurrentGame().masterlist.GetDate(g_app_state.CurrentGame().MasterlistPath()); + gameNode["masterlist"]["revision"] = _lootState.CurrentGame().masterlist.GetRevision(_lootState.CurrentGame().MasterlistPath(), true); + gameNode["masterlist"]["date"] = _lootState.CurrentGame().masterlist.GetDate(_lootState.CurrentGame().MasterlistPath()); } catch (error &e) { gameNode["masterlist"]["revision"] = e.what(); gameNode["masterlist"]["date"] = e.what(); } - for (const auto& pluginPair : g_app_state.CurrentGame().plugins) { + for (const auto& pluginPair : _lootState.CurrentGame().plugins) { Plugin mlistPlugin(pluginPair.second); - mlistPlugin.MergeMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(pluginPair.second)); + mlistPlugin.MergeMetadata(_lootState.CurrentGame().masterlist.FindPlugin(pluginPair.second)); YAML::Node pluginNode; if (!mlistPlugin.HasNameOnly()) { @@ -874,11 +874,11 @@ namespace loot { //Evaluate any conditions in the global messages. BOOST_LOG_TRIVIAL(debug) << "Evaluating global message conditions."; - list messages = g_app_state.CurrentGame().masterlist.messages; + list messages = _lootState.CurrentGame().masterlist.messages; try { list::iterator it = messages.begin(); while (it != messages.end()) { - if (!it->EvalCondition(g_app_state.CurrentGame(), language)) + if (!it->EvalCondition(_lootState.CurrentGame(), language)) it = messages.erase(it); else ++it; @@ -911,16 +911,16 @@ namespace loot { BOOST_LOG_TRIVIAL(debug) << "Clearing all user metadata."; // Record which plugins have userlist entries. vector userlistPlugins; - for (const auto &plugin : g_app_state.CurrentGame().userlist.Plugins()) { + for (const auto &plugin : _lootState.CurrentGame().userlist.Plugins()) { userlistPlugins.push_back(plugin.Name()); } BOOST_LOG_TRIVIAL(trace) << "User metadata exists for " << userlistPlugins.size() << " plugins."; // Clear the user metadata. - g_app_state.CurrentGame().userlist.clear(); + _lootState.CurrentGame().userlist.clear(); // Save userlist edits. - g_app_state.CurrentGame().userlist.Save(g_app_state.CurrentGame().UserlistPath()); + _lootState.CurrentGame().userlist.Save(_lootState.CurrentGame().UserlistPath()); // Regenerate the derived metadata (priority, messages, tags and dirty state) // for any plugins with userlist entries. @@ -940,8 +940,8 @@ namespace loot { BOOST_LOG_TRIVIAL(info) << "Beginning sorting operation."; //Set language. unsigned int language; - if (g_app_state.GetSettings()["language"]) - language = Language(g_app_state.GetSettings()["language"].as()).Code(); + if (_lootState.GetSettings()["language"]) + language = Language(_lootState.GetSettings()["language"].as()).Code(); else language = Language::any; BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name(); @@ -949,10 +949,10 @@ namespace loot { try { // Always reload all the plugins. SendProgressUpdate(frame, loc::translate("Loading plugin contents...")); - g_app_state.CurrentGame().LoadPlugins(false); + _lootState.CurrentGame().LoadPlugins(false); //Sort plugins into their load order. - list plugins = g_app_state.CurrentGame().Sort(language, [this, frame](const string& message) { + list plugins = _lootState.CurrentGame().Sort(language, [this, frame](const string& message) { this->SendProgressUpdate(frame, message); }); @@ -973,7 +973,7 @@ namespace loot { node.push_back(pluginNode); } - ++g_app_state.numUnappliedChanges; + ++_lootState.numUnappliedChanges; if (node.size() > 0) callback->Success(JSON::stringify(node)); @@ -989,8 +989,8 @@ namespace loot { YAML::Node Handler::GenerateDerivedMetadata(const Plugin& file, const Plugin& masterlist, const Plugin& userlist) { //Set language. unsigned int language; - if (g_app_state.GetSettings()["language"]) - language = Language(g_app_state.GetSettings()["language"].as()).Code(); + if (_lootState.GetSettings()["language"]) + language = Language(_lootState.GetSettings()["language"].as()).Code(); else language = Language::any; BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name(); @@ -1004,7 +1004,7 @@ namespace loot { //Evaluate any conditions BOOST_LOG_TRIVIAL(trace) << "Evaluate conditions for merged plugin data."; try { - tempPlugin.EvalAllConditions(g_app_state.CurrentGame(), language); + tempPlugin.EvalAllConditions(_lootState.CurrentGame(), language); } catch (std::exception& e) { BOOST_LOG_TRIVIAL(error) << "\"" << tempPlugin.Name() << "\" contains a condition that could not be evaluated. Details: " << e.what(); @@ -1014,7 +1014,7 @@ namespace loot { } //Also check install validity. - bool isDirty = tempPlugin.CheckInstallValidity(g_app_state.CurrentGame()); + bool isDirty = tempPlugin.CheckInstallValidity(_lootState.CurrentGame()); // Now add to pluginNode. YAML::Node pluginNode; @@ -1030,10 +1030,10 @@ namespace loot { YAML::Node Handler::GenerateDerivedMetadata(const std::string& pluginName) { // Now rederive the displayed metadata from the masterlist and userlist. - auto pluginIt = g_app_state.CurrentGame().plugins.find(boost::locale::to_lower(pluginName)); - if (pluginIt != g_app_state.CurrentGame().plugins.end()) { - Plugin master(g_app_state.CurrentGame().masterlist.FindPlugin(pluginIt->second)); - Plugin user(g_app_state.CurrentGame().userlist.FindPlugin(pluginIt->second)); + auto pluginIt = _lootState.CurrentGame().plugins.find(boost::locale::to_lower(pluginName)); + if (pluginIt != _lootState.CurrentGame().plugins.end()) { + Plugin master(_lootState.CurrentGame().masterlist.FindPlugin(pluginIt->second)); + Plugin user(_lootState.CurrentGame().userlist.FindPlugin(pluginIt->second)); return this->GenerateDerivedMetadata(pluginIt->second, master, user); } diff --git a/src/gui/handler.h b/src/gui/handler.h index 34c488d4..8db91504 100644 --- a/src/gui/handler.h +++ b/src/gui/handler.h @@ -25,6 +25,7 @@ #ifndef __LOOT_GUI_HANDLER__ #define __LOOT_GUI_HANDLER__ +#include "loot_state.h" #include "../backend/plugin.h" #include @@ -34,7 +35,7 @@ namespace loot { class Handler : public CefMessageRouterBrowserSide::Handler { public: - Handler(); + Handler(LootState& lootState); // Called due to cefQuery execution in binding.html. virtual bool OnQuery(CefRefPtr browser, @@ -72,6 +73,8 @@ namespace loot { void CopyToClipboard(const std::string& text); void SendProgressUpdate(CefRefPtr frame, const std::string& message); + + LootState& _lootState; private: IMPLEMENT_REFCOUNTING(Handler); }; diff --git a/src/gui/loot_app.cpp b/src/gui/loot_app.cpp index 03909705..e95e7120 100644 --- a/src/gui/loot_app.cpp +++ b/src/gui/loot_app.cpp @@ -23,7 +23,6 @@ */ #include "loot_app.h" -#include "loot_state.h" #include "loot_handler.h" #include "scheme.h" @@ -86,7 +85,7 @@ namespace loot { #endif // Set the handler for browser-level callbacks. - CefRefPtr handler(new LootHandler()); + CefRefPtr handler(new LootHandler(lootState)); // Register the custom "loot" scheme handlers. CefRegisterSchemeHandlerFactory("loot", "l10n", new LootSchemeHandlerFactory()); @@ -97,7 +96,7 @@ namespace loot { // Need to set the global locale for this process so that messages will // be translated. BOOST_LOG_TRIVIAL(debug) << "Initialising language settings in UI thread."; - const YAML::Node& settings = g_app_state.GetSettings(); + const YAML::Node& settings = lootState.GetSettings(); if (settings["language"] && settings["language"].as() != Language(Language::english).Locale()) { boost::locale::generator gen; gen.add_messages_path(g_path_l10n.string()); diff --git a/src/gui/loot_app.h b/src/gui/loot_app.h index c2e0c695..b98f2c37 100644 --- a/src/gui/loot_app.h +++ b/src/gui/loot_app.h @@ -25,6 +25,8 @@ #ifndef __LOOT_GUI_LOOT_APP__ #define __LOOT_GUI_LOOT_APP__ +#include "loot_state.h" + #include #include #include @@ -51,6 +53,8 @@ namespace loot { virtual bool OnProcessMessageReceived(CefRefPtr browser, CefProcessId source_process, CefRefPtr message) OVERRIDE; + + LootState lootState; private: CefRefPtr message_router_; diff --git a/src/gui/loot_handler.cpp b/src/gui/loot_handler.cpp index a69df9f3..6ff0d099 100644 --- a/src/gui/loot_handler.cpp +++ b/src/gui/loot_handler.cpp @@ -26,7 +26,6 @@ #include "handler.h" #include "resource.h" #include "loot_app.h" -#include "loot_state.h" #include "../backend/error.h" #include "../backend/globals.h" @@ -56,7 +55,7 @@ namespace fs = boost::filesystem; namespace loc = boost::locale; namespace loot { - LootHandler::LootHandler() : is_closing_(false) {} + LootHandler::LootHandler(LootState& lootState) : is_closing_(false), _lootState(lootState) {} // CefClient methods //------------------ @@ -98,7 +97,7 @@ namespace loot { #endif // Set window size & position. - YAML::Node settings = g_app_state.GetSettings(); + YAML::Node settings = _lootState.GetSettings(); if (settings["window"]["left"] && settings["window"]["top"] && settings["window"]["right"] && settings["window"]["bottom"]) { #ifdef _WIN32 @@ -148,14 +147,14 @@ namespace loot { CefMessageRouterConfig config; browser_side_router_ = CefMessageRouterBrowserSide::Create(config); - browser_side_router_->AddHandler(new Handler(), false); + browser_side_router_->AddHandler(new Handler(_lootState), false); } bool LootHandler::DoClose(CefRefPtr browser) { assert(CefCurrentlyOn(TID_UI)); // Check if unapplied changes exist. - if (g_app_state.numUnappliedChanges > 0) { + if (_lootState.numUnappliedChanges > 0) { browser->GetMainFrame()->ExecuteJavaScript("onQuit();", browser->GetMainFrame()->GetURL(), 0); return true; } @@ -177,7 +176,7 @@ namespace loot { assert(CefCurrentlyOn(TID_UI)); // Save window size & position. - YAML::Node settings = g_app_state.GetSettings(); + YAML::Node settings = _lootState.GetSettings(); #ifdef _WIN32 RECT rc; @@ -189,8 +188,8 @@ namespace loot { settings["window"]["bottom"] = rc.bottom; #endif - g_app_state.UpdateSettings(settings); - g_app_state.SaveSettings(); + _lootState.UpdateSettings(settings); + _lootState.SaveSettings(); // Cancel any javascript callbacks. browser_side_router_->OnBeforeClose(browser); diff --git a/src/gui/loot_handler.h b/src/gui/loot_handler.h index f12b4fbc..872a9b66 100644 --- a/src/gui/loot_handler.h +++ b/src/gui/loot_handler.h @@ -25,6 +25,8 @@ #ifndef __LOOT_GUI_LOOT_HANDLER__ #define __LOOT_GUI_LOOT_HANDLER__ +#include "loot_state.h" + #include #include @@ -37,7 +39,7 @@ namespace loot { public CefLoadHandler, public CefRequestHandler { public: - LootHandler(); + LootHandler(LootState& lootState); // CefClient methods //------------------ @@ -80,6 +82,8 @@ namespace loot { bool IsClosing() const { return is_closing_; } + LootState& _lootState; + private: // List of existing browser windows. Only accessed on the CEF UI thread. typedef std::list > BrowserList; diff --git a/src/gui/loot_state.cpp b/src/gui/loot_state.cpp index 535d1e54..3c9c3e7d 100644 --- a/src/gui/loot_state.cpp +++ b/src/gui/loot_state.cpp @@ -46,8 +46,6 @@ using boost::format; namespace fs = boost::filesystem; namespace loot { - LootState g_app_state = LootState(); - LootState::LootState() : numUnappliedChanges(0), _currentGame(_games.end()) {} void LootState::Init(const std::string& cmdLineGame) { diff --git a/src/gui/loot_state.h b/src/gui/loot_state.h index 3ba50c20..75701f73 100644 --- a/src/gui/loot_state.h +++ b/src/gui/loot_state.h @@ -69,8 +69,6 @@ namespace loot { base::Lock _lock; IMPLEMENT_REFCOUNTING(LootState); }; - - extern LootState g_app_state; } #endif diff --git a/src/gui/main_win.cpp b/src/gui/main_win.cpp index 84520e66..2aba1f13 100644 --- a/src/gui/main_win.cpp +++ b/src/gui/main_win.cpp @@ -115,7 +115,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmd gameStr = command_line->GetSwitchValue("game"); } - loot::g_app_state.Init(gameStr); + app.get()->lootState.Init(gameStr); // Back to CEF //------------