Fixes issue with iterating over two script sets.
continuous-integration/drone/push Build is passing Details

Signed-off-by: Deukhoofd <Deukhoofd@gmail.com>
This commit is contained in:
Deukhoofd 2021-04-17 16:23:29 +02:00
parent 9f091308b0
commit 8f9f2b2b8d
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
2 changed files with 74 additions and 48 deletions

View File

@ -7,7 +7,7 @@
namespace CreatureLib::Battling { namespace CreatureLib::Battling {
class ScriptAggregator { class ScriptAggregator {
const ScriptWrapper *_scripts; const ScriptWrapper* _scripts;
i32 _size; i32 _size;
i32 _index = 0; i32 _index = 0;
i32 _setIndex = 0; i32 _setIndex = 0;
@ -15,7 +15,7 @@ namespace CreatureLib::Battling {
inline void IncrementToNextNotNull(bool initialIncrement = true) { inline void IncrementToNextNotNull(bool initialIncrement = true) {
if (_scripts[_index].IsSet()) { if (_scripts[_index].IsSet()) {
_setIndex++; _setIndex++;
if (_setIndex >= (i32) _scripts[_index].GetScriptSet()->Count()) { if (_setIndex >= (i32)_scripts[_index].GetScriptSet()->Count()) {
_setIndex = -1; _setIndex = -1;
} else { } else {
return; return;
@ -32,10 +32,10 @@ namespace CreatureLib::Battling {
} }
public: public:
ScriptAggregator() {}; ScriptAggregator(){};
explicit ScriptAggregator(const ArbUt::List<ScriptWrapper> &scripts) explicit ScriptAggregator(const ArbUt::List<ScriptWrapper>& scripts)
: _scripts(scripts.RawData()), _size(scripts.Count()) { : _scripts(scripts.RawData()), _size(scripts.Count()) {
Reset(); Reset();
}; };
@ -60,13 +60,16 @@ namespace CreatureLib::Battling {
} }
ArbUt::BorrowedPtr<BattleScript> GetNext() { ArbUt::BorrowedPtr<BattleScript> GetNext() {
auto &current = _scripts[_index]; auto& current = _scripts[_index];
if (!current.IsSet()) { if (!current.IsSet()) {
auto s = current.GetScript(); auto s = current.GetScript();
IncrementToNextNotNull(); IncrementToNextNotNull();
return (*s); return (*s);
} else { } else {
auto &set = current.GetScriptSet()->GetIterator(); auto& set = current.GetScriptSet()->GetIterator();
if (_setIndex == -1) {
_setIndex = 0;
}
auto v = set[_setIndex]; auto v = set[_setIndex];
IncrementToNextNotNull(); IncrementToNextNotNull();
return v; return v;

View File

@ -12,49 +12,49 @@ private:
ArbUt::StringView _name; ArbUt::StringView _name;
public: public:
explicit TestScript(const ArbUt::StringView &name) : _name(name) {}; explicit TestScript(const ArbUt::StringView& name) : _name(name){};
const ArbUt::StringView &GetName() const noexcept override { return _name; } const ArbUt::StringView& GetName() const noexcept override { return _name; }
void TestMethod(int &runCount) { runCount++; } void TestMethod(int& runCount) { runCount++; }
BattleScript *Clone() override { return new TestScript(_name); } BattleScript* Clone() override { return new TestScript(_name); }
}; };
TEST_CASE ("Script Aggregator properly iterates containing script.") { TEST_CASE("Script Aggregator properly iterates containing script.") {
auto script = std::make_unique<TestScript>("test"); auto script = std::make_unique<TestScript>("test");
auto ran = 0; auto ran = 0;
auto vec = ArbUt::List<ScriptWrapper>{ auto vec = ArbUt::List<ScriptWrapper>{
ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript> *>(&script))}; ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript>*>(&script))};
auto aggr = ScriptAggregator(vec); auto aggr = ScriptAggregator(vec);
while (aggr.HasNext()) { while (aggr.HasNext()) {
auto next = aggr.GetNext(); auto next = aggr.GetNext();
next.As<TestScript>()->TestMethod(ran); next.As<TestScript>()->TestMethod(ran);
} }
CHECK(ran == 1); CHECK(ran == 1);
} }
TEST_CASE ("Script Aggregator properly iterates multiple scripts.") { TEST_CASE("Script Aggregator properly iterates multiple scripts.") {
auto script = std::make_unique<TestScript>("test"); auto script = std::make_unique<TestScript>("test");
auto script2 = std::make_unique<TestScript>("test2"); auto script2 = std::make_unique<TestScript>("test2");
auto script3 = std::make_unique<TestScript>("test3"); auto script3 = std::make_unique<TestScript>("test3");
auto ran = 0; auto ran = 0;
auto vec = ArbUt::List<ScriptWrapper>{ auto vec = ArbUt::List<ScriptWrapper>{
ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript> *>(&script)), ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript>*>(&script)),
ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript> *>(&script2)), ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript>*>(&script2)),
ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript> *>(&script3))}; ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript>*>(&script3))};
auto aggr = ScriptAggregator(vec); auto aggr = ScriptAggregator(vec);
while (aggr.HasNext()) { while (aggr.HasNext()) {
auto next = aggr.GetNext(); auto next = aggr.GetNext();
next.As<TestScript>()->TestMethod(ran); next.As<TestScript>()->TestMethod(ran);
} }
CHECK(ran == 3); CHECK(ran == 3);
} }
TEST_CASE ("Script Aggregator properly iterates Script Set.") { TEST_CASE("Script Aggregator properly iterates Script Set.") {
BattleScript *script = new TestScript("test"); BattleScript* script = new TestScript("test");
BattleScript *script2 = new TestScript("test2"); BattleScript* script2 = new TestScript("test2");
BattleScript *script3 = new TestScript("test3"); BattleScript* script3 = new TestScript("test3");
auto ran = 0; auto ran = 0;
auto set = ScriptSet(); auto set = ScriptSet();
set.Add(script); set.Add(script);
@ -66,80 +66,103 @@ TEST_CASE ("Script Aggregator properly iterates Script Set.") {
auto next = aggr.GetNextNotNull(); auto next = aggr.GetNextNotNull();
next.value().As<TestScript>()->TestMethod(ran); next.value().As<TestScript>()->TestMethod(ran);
} }
CHECK(ran == 3); CHECK(ran == 3);
} }
TEST_CASE ("Script Aggregator properly iterates data of Script Set and Script.") { TEST_CASE("Script Aggregator properly iterates data of Script Set and Script.") {
auto script = std::make_unique<TestScript>("test"); auto script = std::make_unique<TestScript>("test");
BattleScript *script2 = new TestScript("test2"); BattleScript* script2 = new TestScript("test2");
BattleScript *script3 = new TestScript("test3"); BattleScript* script3 = new TestScript("test3");
auto ran = 0; auto ran = 0;
auto set = ScriptSet(); auto set = ScriptSet();
set.Add(script2); set.Add(script2);
set.Add(script3); set.Add(script3);
auto vec = ArbUt::List<ScriptWrapper>{ auto vec = ArbUt::List<ScriptWrapper>{
ScriptWrapper::FromSet(&set), ScriptWrapper::FromSet(&set),
ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript> *>(&script))}; ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript>*>(&script))};
auto aggr = ScriptAggregator(vec); auto aggr = ScriptAggregator(vec);
while (aggr.HasNext()) { while (aggr.HasNext()) {
auto next = aggr.GetNextNotNull(); auto next = aggr.GetNextNotNull();
next.value().As<TestScript>()->TestMethod(ran); next.value().As<TestScript>()->TestMethod(ran);
} }
CHECK(ran == 3); CHECK(ran == 3);
} }
TEST_CASE ("Script Aggregator properly iterates data of Script and Script Set.") { TEST_CASE("Script Aggregator properly iterates data of Script and Script Set.") {
auto script = std::make_unique<TestScript>("test"); auto script = std::make_unique<TestScript>("test");
BattleScript *script2 = new TestScript("test2"); BattleScript* script2 = new TestScript("test2");
BattleScript *script3 = new TestScript("test3"); BattleScript* script3 = new TestScript("test3");
auto ran = 0; auto ran = 0;
auto set = ScriptSet(); auto set = ScriptSet();
set.Add(script2); set.Add(script2);
set.Add(script3); set.Add(script3);
auto vec = auto vec =
ArbUt::List<ScriptWrapper>{ ArbUt::List<ScriptWrapper>{ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript>*>(&script)),
ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript> *>(&script)), ScriptWrapper::FromSet(&set)};
ScriptWrapper::FromSet(&set)};
auto aggr = ScriptAggregator(vec); auto aggr = ScriptAggregator(vec);
while (aggr.HasNext()) { while (aggr.HasNext()) {
auto next = aggr.GetNextNotNull(); auto next = aggr.GetNextNotNull();
next.value().As<TestScript>()->TestMethod(ran); next.value().As<TestScript>()->TestMethod(ran);
} }
CHECK(ran == 3); CHECK(ran == 3);
} }
TEST_CASE ("Script Aggregator properly iterates data of Script, Script Set and Script.") { TEST_CASE("Script Aggregator properly iterates data of Script, Script Set and Script.") {
auto script = std::make_unique<TestScript>("test"); auto script = std::make_unique<TestScript>("test");
BattleScript *script2 = new TestScript("test2"); BattleScript* script2 = new TestScript("test2");
BattleScript *script3 = new TestScript("test3"); BattleScript* script3 = new TestScript("test3");
auto script4 = std::make_unique<TestScript>("test4"); auto script4 = std::make_unique<TestScript>("test4");
auto ran = 0; auto ran = 0;
auto set = ScriptSet(); auto set = ScriptSet();
set.Add(script2); set.Add(script2);
set.Add(script3); set.Add(script3);
auto vec = ArbUt::List<ScriptWrapper>{ auto vec = ArbUt::List<ScriptWrapper>{
ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript> *>(&script)), ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript>*>(&script)),
ScriptWrapper::FromSet(&set), ScriptWrapper::FromSet(&set),
ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript> *>(&script4))}; ScriptWrapper::FromScript(reinterpret_cast<std::unique_ptr<BattleScript>*>(&script4))};
auto aggr = ScriptAggregator(vec); auto aggr = ScriptAggregator(vec);
while (aggr.HasNext()) { while (aggr.HasNext()) {
auto next = aggr.GetNextNotNull(); auto next = aggr.GetNextNotNull();
next.value().As<TestScript>()->TestMethod(ran); next.value().As<TestScript>()->TestMethod(ran);
} }
CHECK(ran == 4); CHECK(ran == 4);
} }
TEST_CASE ("Script Aggregator properly iterates when empty.") { TEST_CASE("Script Aggregator properly iterates multiple script sets.") {
BattleScript* script1 = new TestScript("test");
BattleScript* script2 = new TestScript("test2");
BattleScript* script3 = new TestScript("test3");
BattleScript* script4 = new TestScript("test4");
auto ran = 0;
auto set1 = ScriptSet();
set1.Add(script2);
set1.Add(script3);
auto set2 = ScriptSet();
set2.Add(script1);
set2.Add(script4);
auto vec = ArbUt::List<ScriptWrapper>{
ScriptWrapper::FromSet(&set1),
ScriptWrapper::FromSet(&set2),
};
auto aggr = ScriptAggregator(vec);
while (aggr.HasNext()) {
auto next = aggr.GetNextNotNull();
next.value().As<TestScript>()->TestMethod(ran);
}
CHECK(ran == 4);
}
TEST_CASE("Script Aggregator properly iterates when empty.") {
auto ran = 0; auto ran = 0;
auto vec = ArbUt::List<ScriptWrapper>{}; auto vec = ArbUt::List<ScriptWrapper>{};
auto aggr = ScriptAggregator(vec); auto aggr = ScriptAggregator(vec);
while (aggr.HasNext()) { while (aggr.HasNext()) {
THROW("Aggregator returned a script, but should have been empty."); THROW("Aggregator returned a script, but should have been empty.");
} }
CHECK(ran == 0); CHECK(ran == 0);
} }
TEST_CASE ("Script Aggregator properly iterates empty Script Set.") { TEST_CASE("Script Aggregator properly iterates empty Script Set.") {
auto ran = 0; auto ran = 0;
auto set = ScriptSet(); auto set = ScriptSet();
auto vec = ArbUt::List<ScriptWrapper>{ScriptWrapper::FromSet(&set)}; auto vec = ArbUt::List<ScriptWrapper>{ScriptWrapper::FromSet(&set)};
@ -148,7 +171,7 @@ TEST_CASE ("Script Aggregator properly iterates empty Script Set.") {
while (aggr.HasNext()) { while (aggr.HasNext()) {
ran++; ran++;
} }
CHECK(ran == 0); CHECK(ran == 0);
} }
#endif #endif