Add load order state management

(Re)load the current state when loading plugins, and add an API function for managing load order state so that clients have full control over when libloadorder reloads its cached state.
This commit is contained in:
Oliver Hamlet
2017-10-08 15:49:39 +01:00
parent ef60b334e3
commit 89839fdc74
10 changed files with 59 additions and 1 deletions
+11 -1
View File
@@ -63,7 +63,7 @@ public:
/**
* @brief Parses plugins and loads their data.
* @details Any previously-loaded plugin data is discarded when this function
* is called.
* is called. This function also loads the current load order state.
* @param plugins
* The filenames of the plugins to load.
* @param loadHeadersOnly
@@ -127,6 +127,16 @@ public:
* @{
*/
/**
*
* @brief Load the current load order state, discarding any previously held
* state.
* @details This function should be called whenever the load order or active
* state of plugins "on disk" changes, so that the cached state is
* updated to reflect the changes.
*/
virtual void LoadCurrentLoadOrderState() = 0;
/**
* @brief Check if a plugin is active.
* @param plugin
+5
View File
@@ -140,6 +140,7 @@ void Game::LoadPlugins(const std::vector<std::string>& plugins, bool loadHeaders
// Clear the existing plugin cache.
cache_->ClearCachedPlugins();
loadOrderHandler_->LoadCurrentState();
// Load the plugins.
BOOST_LOG_TRIVIAL(trace) << "Starting plugin loading.";
@@ -191,6 +192,10 @@ std::vector<std::string> Game::SortPlugins(const std::vector<std::string>& plugi
return sorter.Sort(*this);
}
void Game::LoadCurrentLoadOrderState() {
loadOrderHandler_->LoadCurrentState();
}
bool Game::IsPluginActive(const std::string& plugin) const {
try {
return std::static_pointer_cast<const Plugin>(GetPlugin(plugin))->IsActive();
+2
View File
@@ -66,6 +66,8 @@ public:
std::vector<std::string> SortPlugins(const std::vector<std::string>& plugins);
void LoadCurrentLoadOrderState();
bool IsPluginActive(const std::string& pluginName) const;
std::vector<std::string> GetLoadOrder() const;
+8
View File
@@ -77,6 +77,14 @@ void LoadOrderHandler::Init(const GameType& gameType,
HandleError("create a game handle", ret);
}
void LoadOrderHandler::LoadCurrentState() {
BOOST_LOG_TRIVIAL(debug) << "Loading the current load order state.";
unsigned int ret = lo_load_current_state(gh_);
HandleError("load the current load order state", ret);
}
bool LoadOrderHandler::IsPluginActive(const std::string& pluginName) const {
BOOST_LOG_TRIVIAL(debug) << "Checking if plugin \"" << pluginName << "\" is active.";
+2
View File
@@ -44,6 +44,8 @@ public:
const boost::filesystem::path& gamePath,
const boost::filesystem::path& gameLocalAppData = "");
void LoadCurrentState();
std::vector<std::string> GetLoadOrder() const;
bool IsPluginActive(const std::string& pluginName) const;
@@ -158,18 +158,22 @@ TEST_P(GameInterfaceTest, sortPluginsShouldSucceedIfPassedValidArguments) {
}
TEST_P(GameInterfaceTest, isPluginActiveShouldReturnFalseIfTheGivenPluginIsNotActive) {
handle_->LoadCurrentLoadOrderState();
EXPECT_TRUE(handle_->IsPluginActive(blankEsm));
}
TEST_P(GameInterfaceTest, isPluginActiveShouldReturnTrueIfTheGivenPluginIsActive) {
handle_->LoadCurrentLoadOrderState();
EXPECT_FALSE(handle_->IsPluginActive(blankEsp));
}
TEST_P(GameInterfaceTest, getLoadOrderShouldReturnTheCurrentLoadOrder) {
handle_->LoadCurrentLoadOrderState();
ASSERT_EQ(getLoadOrder(), handle_->GetLoadOrder());
}
TEST_P(GameInterfaceTest, setLoadOrderShouldSetTheLoadOrder) {
handle_->LoadCurrentLoadOrderState();
std::vector<std::string> loadOrder({
masterFile,
blankEsm,
+6
View File
@@ -145,18 +145,21 @@ TEST_P(GameTest, loadPluginsWithHeadersOnlyFalseShouldFullyLoadAllInstalledPlugi
TEST_P(GameTest, shouldShowBlankEsmAsActiveIfItHasNotBeenLoaded) {
Game game = Game(GetParam(), dataPath.parent_path(), localPath);
game.LoadCurrentLoadOrderState();
EXPECT_TRUE(game.IsPluginActive(blankEsm));
}
TEST_P(GameTest, shouldShowBlankEspAsInactiveIfItHasNotBeenLoaded) {
Game game = Game(GetParam(), dataPath.parent_path(), localPath);
game.LoadCurrentLoadOrderState();
EXPECT_FALSE(game.IsPluginActive(blankEsp));
}
TEST_P(GameTest, shouldShowBlankEsmAsActiveIfItsHeaderHasBeenLoaded) {
Game game = Game(GetParam(), dataPath.parent_path(), localPath);
game.LoadCurrentLoadOrderState();
ASSERT_NO_THROW(loadInstalledPlugins(game, true));
@@ -165,6 +168,7 @@ TEST_P(GameTest, shouldShowBlankEsmAsActiveIfItsHeaderHasBeenLoaded) {
TEST_P(GameTest, shouldShowBlankEspAsInactiveIfItsHeaderHasBeenLoaded) {
Game game = Game(GetParam(), dataPath.parent_path(), localPath);
game.LoadCurrentLoadOrderState();
ASSERT_NO_THROW(loadInstalledPlugins(game, true));
@@ -173,6 +177,7 @@ TEST_P(GameTest, shouldShowBlankEspAsInactiveIfItsHeaderHasBeenLoaded) {
TEST_P(GameTest, shouldShowBlankEsmAsActiveIfItHasBeenFullyLoaded) {
Game game = Game(GetParam(), dataPath.parent_path(), localPath);
game.LoadCurrentLoadOrderState();
ASSERT_NO_THROW(loadInstalledPlugins(game, false));
@@ -181,6 +186,7 @@ TEST_P(GameTest, shouldShowBlankEsmAsActiveIfItHasBeenFullyLoaded) {
TEST_P(GameTest, shouldShowBlankEspAsInactiveIfItHasBeenFullyLoaded) {
Game game = Game(GetParam(), dataPath.parent_path(), localPath);
game.LoadCurrentLoadOrderState();
ASSERT_NO_THROW(loadInstalledPlugins(game, false));
@@ -92,8 +92,17 @@ TEST_P(LoadOrderHandlerTest, isPluginActiveShouldThrowIfTheHandlerHasNotBeenInit
EXPECT_THROW(loadOrderHandler_.IsPluginActive(masterFile), std::system_error);
}
TEST_P(LoadOrderHandlerTest, isPluginActiveShouldReturnFalseIfLoadOrderStateHasNotBeenLoaded) {
initialiseHandler();
EXPECT_FALSE(loadOrderHandler_.IsPluginActive(masterFile));
EXPECT_FALSE(loadOrderHandler_.IsPluginActive(blankEsm));
EXPECT_FALSE(loadOrderHandler_.IsPluginActive(blankEsp));
}
TEST_P(LoadOrderHandlerTest, isPluginActiveShouldReturnCorrectPluginStatesAfterInitialisation) {
initialiseHandler();
loadOrderHandler_.LoadCurrentState();
EXPECT_TRUE(loadOrderHandler_.IsPluginActive(masterFile));
EXPECT_TRUE(loadOrderHandler_.IsPluginActive(blankEsm));
@@ -104,8 +113,15 @@ TEST_P(LoadOrderHandlerTest, getLoadOrderShouldThrowIfTheHandlerHasNotBeenInitia
EXPECT_THROW(loadOrderHandler_.GetLoadOrder(), std::system_error);
}
TEST_P(LoadOrderHandlerTest, getLoadOrderShouldReturnAnEmptyVectorIfStateHasNotBeenLoaded) {
initialiseHandler();
EXPECT_TRUE(loadOrderHandler_.GetLoadOrder().empty());
}
TEST_P(LoadOrderHandlerTest, getLoadOrderShouldReturnTheCurrentLoadOrder) {
initialiseHandler();
loadOrderHandler_.LoadCurrentState();
ASSERT_EQ(getLoadOrder(), loadOrderHandler_.GetLoadOrder());
}
@@ -116,6 +132,7 @@ TEST_P(LoadOrderHandlerTest, setLoadOrderShouldThrowIfTheHandlerHasNotBeenInitia
TEST_P(LoadOrderHandlerTest, setLoadOrderShouldSetTheLoadOrder) {
initialiseHandler();
loadOrderHandler_.LoadCurrentState();
EXPECT_NO_THROW(loadOrderHandler_.SetLoadOrder(loadOrderToSet_));
@@ -45,6 +45,8 @@ protected:
inline void SetUp() {
CommonGameTestFixture::SetUp();
game_.LoadCurrentLoadOrderState();
// Write out an empty resource file.
ASSERT_NO_THROW(boost::filesystem::create_directories(resourcePath.parent_path()));
boost::filesystem::ofstream out(resourcePath);
@@ -44,6 +44,8 @@ protected:
void SetUp() {
CommonGameTestFixture::SetUp();
game_.LoadCurrentLoadOrderState();
// Write out an empty file.
boost::filesystem::ofstream out(dataPath / emptyFile);
out.close();