Don't throw when checking FormID overlap

If the passed object is not a Plugin object.
This commit is contained in:
Oliver Hamlet
2017-02-06 22:37:35 +00:00
parent ef4cedab86
commit 11a3bc5d3a
2 changed files with 43 additions and 18 deletions
+19 -18
View File
@@ -160,26 +160,27 @@ bool Plugin::LoadsArchive() const {
}
bool Plugin::DoFormIDsOverlap(const PluginInterface& plugin) const {
// Assume the PluginInterface is another plugin: it'll throw if it's not.
// Not great design, but the function needs getFormIds() and that can't
// be exposed in the interface.
const Plugin& otherPlugin = dynamic_cast<const Plugin&>(plugin);
try {
auto otherPlugin = dynamic_cast<const Plugin&>(plugin);
//Basically std::set_intersection except with an early exit instead of an append to results.
set<FormId> formIds(getFormIds());
set<FormId> otherFormIds(otherPlugin.getFormIds());
auto i = begin(formIds);
auto j = begin(otherFormIds);
auto iend = end(formIds);
auto jend = end(otherFormIds);
//Basically std::set_intersection except with an early exit instead of an append to results.
set<FormId> formIds(getFormIds());
set<FormId> otherFormIds(otherPlugin.getFormIds());
auto i = begin(formIds);
auto j = begin(otherFormIds);
auto iend = end(formIds);
auto jend = end(otherFormIds);
while (i != iend && j != jend) {
if (*i < *j)
++i;
else if (*j < *i)
++j;
else
return true;
while (i != iend && j != jend) {
if (*i < *j)
++i;
else if (*j < *i)
++j;
else
return true;
}
} catch (std::bad_cast& e) {
BOOST_LOG_TRIVIAL(error) << "Tried to check if FormIDs overlapped with a non-Plugin implementation of PluginInterface.";
}
return false;
@@ -79,6 +79,22 @@ protected:
const std::string blankSuffixArchive;
};
class OtherPluginType : public PluginInterface {
public:
std::string GetName() const { return ""; }
std::string GetLowercasedName() const { return ""; }
std::string GetVersion() const { return ""; }
std::vector<std::string> GetMasters() const { return std::vector<std::string>(); }
std::vector<Message> GetStatusMessages() const { return std::vector<Message>(); }
std::set<Tag> GetBashTags() const { return std::set<Tag>(); }
uint32_t GetCRC() const { return 0; }
bool IsMaster() const { return false; }
bool IsEmpty() const { return false; }
bool LoadsArchive() const { return false; }
bool DoFormIDsOverlap(const PluginInterface& plugin) const { return true; }
};
// Pass an empty first argument, as it's a prefix for the test instantation,
// but we only have the one so no prefix is necessary.
INSTANTIATE_TEST_CASE_P(,
@@ -216,6 +232,14 @@ TEST_P(PluginTest, lessThanOperatorShouldUseCaseInsensitiveLexicographicalNameCo
EXPECT_FALSE(plugin4 < plugin3);
}
TEST_P(PluginTest, doFormIDsOverlapShouldReturnFalseIfTheArgumentIsNotAPluginObject) {
Plugin plugin1(game_, blankEsm, false);
OtherPluginType plugin2;
EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2));
EXPECT_TRUE(plugin2.DoFormIDsOverlap(plugin1));
}
TEST_P(PluginTest, doFormIDsOverlapShouldReturnFalseForTwoPluginsWithOnlyHeadersLoaded) {
Plugin plugin1(game_, blankEsm, true);
Plugin plugin2(game_, blankMasterDependentEsm, true);