From eccf38b98751a24204e833e88a98930525913bd6 Mon Sep 17 00:00:00 2001 From: WrinklyNinja Date: Thu, 1 Aug 2013 12:30:30 +0100 Subject: [PATCH] Added possibility of early exit to masterlist updating. The parsing test also has its output recorded so that if there aren't any issues, it doesn't need to be repeated later. --- src/backend/network.cpp | 22 +++++++++++++++++----- src/backend/network.h | 3 ++- src/gui/main.cpp | 24 ++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/backend/network.cpp b/src/backend/network.cpp index cb9e8e3a..a0480ad3 100644 --- a/src/backend/network.cpp +++ b/src/backend/network.cpp @@ -193,7 +193,7 @@ namespace boss { throw boss::error(boss::error::git_error, error_message); } - std::string UpdateMasterlist(Game& game, std::vector& parsingErrors) { + std::string UpdateMasterlist(Game& game, std::vector& parsingErrors, std::list& plugins, std::list& messages) { //First need to decide how the masterlist is updated: using Git or Subversion? //Look at the update URL to decide. @@ -268,16 +268,19 @@ namespace boss { } BOOST_LOG_TRIVIAL(trace) << "Reading the masterlist version from the svn info output."; - revision = GetRevision(output); + std::string newRevision = GetRevision(output); + + //Check if revision has changed. If it hasn't, exit early. + if (newRevision == revision) + return revision; + else + revision = newRevision; try { //Now test masterlist to see if it parses OK. BOOST_LOG_TRIVIAL(trace) << "Testing the new masterlist to see if it parses OK."; YAML::Node mlist = YAML::LoadFile(game.MasterlistPath().string()); - list messages; - list plugins; - if (mlist["globals"]) messages = mlist["globals"].as< list >(); if (mlist["plugins"]) @@ -446,6 +449,10 @@ namespace boss { BOOST_LOG_TRIVIAL(info) << "Received " << stats->indexed_objects << " of " << stats->total_objects << " objects in " << stats->received_bytes << " bytes."; + bool exitEarly = false; + if (stats->received_bytes == 0) //No update received. + exitEarly = true; + // Disconnect from the remote repository. BOOST_LOG_TRIVIAL(trace) << "Disconnecting from remote."; @@ -508,6 +515,11 @@ namespace boss { git_object_free(ptrs.obj); + if (exitEarly) { + ptrs.free(); + return string(revision); + } + BOOST_LOG_TRIVIAL(trace) << "Testing masterlist parsing."; //Now try parsing the masterlist. diff --git a/src/backend/network.h b/src/backend/network.h index 34d71fbc..ae1d46d2 100644 --- a/src/backend/network.h +++ b/src/backend/network.h @@ -28,6 +28,7 @@ #include #include "game.h" +#include "metadata.h" namespace boss { @@ -62,6 +63,6 @@ namespace boss { So when using Git, the Game::URL() function would return the path to the repository, and BOSS would expect that the masterlist be in the root directory of the repository, which is not unreasonable. */ - std::string UpdateMasterlist(Game& game, std::vector& parsingErrors); + std::string UpdateMasterlist(Game& game, std::vector& parsingErrors, std::list& plugins, std::list& messages); } #endif diff --git a/src/gui/main.cpp b/src/gui/main.cpp index a65e7940..a704bec1 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -408,13 +408,33 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { wxProgressDialog *progDia = new wxProgressDialog(translate("BOSS: Working..."),translate("BOSS working..."), 1000, this, wxPD_APP_MODAL|wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME); + /* MULTITHREADING + + The following things are quite slow: + + * Masterlist updating (need to fetch over network, parse masterlist possibly several times) + * Masterlist parsing (at least when it's big). + * Large plugin loading. + + As such, the following items will each have a separate thread: + + * Each plugin which has a size greater than the mean plugin size. + * All the plugins with sizes less than or equal to the mean plugin size. + * Masterlist updating. + + Userlist parsing could also get its own thread, but userlists are generally quite small so it probably isn't worth it. + + */ + BOOST_LOG_TRIVIAL(trace) << "Updating masterlist"; vector parsingErrors; string revision; try { - revision = UpdateMasterlist(_game, parsingErrors); + revision = UpdateMasterlist(_game, parsingErrors, mlist_plugins, mlist_messages); } catch (boss::error& e) { + mlist_plugins.clear(); + mlist_messages.clear(); BOOST_LOG_TRIVIAL(error) << "Masterlist update failed. Details: " << e.what(); messages.push_back(boss::Message(boss::g_message_error, (format(loc::translate("Masterlist update failed. Details: %1%")) % e.what()).str())); } @@ -445,7 +465,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { group.create_thread(pll); group.join_all(); - if (fs::exists(_game.MasterlistPath())) { + if (mlist_plugins.empty() && mlist_messages.empty() && fs::exists(_game.MasterlistPath())) { BOOST_LOG_TRIVIAL(trace) << "Parsing masterlist..."; try {