Cleanup of ScriptAggregator class.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
3a11bba913
commit
dd668f2b1c
|
@ -85,7 +85,9 @@ bool Battle::CreatureInField(const Creature* creature) const {
|
||||||
|
|
||||||
void Battle::ForceRecall(uint8_t side, uint8_t index) { _sides[side]->SetCreature(nullptr, index); }
|
void Battle::ForceRecall(uint8_t side, uint8_t index) { _sides[side]->SetCreature(nullptr, index); }
|
||||||
|
|
||||||
void Battle::GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) { scripts.Append(&_volatile); }
|
void Battle::GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) {
|
||||||
|
scripts.Append(ScriptWrapper::FromSet(&_volatile));
|
||||||
|
}
|
||||||
|
|
||||||
void Battle::SwitchCreature(uint8_t sideIndex, uint8_t index, Creature* c) {
|
void Battle::SwitchCreature(uint8_t sideIndex, uint8_t index, Creature* c) {
|
||||||
auto side = this->_sides[sideIndex];
|
auto side = this->_sides[sideIndex];
|
||||||
|
|
|
@ -70,7 +70,7 @@ bool BattleSide::CreatureOnSide(const Creature* creature) const {
|
||||||
Creature* BattleSide::GetCreature(uint8_t index) const { return _creatures[index]; }
|
Creature* BattleSide::GetCreature(uint8_t index) const { return _creatures[index]; }
|
||||||
|
|
||||||
void BattleSide::GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) {
|
void BattleSide::GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) {
|
||||||
scripts.Append(&_volatile);
|
scripts.Append(ScriptWrapper::FromSet(&_volatile));
|
||||||
_battle->GetActiveScripts(scripts);
|
_battle->GetActiveScripts(scripts);
|
||||||
}
|
}
|
||||||
uint8_t BattleSide::GetRandomCreatureIndex() {
|
uint8_t BattleSide::GetRandomCreatureIndex() {
|
||||||
|
|
|
@ -167,9 +167,9 @@ bool Battling::Creature::HasType(uint8_t type) const noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Battling::Creature::GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) {
|
void Battling::Creature::GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) {
|
||||||
scripts.Append(&_activeTalent);
|
scripts.Append(ScriptWrapper::FromScript(&_activeTalent));
|
||||||
scripts.Append(&_status);
|
scripts.Append(ScriptWrapper::FromScript(&_status));
|
||||||
scripts.Append(&_volatile);
|
scripts.Append(ScriptWrapper::FromSet(&_volatile));
|
||||||
if (_side != nullptr) {
|
if (_side != nullptr) {
|
||||||
_side->GetActiveScripts(scripts);
|
_side->GetActiveScripts(scripts);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace CreatureLib::Battling {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override {
|
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override {
|
||||||
scripts.Append(&_script);
|
scripts.Append(ScriptWrapper::FromScript(&_script));
|
||||||
_user->GetActiveScripts(scripts);
|
_user->GetActiveScripts(scripts);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,54 +11,54 @@ using namespace Arbutils::Collections;
|
||||||
|
|
||||||
namespace CreatureLib::Battling {
|
namespace CreatureLib::Battling {
|
||||||
class ScriptAggregator {
|
class ScriptAggregator {
|
||||||
List<ScriptWrapper> _scripts;
|
const ScriptWrapper* _scripts;
|
||||||
|
size_t _size;
|
||||||
size_t _index = 0;
|
size_t _index = 0;
|
||||||
bool _isSetSet = false;
|
|
||||||
const List<Script*>* _setScripts = nullptr;
|
|
||||||
size_t _setIndex = 0;
|
size_t _setIndex = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScriptAggregator(){};
|
ScriptAggregator(){};
|
||||||
explicit ScriptAggregator(const List<ScriptWrapper>& scripts) : _scripts(scripts){};
|
explicit ScriptAggregator(const List<ScriptWrapper>& scripts)
|
||||||
|
: _scripts(scripts.RawData()), _size(scripts.Count()){};
|
||||||
|
|
||||||
void Reset() {
|
inline void Reset() {
|
||||||
_index = 0;
|
_index = 0;
|
||||||
_isSetSet = false;
|
|
||||||
_setIndex = 0;
|
_setIndex = 0;
|
||||||
}
|
}
|
||||||
bool HasNext() { return _index < _scripts.Count() || (_isSetSet && _setIndex < _setScripts->Count()); }
|
inline bool HasNext() { return _index < _size; }
|
||||||
|
|
||||||
|
Script* GetNextNotNull() {
|
||||||
|
while (HasNext()) {
|
||||||
|
auto s = GetNext();
|
||||||
|
if (s != nullptr) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Script* GetNext() {
|
Script* GetNext() {
|
||||||
// We can probably do this in a cleaner version once C++ 20 drops with Coroutine support.
|
auto& current = _scripts[_index];
|
||||||
if (_isSetSet) {
|
if (!current.IsSet()) {
|
||||||
if (_setIndex >= _setScripts->Count()) {
|
_index++;
|
||||||
_isSetSet = false;
|
auto s = current.GetScript();
|
||||||
return GetNext();
|
if (s == nullptr)
|
||||||
}
|
return nullptr;
|
||||||
auto s = _setScripts->At(_setIndex);
|
return *s;
|
||||||
_setIndex++;
|
|
||||||
if (_setIndex >= _setScripts->Count()) {
|
|
||||||
_isSetSet = false;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
if (_index >= _scripts.Count())
|
|
||||||
return nullptr;
|
|
||||||
auto& next = _scripts[_index];
|
|
||||||
_index++;
|
|
||||||
if (!next.IsSet()) {
|
|
||||||
auto scriptPtr = next.GetScript();
|
|
||||||
if (scriptPtr == nullptr)
|
|
||||||
return GetNext();
|
|
||||||
return *scriptPtr;
|
|
||||||
} else {
|
} else {
|
||||||
auto set = next.GetScriptSet();
|
auto& set = *current.GetScriptSet()->GetIterator();
|
||||||
if (set->Count() == 0)
|
auto count = set.Count();
|
||||||
return GetNext();
|
if (_setIndex >= count) {
|
||||||
_setScripts = set->GetIterator();
|
_index++;
|
||||||
_isSetSet = true;
|
_setIndex = 0;
|
||||||
_setIndex = 0;
|
return nullptr;
|
||||||
return GetNext();
|
}
|
||||||
|
auto v = set[_setIndex++];
|
||||||
|
if (_setIndex >= count) {
|
||||||
|
_index++;
|
||||||
|
_setIndex = 0;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace CreatureLib::Battling {
|
||||||
|
|
||||||
bool Has(uint32_t keyHash) const { return _lookup.Has(keyHash); }
|
bool Has(uint32_t keyHash) const { return _lookup.Has(keyHash); }
|
||||||
|
|
||||||
size_t Count() const { return _scripts.Count(); }
|
inline size_t Count() const { return _scripts.Count(); }
|
||||||
|
|
||||||
const Arbutils::Collections::List<Script*>* GetIterator() const { return &_scripts; }
|
const Arbutils::Collections::List<Script*>* GetIterator() const { return &_scripts; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
namespace CreatureLib::Battling {
|
namespace CreatureLib::Battling {
|
||||||
class ScriptSource {
|
class ScriptSource {
|
||||||
bool _areScriptsInitialized = false;
|
bool _areScriptsInitialized = false;
|
||||||
ScriptAggregator _scripts;
|
List<ScriptWrapper> _scripts;
|
||||||
|
ScriptAggregator _scriptsIterator;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) = 0;
|
virtual void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) = 0;
|
||||||
|
@ -17,12 +18,11 @@ namespace CreatureLib::Battling {
|
||||||
public:
|
public:
|
||||||
const ScriptAggregator& GetScriptIterator() {
|
const ScriptAggregator& GetScriptIterator() {
|
||||||
if (!_areScriptsInitialized) {
|
if (!_areScriptsInitialized) {
|
||||||
List<ScriptWrapper> scripts;
|
GetActiveScripts(_scripts);
|
||||||
GetActiveScripts(scripts);
|
_scriptsIterator = ScriptAggregator(_scripts);
|
||||||
_scripts = ScriptAggregator(scripts);
|
|
||||||
_areScriptsInitialized = true;
|
_areScriptsInitialized = true;
|
||||||
}
|
}
|
||||||
return _scripts;
|
return _scriptsIterator;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,20 +7,24 @@
|
||||||
|
|
||||||
namespace CreatureLib::Battling {
|
namespace CreatureLib::Battling {
|
||||||
class ScriptWrapper {
|
class ScriptWrapper {
|
||||||
union {
|
|
||||||
Script** _script;
|
|
||||||
ScriptSet* _scriptSet;
|
|
||||||
};
|
|
||||||
bool _isSet;
|
bool _isSet;
|
||||||
|
|
||||||
|
union {
|
||||||
|
Script* const* _script;
|
||||||
|
const ScriptSet* _scriptSet;
|
||||||
|
};
|
||||||
|
|
||||||
|
ScriptWrapper(Script** s, bool isSet) : _isSet(isSet), _script(s){};
|
||||||
|
ScriptWrapper(ScriptSet* s, bool isSet) : _isSet(isSet), _scriptSet(s){};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScriptWrapper(Script** s) : _script(s), _isSet(false) {}
|
static inline ScriptWrapper FromScript(Script** s) { return ScriptWrapper(s, false); }
|
||||||
ScriptWrapper(ScriptSet* s) : _scriptSet(s), _isSet(true) {}
|
static inline ScriptWrapper FromSet(ScriptSet* s) { return ScriptWrapper(s, true); }
|
||||||
|
|
||||||
bool IsSet() const { return _isSet; }
|
bool IsSet() const { return _isSet; }
|
||||||
|
|
||||||
Script** GetScript() const { return _script; }
|
inline Script* const* GetScript() const { return _script; }
|
||||||
ScriptSet* GetScriptSet() const { return _scriptSet; }
|
inline const ScriptSet* GetScriptSet() const { return _scriptSet; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace CreatureLib::Battling {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override {
|
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override {
|
||||||
scripts.Append(&_attackScript);
|
scripts.Append(ScriptWrapper::FromScript(&_attackScript));
|
||||||
GetUser()->GetActiveScripts(scripts);
|
GetUser()->GetActiveScripts(scripts);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
TEST_CASE("Script Aggregator properly iterates containing script.", "[Battling, Scripting]") {
|
TEST_CASE("Script Aggregator properly iterates containing script.", "[Battling, Scripting]") {
|
||||||
Script* script = new TestScript("test");
|
Script* script = new TestScript("test");
|
||||||
auto ran = 0;
|
auto ran = 0;
|
||||||
auto vec = Arbutils::Collections::List<ScriptWrapper>{&script};
|
auto vec = Arbutils::Collections::List<ScriptWrapper>{ScriptWrapper::FromScript(&script)};
|
||||||
auto aggr = ScriptAggregator(vec);
|
auto aggr = ScriptAggregator(vec);
|
||||||
while (aggr.HasNext()) {
|
while (aggr.HasNext()) {
|
||||||
auto next = aggr.GetNext();
|
auto next = aggr.GetNext();
|
||||||
|
@ -37,7 +37,8 @@ TEST_CASE("Script Aggregator properly iterates multiple scripts.", "[Battling, S
|
||||||
Script* script2 = new TestScript("test2");
|
Script* script2 = new TestScript("test2");
|
||||||
Script* script3 = new TestScript("test3");
|
Script* script3 = new TestScript("test3");
|
||||||
auto ran = 0;
|
auto ran = 0;
|
||||||
auto vec = Arbutils::Collections::List<ScriptWrapper>{&script, &script2, &script3};
|
auto vec = Arbutils::Collections::List<ScriptWrapper>{
|
||||||
|
ScriptWrapper::FromScript(&script), ScriptWrapper::FromScript(&script2), ScriptWrapper::FromScript(&script3)};
|
||||||
auto aggr = ScriptAggregator(vec);
|
auto aggr = ScriptAggregator(vec);
|
||||||
while (aggr.HasNext()) {
|
while (aggr.HasNext()) {
|
||||||
auto next = aggr.GetNext();
|
auto next = aggr.GetNext();
|
||||||
|
@ -59,10 +60,10 @@ TEST_CASE("Script Aggregator properly iterates Script Set.", "[Battling, Scripti
|
||||||
set.Add(script);
|
set.Add(script);
|
||||||
set.Add(script2);
|
set.Add(script2);
|
||||||
set.Add(script3);
|
set.Add(script3);
|
||||||
auto vec = Arbutils::Collections::List<ScriptWrapper>{&set};
|
auto vec = Arbutils::Collections::List<ScriptWrapper>{ScriptWrapper::FromSet(&set)};
|
||||||
auto aggr = ScriptAggregator(vec);
|
auto aggr = ScriptAggregator(vec);
|
||||||
while (aggr.HasNext()) {
|
while (aggr.HasNext()) {
|
||||||
auto next = aggr.GetNext();
|
auto next = aggr.GetNextNotNull();
|
||||||
REQUIRE(next != nullptr);
|
REQUIRE(next != nullptr);
|
||||||
dynamic_cast<TestScript*>(next)->TestMethod(ran);
|
dynamic_cast<TestScript*>(next)->TestMethod(ran);
|
||||||
}
|
}
|
||||||
|
@ -77,10 +78,11 @@ TEST_CASE("Script Aggregator properly iterates data of Script Set and Script.",
|
||||||
auto set = ScriptSet();
|
auto set = ScriptSet();
|
||||||
set.Add(script2);
|
set.Add(script2);
|
||||||
set.Add(script3);
|
set.Add(script3);
|
||||||
auto vec = Arbutils::Collections::List<ScriptWrapper>{&set, &script};
|
auto vec =
|
||||||
|
Arbutils::Collections::List<ScriptWrapper>{ScriptWrapper::FromSet(&set), ScriptWrapper::FromScript(&script)};
|
||||||
auto aggr = ScriptAggregator(vec);
|
auto aggr = ScriptAggregator(vec);
|
||||||
while (aggr.HasNext()) {
|
while (aggr.HasNext()) {
|
||||||
auto next = aggr.GetNext();
|
auto next = aggr.GetNextNotNull();
|
||||||
REQUIRE(next != nullptr);
|
REQUIRE(next != nullptr);
|
||||||
dynamic_cast<TestScript*>(next)->TestMethod(ran);
|
dynamic_cast<TestScript*>(next)->TestMethod(ran);
|
||||||
}
|
}
|
||||||
|
@ -96,10 +98,11 @@ TEST_CASE("Script Aggregator properly iterates data of Script and Script Set.",
|
||||||
auto set = ScriptSet();
|
auto set = ScriptSet();
|
||||||
set.Add(script2);
|
set.Add(script2);
|
||||||
set.Add(script3);
|
set.Add(script3);
|
||||||
auto vec = Arbutils::Collections::List<ScriptWrapper>{&script, &set};
|
auto vec =
|
||||||
|
Arbutils::Collections::List<ScriptWrapper>{ScriptWrapper::FromScript(&script), ScriptWrapper::FromSet(&set)};
|
||||||
auto aggr = ScriptAggregator(vec);
|
auto aggr = ScriptAggregator(vec);
|
||||||
while (aggr.HasNext()) {
|
while (aggr.HasNext()) {
|
||||||
auto next = aggr.GetNext();
|
auto next = aggr.GetNextNotNull();
|
||||||
REQUIRE(next != nullptr);
|
REQUIRE(next != nullptr);
|
||||||
dynamic_cast<TestScript*>(next)->TestMethod(ran);
|
dynamic_cast<TestScript*>(next)->TestMethod(ran);
|
||||||
}
|
}
|
||||||
|
@ -116,10 +119,11 @@ TEST_CASE("Script Aggregator properly iterates data of Script, Script Set and Sc
|
||||||
auto set = ScriptSet();
|
auto set = ScriptSet();
|
||||||
set.Add(script2);
|
set.Add(script2);
|
||||||
set.Add(script3);
|
set.Add(script3);
|
||||||
auto vec = Arbutils::Collections::List<ScriptWrapper>{&script, &set, &script4};
|
auto vec = Arbutils::Collections::List<ScriptWrapper>{
|
||||||
|
ScriptWrapper::FromScript(&script), ScriptWrapper::FromSet(&set), ScriptWrapper::FromScript(&script4)};
|
||||||
auto aggr = ScriptAggregator(vec);
|
auto aggr = ScriptAggregator(vec);
|
||||||
while (aggr.HasNext()) {
|
while (aggr.HasNext()) {
|
||||||
auto next = aggr.GetNext();
|
auto next = aggr.GetNextNotNull();
|
||||||
REQUIRE(next != nullptr);
|
REQUIRE(next != nullptr);
|
||||||
dynamic_cast<TestScript*>(next)->TestMethod(ran);
|
dynamic_cast<TestScript*>(next)->TestMethod(ran);
|
||||||
}
|
}
|
||||||
|
@ -141,7 +145,7 @@ TEST_CASE("Script Aggregator properly iterates when empty.", "[Battling, Scripti
|
||||||
TEST_CASE("Script Aggregator properly iterates empty Script Set.", "[Battling, Scripting]") {
|
TEST_CASE("Script Aggregator properly iterates empty Script Set.", "[Battling, Scripting]") {
|
||||||
auto ran = 0;
|
auto ran = 0;
|
||||||
auto set = ScriptSet();
|
auto set = ScriptSet();
|
||||||
auto vec = Arbutils::Collections::List<ScriptWrapper>{&set};
|
auto vec = Arbutils::Collections::List<ScriptWrapper>{ScriptWrapper::FromSet(&set)};
|
||||||
auto aggr = ScriptAggregator(vec);
|
auto aggr = ScriptAggregator(vec);
|
||||||
while (aggr.HasNext()) {
|
while (aggr.HasNext()) {
|
||||||
auto next = aggr.GetNext();
|
auto next = aggr.GetNext();
|
||||||
|
|
|
@ -24,7 +24,9 @@ public:
|
||||||
Script* ScriptPtr = nullptr;
|
Script* ScriptPtr = nullptr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override { scripts.Append(&ScriptPtr); }
|
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override {
|
||||||
|
scripts.Append(ScriptWrapper::FromScript(&ScriptPtr));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScriptSourceWithScriptSet : public ScriptSource {
|
class ScriptSourceWithScriptSet : public ScriptSource {
|
||||||
|
@ -32,7 +34,9 @@ public:
|
||||||
ScriptSet Set;
|
ScriptSet Set;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override { scripts.Append(&Set); }
|
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override {
|
||||||
|
scripts.Append(ScriptWrapper::FromSet(&Set));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE("Script source with unset script ptr.", "[Battling, Scripting]") {
|
TEST_CASE("Script source with unset script ptr.", "[Battling, Scripting]") {
|
||||||
|
@ -75,7 +79,7 @@ TEST_CASE("Script source with single item script set.", "[Battling, Scripting]")
|
||||||
auto s = new TestScript("foobar");
|
auto s = new TestScript("foobar");
|
||||||
source.Set.Add(s);
|
source.Set.Add(s);
|
||||||
auto scripts = source.GetScriptIterator();
|
auto scripts = source.GetScriptIterator();
|
||||||
auto first = scripts.GetNext();
|
auto first = scripts.GetNextNotNull();
|
||||||
CHECK(first != nullptr);
|
CHECK(first != nullptr);
|
||||||
CHECK(first->GetName() == "foobar");
|
CHECK(first->GetName() == "foobar");
|
||||||
}
|
}
|
||||||
|
@ -87,11 +91,11 @@ TEST_CASE("Script source with multiple item script set.", "[Battling, Scripting]
|
||||||
source.Set.Add(s);
|
source.Set.Add(s);
|
||||||
source.Set.Add(s2);
|
source.Set.Add(s2);
|
||||||
auto scripts = source.GetScriptIterator();
|
auto scripts = source.GetScriptIterator();
|
||||||
auto first = scripts.GetNext();
|
auto first = scripts.GetNextNotNull();
|
||||||
CHECK(first != nullptr);
|
REQUIRE(first != nullptr);
|
||||||
CHECK(first->GetName() == "foobar");
|
CHECK(first->GetName() == "foobar");
|
||||||
auto second = scripts.GetNext();
|
auto second = scripts.GetNextNotNull();
|
||||||
CHECK(second != nullptr);
|
REQUIRE(second != nullptr);
|
||||||
CHECK(second->GetName() == "foobar2");
|
CHECK(second->GetName() == "foobar2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue