Warn if load order has not been sorted since opening LOOT.

The warning is removed when the load order is sorted, but
reinstated if sorting is cancelled. Closes #528.

Note that if sorting is applied, then changes made so that
another sort produces a new load order and this is cancelled,
the message is not reinstated again, as its purposes is to remind
users that simply launching LOOT is not enough, and not to tell
them when another sort may be required.
This commit is contained in:
Oliver Hamlet
2016-01-30 13:25:42 +00:00
parent b1999822b1
commit 4d1b06e6c7
6 changed files with 54 additions and 12 deletions
+14 -3
View File
@@ -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<Message> GameCache::GetMessages() const {
return messages;
vector<Message> 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<std::mutex> guard(mutex);
+3
View File
@@ -55,6 +55,8 @@ namespace loot {
std::vector<Message> 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<std::string, bool> conditionCache;
std::unordered_map<std::string, Plugin> plugins;
std::vector<Message> messages;
bool isLoadOrderSorted;
mutable std::mutex mutex;
};
+1
View File
@@ -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;
}
+4 -1
View File
@@ -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") {
+7 -3
View File
@@ -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');
+25 -5
View File
@@ -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<Message> 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());
}
}
}