From 63122f7cc871815379b9feb68e54221b8ba24795 Mon Sep 17 00:00:00 2001 From: MrD Date: Sat, 27 Jun 2015 21:55:54 +0200 Subject: [PATCH] [7.4.0]lo_set_load_order no more adds additional plugins + performance: When client requests a load order to be set we must set this - related to #6: if the client's definition of invalid (in Bash 'corrupted') plugin differs from liblo's, liblo will keep adding to the load order what client will keep removing. Once #6 is closed consider adding the commented out warn. Performance monkey patch (_skip parameter) - Load performs all the tests CheckValidity would reperform for timestamp load orders - ofc real solution is a cache (#3). --- src/api/libloadorder.cpp | 8 +++--- src/api/loadorder.cpp | 20 ++++++++++---- src/backend/plugins.cpp | 57 +++++++++++++++++++++------------------- src/backend/plugins.h | 4 +-- 4 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/api/libloadorder.cpp b/src/api/libloadorder.cpp index 4ef06a1..6c91478 100644 --- a/src/api/libloadorder.cpp +++ b/src/api/libloadorder.cpp @@ -38,8 +38,8 @@ using namespace liblo; ------------------------------*/ const unsigned int LIBLO_VERSION_MAJOR = 7; -const unsigned int LIBLO_VERSION_MINOR = 3; -const unsigned int LIBLO_VERSION_PATCH = 1; +const unsigned int LIBLO_VERSION_MINOR = 4; +const unsigned int LIBLO_VERSION_PATCH = 0; /* Returns whether this version of libloadorder is compatible with the given version of libloadorder. */ @@ -151,8 +151,8 @@ LIBLO unsigned int lo_create_handle(lo_game_handle * const gh, } try { - LoadOrderFileLO.CheckValidity(**gh); - PluginsFileLO.CheckValidity(**gh); + LoadOrderFileLO.CheckValidity(**gh, false); + PluginsFileLO.CheckValidity(**gh, false); } catch (error& e) { return c_error(e); diff --git a/src/api/loadorder.cpp b/src/api/loadorder.cpp index ebf9228..387cd3c 100644 --- a/src/api/loadorder.cpp +++ b/src/api/loadorder.cpp @@ -62,7 +62,7 @@ LIBLO unsigned int lo_get_load_order(lo_game_handle gh, char *** const plugins, if (gh->loadOrder.HasChanged(*gh)) { gh->loadOrder.Load(*gh); try { - gh->loadOrder.CheckValidity(*gh); // FIXME: repeats existence/validity/master checks !!! + gh->loadOrder.CheckValidity(*gh, true); } catch (error& e) { successRetCode = c_error(e); @@ -118,7 +118,7 @@ LIBLO unsigned int lo_set_load_order(lo_game_handle gh, const char * const * con //Check to see if basic rules are being obeyed. try { - gh->loadOrder.CheckValidity(*gh); + gh->loadOrder.CheckValidity(*gh, false); } catch (error& e) { gh->loadOrder.clear(); @@ -126,16 +126,26 @@ LIBLO unsigned int lo_set_load_order(lo_game_handle gh, const char * const * con } //Now add any additional plugins to the load order. - gh->loadOrder.LoadAdditionalFiles(*gh); + unsigned int successRetCode = LIBLO_OK; + //unordered_set added = gh->loadOrder.LoadAdditionalFiles(*gh); + //if (!added.empty()) { + // std::stringstream ss; + // std::for_each( + // added.cbegin(), + // added.cend(), + // [&ss](const Plugin c) {ss << c.Name() << " "; } + // ); + // successRetCode = c_error(LIBLO_WARN_INVALID_LIST, + // "lo_set_load_order: the list you passed in does not contain the following plugins: " + ss.str()); + //} //Now save changes. try { gh->loadOrder.Save(*gh); + return successRetCode; } catch (error& e) { gh->loadOrder.clear(); return c_error(e); } - - return LIBLO_OK; } diff --git a/src/backend/plugins.cpp b/src/backend/plugins.cpp index 8ec47ba..450fda2 100644 --- a/src/backend/plugins.cpp +++ b/src/backend/plugins.cpp @@ -347,7 +347,7 @@ namespace liblo { } } - void LoadOrder::CheckValidity(const _lo_game_handle_int& parentGame) { + void LoadOrder::CheckValidity(const _lo_game_handle_int& parentGame, bool _skip) { if (empty()) return; @@ -357,29 +357,32 @@ namespace liblo { if (at(0) != masterEsm) msg += "\"" + masterEsm.Name() + "\" is not the first plugin in the load order. " + at(0).Name() + " is first.\n"; - - bool wasMaster = false; - bool wasMasterSet = false; - unordered_set hashset; // check for duplicates - for (const auto plugin : *this) { - if (hashset.find(plugin) != hashset.end()) { - msg += "\"" + plugin.Name() + "\" is in the load order twice.\n"; - if (plugin.exists()) wasMaster = plugin.esm(); - continue; - } else hashset.insert(plugin); - if (!plugin.Exists(parentGame)){ - msg += "\"" + plugin.Name() + "\" is not installed.\n"; - continue; - } - // plugin exists - bool isMaster = wasMaster; - try { - isMaster = plugin.IsMasterFile(parentGame); - if (wasMasterSet && isMaster && !wasMaster) - msg += "Master plugin \"" + plugin.Name() + "\" loaded after a non-master plugin.\n"; - wasMaster = isMaster; wasMasterSet = true; - } catch (std::exception& e) { - msg += "Plugin \"" + plugin.Name() + "\" is invalid - details: " + e.what() + "\n"; + if (parentGame.LoadOrderMethod() != LIBLO_METHOD_TIMESTAMP || !_skip) { // we just loaded, performing all operations below on loading + bool wasMaster = false; + bool wasMasterSet = false; + unordered_set hashset; // check for duplicates + for (const auto plugin : *this) { + if (hashset.find(plugin) != hashset.end()) { + msg += "\"" + plugin.Name() + "\" is in the load order twice.\n"; + if (plugin.exists()) wasMaster = plugin.esm(); + continue; + } + else hashset.insert(plugin); + if (!plugin.Exists(parentGame)){ + msg += "\"" + plugin.Name() + "\" is not installed.\n"; + continue; + } + // plugin exists + bool isMaster = wasMaster; + try { + isMaster = plugin.IsMasterFile(parentGame); + if (wasMasterSet && isMaster && !wasMaster) + msg += "Master plugin \"" + plugin.Name() + "\" loaded after a non-master plugin.\n"; + wasMaster = isMaster; wasMasterSet = true; + } + catch (std::exception& e) { + msg += "Plugin \"" + plugin.Name() + "\" is invalid - details: " + e.what() + "\n"; + } } } if (msg != "") throw error(LIBLO_WARN_INVALID_LIST, msg); @@ -499,8 +502,8 @@ namespace liblo { } } - bool LoadOrder::LoadAdditionalFiles(const _lo_game_handle_int& parentGame) { - bool added = false; + unordered_set LoadOrder::LoadAdditionalFiles(const _lo_game_handle_int& parentGame) { + unordered_set added; if (fs::is_directory(parentGame.PluginsFolder())) { //Now scan through Data folder. Add any plugins that aren't already in loadorder //to loadorder, at the end. // FIXME: TIMESTAMPS METHOD !WHY AT THE END ? @@ -532,7 +535,7 @@ namespace liblo { this->push_back(plugin); firstNonMaster = this->begin() + firstNonMasterPos + 1; } - added = true; + added.insert(plugin); } catch (std::exception& /*e*/) { // LOG ! msg += "Plugin \"" + plugin.Name() + "\" is invalid - details: " + e.what() + "\n"; diff --git a/src/backend/plugins.h b/src/backend/plugins.h index f345c2f..204ee8d 100644 --- a/src/backend/plugins.h +++ b/src/backend/plugins.h @@ -71,7 +71,7 @@ namespace liblo { void Load(const _lo_game_handle_int& parentGame); void Save(_lo_game_handle_int& parentGame); //Also updates mtime and active plugins list. - void CheckValidity(const _lo_game_handle_int& parentGame); //Game master first, plugins all exist. + void CheckValidity(const _lo_game_handle_int& parentGame, bool _skip); //Game master first, plugins all exist. bool HasChanged(const _lo_game_handle_int& parentGame) const; //Checks timestamp and also if LoadOrder is empty. @@ -80,7 +80,7 @@ namespace liblo { std::vector::iterator Find(const Plugin& plugin); std::vector::iterator FindFirstNonMaster(const _lo_game_handle_int& parentGame); - bool LoadAdditionalFiles(const _lo_game_handle_int& parentGame); // HACK, scan plugins dir and load files not in parentGame.loadOrder + std::unordered_set LoadAdditionalFiles(const _lo_game_handle_int& parentGame); // HACK, scan plugins dir and load files not in parentGame.loadOrder //Assumes that the content of the file is valid. void LoadFromFile(const _lo_game_handle_int& parentGame, const boost::filesystem::path& file);