Source Bash Tag autocomplete suggestions from masterlist

This commit is contained in:
Oliver Hamlet
2016-07-13 07:23:33 +01:00
parent c293e83f19
commit ab5bdd26f9
10 changed files with 50 additions and 342 deletions
+1 -1
View File
@@ -89,7 +89,7 @@ set(PSEUDOSEM_INCLUDE_DIRS "${SOURCE_DIR}/include")
ExternalProject_Add(testing-metadata
PREFIX "external"
URL "https://github.com/loot/testing-metadata/archive/1.0.0.tar.gz"
URL "https://github.com/loot/testing-metadata/archive/1.1.0.tar.gz"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
+5 -1
View File
@@ -240,13 +240,17 @@ var {
<table>
<thead><tr><th>Key Name<th>Value Type<th>Notes
<tbody>
<tr><td><code>bash_tags</code><td>string list<td>A list of Bash Tags that are supported by the masterlist's game. These Bash Tags are used to provide autocomplete suggestions in LOOT's metadata editor.
<tr><td><code>globals</code><td>message list<td>A list of message data structures for messages that are displayed independently of any plugin.
<tr><td><code>plugins</code><td>plugin list <i>and</i> plugin set<td>The plugin data structures that hold all the plugin metadata within the file. It is a mixture of a list and a set because <strong>no non-regex plugin value may be equal to any other non-regex plugin value</strong>, but there may be any number of equal regex plugin values, and non-regex plugin values may be equal to regex plugin values.
<p>If multiple plugin values match a single plugin, their metadata is merged in the order the values are listed, and as defined <a href="#structs-plugin-merge">later in this document</a>.
</table>
<p>Other keys may also be present, but are not processed by LOOT. The message and plugin data structures are detailed in the next section.
<p>An example metadata file:
<pre><code>globals:
<pre><code>bash_tags:
- 'C.Climate'
- 'Relev'
globals:
- type: say
content: 'You are using the latest version of LOOT.'
condition: 'version("LOOT", "0.5.0.0", ==)'
-154
View File
@@ -54,73 +54,6 @@ namespace loot {
_masterFile = "Oblivion.esm";
_repositoryURL = "https://github.com/loot/oblivion.git";
_repositoryBranch = "v0.8";
bashTags = {
"Actors.ACBS",
"Actors.AIData",
"Actors.AIPackages",
"Actors.AIPackagesForceAdd",
"Actors.Animations",
"Actors.CombatStyle",
"Actors.DeathItem",
"Actors.Skeleton",
"Actors.Spells",
"Actors.SpellsForceAdd",
"Actors.Stats",
"Body-F",
"Body-M",
"Body-Size-F",
"Body-Size-M",
"C.Climate",
"C.Light",
"C.Music",
"C.Name",
"C.Owner",
"C.RecordFlags",
"C.Water",
"Creatures.Blood",
"Deactivate",
"Delev",
"Eyes",
"Factions",
"Filter",
"Graphics",
"Hair",
"IIM",
"Invent",
"InventOnly",
"Merge",
"MustBeActiveIfImported",
"Names",
"NoMerge",
"NpcFaces",
"NpcFacesForceFullImport",
"NPC.Class",
"Npc.EyesOnly",
"Npc.HairOnly",
"NPC.Race",
"Relations",
"Relev",
"Roads",
"R.AddSpells",
"R.Attributes-F",
"R.Attributes-M",
"R.ChangeSpells",
"R.Description",
"R.Ears",
"R.Head",
"R.Mouth",
"R.Relations",
"R.Skills",
"R.Teeth",
"ScriptContents",
"Scripts",
"Sound",
"SpellStats",
"Stats",
"Voice-F",
"Voice-M",
};
}
else if (Id() == GameSettings::tes5) {
_name = "TES V: Skyrim";
@@ -129,78 +62,6 @@ namespace loot {
_masterFile = "Skyrim.esm";
_repositoryURL = "https://github.com/loot/skyrim.git";
_repositoryBranch = "v0.8";
bashTags = {
"Actors.ACBS",
"Actors.AIData",
"Actors.AIPackages",
"Actors.AIPackagesForceAdd",
"Actors.Animations",
"Actors.CombatStyle",
"Actors.DeathItem",
"Actors.Skeleton",
"Actors.Spells",
"Actors.SpellsForceAdd",
"Actors.Stats",
"Body-F",
"Body-M",
"Body-Size-F",
"Body-Size-M",
"C.Acoustic",
"C.Climate",
"C.ImageSpace",
"C.Light",
"C.Location",
"C.Music",
"C.Name",
"C.Owner",
"C.RecordFlags",
"C.Regions",
"C.SkyLighting",
"C.Water",
"Creatures.Blood",
"Deactivate",
"Delev",
"Eyes",
"Factions",
"Filter",
"Graphics",
"Hair",
"IIM",
"Invent",
"InventOnly",
"Merge",
"MustBeActiveIfImported",
"Names",
"NoMerge",
"NpcFaces",
"NpcFacesForceFullImport",
"NPC.Class",
"Npc.EyesOnly",
"Npc.HairOnly",
"NPC.Race",
"Relations",
"Relev",
"Roads",
"R.AddSpells",
"R.Attributes-F",
"R.Attributes-M",
"R.ChangeSpells",
"R.Description",
"R.Ears",
"R.Head",
"R.Mouth",
"R.Relations",
"R.Skills",
"R.Teeth",
"ScriptContents",
"Scripts",
"Sound",
"SpellStats",
"Stats",
"Voice-F",
"Voice-M",
};
}
else if (Id() == GameSettings::fo3) {
_name = "Fallout 3";
@@ -209,11 +70,6 @@ namespace loot {
_masterFile = "Fallout3.esm";
_repositoryURL = "https://github.com/loot/fallout3.git";
_repositoryBranch = "v0.8";
bashTags = {
"Deflst",
"Destructible",
};
}
else if (Id() == GameSettings::fonv) {
_name = "Fallout: New Vegas";
@@ -222,12 +78,6 @@ namespace loot {
_masterFile = "FalloutNV.esm";
_repositoryURL = "https://github.com/loot/falloutnv.git";
_repositoryBranch = "v0.8";
bashTags = {
"Deflst",
"Destructible",
"WeaponMods",
};
}
else if (Id() == GameSettings::fo4) {
_name = "Fallout 4";
@@ -341,10 +191,6 @@ namespace loot {
return LootPaths::getLootDataPath() / _lootFolderName / "userlist.yaml";
}
std::vector<std::string> GameSettings::getSupportedBashTags() const {
return bashTags;
}
GameSettings& GameSettings::SetName(const std::string& name) {
BOOST_LOG_TRIVIAL(trace) << "Setting \"" << _name << "\" name to: " << name;
_name = name;
-4
View File
@@ -59,8 +59,6 @@ namespace loot {
boost::filesystem::path MasterlistPath() const;
boost::filesystem::path UserlistPath() const;
std::vector<std::string> getSupportedBashTags() const;
GameSettings& SetName(const std::string& name);
GameSettings& SetMaster(const std::string& masterFile);
GameSettings& SetRegistryKey(const std::string& registry);
@@ -86,8 +84,6 @@ namespace loot {
std::string _repositoryBranch;
boost::filesystem::path _gamePath; //Path to the game's folder.
std::vector<std::string> bashTags;
};
}
+11 -4
View File
@@ -33,9 +33,7 @@ using namespace std;
namespace loot {
void MetadataList::Load(const boost::filesystem::path& filepath) {
plugins.clear();
regexPlugins.clear();
messages.clear();
clear();
BOOST_LOG_TRIVIAL(debug) << "Loading file: " << filepath;
@@ -58,7 +56,10 @@ namespace loot {
}
}
if (metadataList["globals"])
messages = metadataList["globals"].as< list<Message> >();
messages = metadataList["globals"].as<list<Message>>();
if (metadataList["bash_tags"])
bashTags_ = metadataList["bash_tags"].as<set<string>>();
BOOST_LOG_TRIVIAL(debug) << "File loaded successfully.";
}
@@ -68,6 +69,7 @@ namespace loot {
YAML::Emitter yout;
yout.SetIndent(2);
yout << YAML::BeginMap
<< YAML::Key << "bash_tags" << YAML::Value << bashTags_
<< YAML::Key << "plugins" << YAML::Value << Plugins()
<< YAML::Key << "globals" << YAML::Value << messages
<< YAML::EndMap;
@@ -78,6 +80,7 @@ namespace loot {
}
void MetadataList::clear() {
bashTags_.clear();
plugins.clear();
regexPlugins.clear();
messages.clear();
@@ -95,6 +98,10 @@ namespace loot {
return messages;
}
std::set<std::string> MetadataList::BashTags() const {
return bashTags_;
}
// Merges multiple matching regex entries if any are found.
PluginMetadata MetadataList::FindPlugin(const PluginMetadata& plugin) const {
PluginMetadata match(plugin.Name());
+2
View File
@@ -54,6 +54,7 @@ namespace loot {
std::list<PluginMetadata> Plugins() const;
std::list<Message> Messages() const;
std::set<std::string> BashTags() const;
// Merges multiple matching regex entries if any are found.
PluginMetadata FindPlugin(const PluginMetadata& plugin) const;
@@ -69,6 +70,7 @@ namespace loot {
void EvalAllConditions(Game& game, const unsigned int language);
protected:
std::set<std::string> bashTags_;
std::unordered_set<PluginMetadata> plugins;
std::list<PluginMetadata> regexPlugins;
std::list<Message> messages;
+4 -1
View File
@@ -701,7 +701,7 @@ namespace loot {
// Now store global messages.
gameNode["globalMessages"] = GetGeneralMessages();
gameNode["bashTags"] = _lootState.CurrentGame().getSupportedBashTags();
gameNode["bashTags"] = _lootState.CurrentGame().GetMasterlist().BashTags();
// Now store plugin data.
for (const auto& plugin : installed) {
@@ -822,6 +822,9 @@ namespace loot {
gameNode["masterlist"]["date"] = e.what();
}
// Store bash tags in case they have changed.
gameNode["bashTags"] = _lootState.CurrentGame().GetMasterlist().BashTags();
// Store global messages in case they have changed.
gameNode["globalMessages"] = GetGeneralMessages();
+3
View File
@@ -80,6 +80,9 @@ function updateMasterlist() {
loot.game.masterlist = result.masterlist;
loot.game.globalMessages = result.globalMessages;
/* Update Bash Tag autocomplete suggestions. */
loot.DOM.initialiseAutocompleteBashTags(result.bashTags);
result.plugins.forEach((resultPlugin) => {
const existingPlugin = loot.game.plugins.find(plugin => plugin.name === resultPlugin.name);
if (existingPlugin) {
-176
View File
@@ -59,8 +59,6 @@ namespace loot {
EXPECT_EQ("", game.DataPath());
EXPECT_EQ("", game.MasterlistPath());
EXPECT_EQ("", game.UserlistPath());
EXPECT_TRUE(game.getSupportedBashTags().empty());
}
TEST_P(GameSettingsTest, idConstructorShouldInitialiseSettingsToDefaultsForThatGame) {
@@ -89,180 +87,6 @@ namespace loot {
EXPECT_EQ(LootPaths::getLootDataPath() / "folder" / "userlist.yaml", game.UserlistPath());
}
TEST_P(GameSettingsTest, idConstructorShouldSetCorrectBashTagsForTES4) {
game = GameSettings(GameSettings::tes4);
std::vector<std::string> expectedBashTags = {
"Actors.ACBS",
"Actors.AIData",
"Actors.AIPackages",
"Actors.AIPackagesForceAdd",
"Actors.Animations",
"Actors.CombatStyle",
"Actors.DeathItem",
"Actors.Skeleton",
"Actors.Spells",
"Actors.SpellsForceAdd",
"Actors.Stats",
"Body-F",
"Body-M",
"Body-Size-F",
"Body-Size-M",
"C.Climate",
"C.Light",
"C.Music",
"C.Name",
"C.Owner",
"C.RecordFlags",
"C.Water",
"Creatures.Blood",
"Deactivate",
"Delev",
"Eyes",
"Factions",
"Filter",
"Graphics",
"Hair",
"IIM",
"Invent",
"InventOnly",
"Merge",
"MustBeActiveIfImported",
"Names",
"NoMerge",
"NpcFaces",
"NpcFacesForceFullImport",
"NPC.Class",
"Npc.EyesOnly",
"Npc.HairOnly",
"NPC.Race",
"Relations",
"Relev",
"Roads",
"R.AddSpells",
"R.Attributes-F",
"R.Attributes-M",
"R.ChangeSpells",
"R.Description",
"R.Ears",
"R.Head",
"R.Mouth",
"R.Relations",
"R.Skills",
"R.Teeth",
"ScriptContents",
"Scripts",
"Sound",
"SpellStats",
"Stats",
"Voice-F",
"Voice-M",
};
EXPECT_EQ(expectedBashTags, game.getSupportedBashTags());
}
TEST_P(GameSettingsTest, idConstructorShouldSetCorrectBashTagsForTES5) {
game = GameSettings(GameSettings::tes5);
std::vector<std::string> expectedBashTags = {
"Actors.ACBS",
"Actors.AIData",
"Actors.AIPackages",
"Actors.AIPackagesForceAdd",
"Actors.Animations",
"Actors.CombatStyle",
"Actors.DeathItem",
"Actors.Skeleton",
"Actors.Spells",
"Actors.SpellsForceAdd",
"Actors.Stats",
"Body-F",
"Body-M",
"Body-Size-F",
"Body-Size-M",
"C.Acoustic",
"C.Climate",
"C.ImageSpace",
"C.Light",
"C.Location",
"C.Music",
"C.Name",
"C.Owner",
"C.RecordFlags",
"C.Regions",
"C.SkyLighting",
"C.Water",
"Creatures.Blood",
"Deactivate",
"Delev",
"Eyes",
"Factions",
"Filter",
"Graphics",
"Hair",
"IIM",
"Invent",
"InventOnly",
"Merge",
"MustBeActiveIfImported",
"Names",
"NoMerge",
"NpcFaces",
"NpcFacesForceFullImport",
"NPC.Class",
"Npc.EyesOnly",
"Npc.HairOnly",
"NPC.Race",
"Relations",
"Relev",
"Roads",
"R.AddSpells",
"R.Attributes-F",
"R.Attributes-M",
"R.ChangeSpells",
"R.Description",
"R.Ears",
"R.Head",
"R.Mouth",
"R.Relations",
"R.Skills",
"R.Teeth",
"ScriptContents",
"Scripts",
"Sound",
"SpellStats",
"Stats",
"Voice-F",
"Voice-M",
};
EXPECT_EQ(expectedBashTags, game.getSupportedBashTags());
}
TEST_P(GameSettingsTest, idConstructorShouldSetNoBashTagsForFO3) {
game = GameSettings(GameSettings::fo3);
std::vector<std::string> expectedBashTags = {
"Deflst",
"Destructible",
};
EXPECT_EQ(expectedBashTags, game.getSupportedBashTags());
}
TEST_P(GameSettingsTest, idConstructorShouldSetNoBashTagsForFONV) {
game = GameSettings(GameSettings::fonv);
std::vector<std::string> expectedBashTags = {
"Deflst",
"Destructible",
"WeaponMods",
};
EXPECT_EQ(expectedBashTags, game.getSupportedBashTags());
}
TEST_P(GameSettingsTest, idConstructorShouldSetNoBashTagsForFO4) {
EXPECT_TRUE(GameSettings(GameSettings::fo4).getSupportedBashTags().empty());
}
TEST_P(GameSettingsTest, isInstalledShouldBeFalseIfGamePathIsNotSet) {
GameSettings game;
EXPECT_FALSE(game.IsInstalled());
+24 -1
View File
@@ -26,6 +26,8 @@ along with LOOT. If not, see
#define LOOT_TEST_BACKEND_METADATA_LIST
#include "backend/metadata_list.h"
#include "backend/game/game.h"
#include "tests/base_game_test.h"
namespace loot {
@@ -110,6 +112,16 @@ namespace loot {
}), names);
}
TEST_P(MetadataListTest, loadShouldLoadBashTags) {
MetadataList metadataList;
ASSERT_NO_THROW(metadataList.Load(metadataPath));
EXPECT_EQ(std::set<std::string>({
"C.Climate",
"Relev"
}), metadataList.BashTags());
}
TEST_P(MetadataListTest, loadShouldThrowIfAnInvalidMetadataFileIsGiven) {
MetadataList ml;
for (const auto& path : invalidMetadataPaths) {
@@ -123,10 +135,12 @@ namespace loot {
ASSERT_NO_THROW(metadataList.Load(metadataPath));
ASSERT_FALSE(metadataList.Messages().empty());
ASSERT_FALSE(metadataList.Plugins().empty());
ASSERT_FALSE(metadataList.BashTags().empty());
EXPECT_ANY_THROW(metadataList.Load(blankEsm));
EXPECT_TRUE(metadataList.Messages().empty());
EXPECT_TRUE(metadataList.Plugins().empty());
EXPECT_TRUE(metadataList.BashTags().empty());
}
TEST_P(MetadataListTest, loadShouldClearExistingDataIfAMissingMetadataFileIsGiven) {
@@ -135,10 +149,12 @@ namespace loot {
ASSERT_NO_THROW(metadataList.Load(metadataPath));
ASSERT_FALSE(metadataList.Messages().empty());
ASSERT_FALSE(metadataList.Plugins().empty());
ASSERT_FALSE(metadataList.BashTags().empty());
EXPECT_ANY_THROW(metadataList.Load(missingMetadataPath));
EXPECT_TRUE(metadataList.Messages().empty());
EXPECT_TRUE(metadataList.Plugins().empty());
EXPECT_TRUE(metadataList.BashTags().empty());
}
TEST_P(MetadataListTest, saveShouldWriteTheLoadedMetadataToTheGivenFilePath) {
@@ -152,6 +168,11 @@ namespace loot {
// Check the new file contains the same metadata.
EXPECT_NO_THROW(metadataList.Load(savedMetadataPath));
EXPECT_EQ(std::set<std::string>({
"C.Climate",
"Relev"
}), metadataList.BashTags());
EXPECT_EQ(std::list<Message>({
Message(Message::say, "A global message."),
}), metadataList.Messages());
@@ -173,15 +194,17 @@ namespace loot {
}), names);
}
TEST_P(MetadataListTest, clearShouldClearLoadedMessagesAndPlugins) {
TEST_P(MetadataListTest, clearShouldClearLoadedData) {
MetadataList metadataList;
ASSERT_NO_THROW(metadataList.Load(metadataPath));
ASSERT_FALSE(metadataList.Messages().empty());
ASSERT_FALSE(metadataList.Plugins().empty());
ASSERT_FALSE(metadataList.BashTags().empty());
metadataList.clear();
EXPECT_TRUE(metadataList.Messages().empty());
EXPECT_TRUE(metadataList.Plugins().empty());
EXPECT_TRUE(metadataList.BashTags().empty());
}
TEST_P(MetadataListTest, findPluginShouldReturnAnEmptyPluginObjectIfTheGivenPluginIsNotInTheMetadataList) {