diff --git a/src/backend/game/game_cache.cpp b/src/backend/game/game_cache.cpp index f662984d..9dd71763 100644 --- a/src/backend/game/game_cache.cpp +++ b/src/backend/game/game_cache.cpp @@ -39,13 +39,15 @@ namespace fs = boost::filesystem; namespace lc = boost::locale; namespace loot { - GameCache::GameCache() {} + GameCache::GameCache() : isLoadOrderSorted(false) {} + GameCache::GameCache(const GameCache& cache) : masterlist(cache.masterlist), userlist(cache.userlist), conditionCache(cache.conditionCache), plugins(cache.plugins), - messages(cache.messages) {} + messages(cache.messages), + isLoadOrderSorted(cache.isLoadOrderSorted) {} GameCache& GameCache::operator=(const GameCache& cache) { if (&cache != this) { @@ -54,6 +56,7 @@ namespace loot { conditionCache = cache.conditionCache; plugins = cache.plugins; messages = cache.messages; + isLoadOrderSorted = cache.isLoadOrderSorted; } return *this; @@ -111,7 +114,11 @@ namespace loot { } std::vector GameCache::GetMessages() const { - return messages; + vector output(messages); + if (!isLoadOrderSorted) + output.push_back(Message(Message::warn, "You have not sorted your load order this session.")); + + return output; } void GameCache::AppendMessage(const Message& message) { @@ -120,6 +127,10 @@ namespace loot { messages.push_back(message); } + void GameCache::SetLoadOrderSorted(bool isLoadOrderSorted) { + this->isLoadOrderSorted = isLoadOrderSorted; + } + void GameCache::ClearCachedConditions() { std::lock_guard guard(mutex); diff --git a/src/backend/game/game_cache.h b/src/backend/game/game_cache.h index 00823f99..36911366 100644 --- a/src/backend/game/game_cache.h +++ b/src/backend/game/game_cache.h @@ -55,6 +55,8 @@ namespace loot { std::vector GetMessages() const; void AppendMessage(const Message& message); + void SetLoadOrderSorted(bool isLoadOrderSorted); + void ClearCachedConditions(); void ClearCachedPlugins(); void ClearMessages(); @@ -64,6 +66,7 @@ namespace loot { std::unordered_map conditionCache; std::unordered_map plugins; std::vector messages; + bool isLoadOrderSorted; mutable std::mutex mutex; }; diff --git a/src/backend/plugin_sorter.cpp b/src/backend/plugin_sorter.cpp index ce525d29..2aa4beac 100644 --- a/src/backend/plugin_sorter.cpp +++ b/src/backend/plugin_sorter.cpp @@ -156,6 +156,7 @@ namespace loot { // Clear any existing game-specific messages, as these only relate to // state that has been changed by sorting. game.ClearMessages(); + game.SetLoadOrderSorted(true); return plugins; } diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index 33a99982..628691da 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -161,7 +161,10 @@ namespace loot { } else if (request == "cancelSort") { _lootState.decrementUnappliedChangeCounter(); - callback->Success(""); + _lootState.CurrentGame().SetLoadOrderSorted(false); + + YAML::Node node(GetGeneralMessages()); + callback->Success(JSON::stringify(node)); return true; } else if (request == "editorOpened") { diff --git a/src/gui/html/js/events.js b/src/gui/html/js/events.js index 7a044c41..3f81f923 100644 --- a/src/gui/html/js/events.js +++ b/src/gui/html/js/events.js @@ -102,13 +102,14 @@ function onSortPlugins() { if (!result) { return; } + + loot.game.globalMessages = result.globalMessages; + /* Check if sorted load order differs from current load order. */ const loadOrderIsUnchanged = result.plugins.every((plugin, index) => { return plugin.name === loot.game.plugins[index].name; }); if (loadOrderIsUnchanged) { - loot.game.globalMessages = result.globalMessages; - result.plugins.forEach((plugin) => { const existingPlugin = loot.game.plugins.find((item) => { return item.name === plugin.name; @@ -177,13 +178,16 @@ function onApplySort() { }).catch(handlePromiseError); } function onCancelSort() { - return loot.query('cancelSort').then(() => { + return loot.query('cancelSort').then(JSON.parse).then((messages) => { /* Sort UI elements again according to stored old load order. */ loot.game.plugins = loot.game.oldLoadOrder; filterPluginData(loot.game.plugins, loot.filters); delete loot.game.loadOrder; delete loot.game.oldLoadOrder; + /* Update general messages */ + loot.game.globalMessages = messages; + /* Now show the masterlist update buttons, and hide the accept and cancel sort buttons. */ loot.dom.show('updateMasterlistButton'); diff --git a/src/tests/backend/game/test_game_cache.h b/src/tests/backend/game/test_game_cache.h index f2c3f16c..6a6f734d 100644 --- a/src/tests/backend/game/test_game_cache.h +++ b/src/tests/backend/game/test_game_cache.h @@ -45,6 +45,7 @@ namespace loot { cache.AddPlugin(loot::Plugin(game, "Blank.esm", true)); Message expectedMessage(Message::say, "1"); cache.AppendMessage(expectedMessage); + cache.SetLoadOrderSorted(true); loot::GameCache otherCache(cache); EXPECT_EQ(std::make_pair(true, true), otherCache.GetCachedCondition("true Condition")); @@ -62,6 +63,7 @@ namespace loot { cache.AddPlugin(loot::Plugin(game, "Blank.esm", true)); Message expectedMessage(Message::say, "1"); cache.AppendMessage(expectedMessage); + cache.SetLoadOrderSorted(true); loot::GameCache otherCache = cache; EXPECT_EQ(std::make_pair(true, true), otherCache.GetCachedCondition("true Condition")); @@ -165,8 +167,22 @@ namespace loot { EXPECT_TRUE(cache.GetPlugins().empty()); } - TEST_F(GameCache, noMessagesShouldBeStoredByDefault) { - EXPECT_TRUE(cache.GetMessages().empty()); + TEST_F(GameCache, aMessageShouldBeCachedByDefault) { + ASSERT_EQ(1, cache.GetMessages().size()); + } + + TEST_F(GameCache, settingLoadOrderSortedToTrueShouldSupressDefaultCachedMessage) { + cache.SetLoadOrderSorted(true); + + ASSERT_TRUE(cache.GetMessages().empty()); + } + + TEST_F(GameCache, settingLoadOrderSortedToFalseShouldReverseTheDefaultCachedMessageSuppression) { + auto expectedMessages = cache.GetMessages(); + cache.SetLoadOrderSorted(true); + cache.SetLoadOrderSorted(false); + + ASSERT_EQ(expectedMessages, cache.GetMessages()); } TEST_F(GameCache, appendingMessagesShouldStoreThemInTheGivenOrder) { @@ -177,10 +193,12 @@ namespace loot { for (const auto& message : messages) cache.AppendMessage(message); - EXPECT_EQ(messages, cache.GetMessages()); + ASSERT_EQ(3, cache.GetMessages().size()); + EXPECT_EQ(messages[0], cache.GetMessages()[0]); + EXPECT_EQ(messages[1], cache.GetMessages()[1]); } - TEST_F(GameCache, clearingMessagesShouldRemoveAllStoredMessages) { + TEST_F(GameCache, clearingMessagesShouldRemoveAllAppendedMessages) { std::vector messages({ Message(Message::say, "1"), Message(Message::error, "2"), @@ -188,9 +206,11 @@ namespace loot { for (const auto& message : messages) cache.AppendMessage(message); + auto previousSize = cache.GetMessages().size(); + cache.ClearMessages(); - EXPECT_TRUE(cache.GetMessages().empty()); + EXPECT_EQ(previousSize - messages.size(), cache.GetMessages().size()); } } }