CreatureLib/src/Battling/ScriptHandling/ScriptAggregator.hpp

73 lines
2.1 KiB
C++

#ifndef CREATURELIB_SCRIPTAGGREGATOR_HPP
#define CREATURELIB_SCRIPTAGGREGATOR_HPP
#include "Script.hpp"
#include "ScriptSet.hpp"
#include "ScriptWrapper.hpp"
namespace CreatureLib::Battling {
class ScriptAggregator {
const ScriptWrapper* _scripts;
size_t _size;
size_t _index = 0;
size_t _setIndex = 0;
inline void IncrementToNextNotNull(bool initialIncrement = true) {
if (_scripts[_index].IsSet()) {
_setIndex++;
if (_setIndex >= _scripts[_index].GetScriptSet()->Count()) {
_setIndex = 0;
} else {
return;
}
}
if (initialIncrement)
_index++;
while (HasNext()) {
if (_scripts[_index].HasValue()) {
return;
}
_index++;
}
}
public:
ScriptAggregator(){};
explicit ScriptAggregator(const ArbUt::List<ScriptWrapper>& scripts)
: _scripts(scripts.RawData()), _size(scripts.Count()){};
inline void Reset() {
_index = 0;
if (_scripts[_index].IsSet()) {
_setIndex = -1;
}
IncrementToNextNotNull(false);
}
inline bool HasNext() { return _index < _size; }
std::optional<ArbUt::BorrowedPtr<Script>> GetNextNotNull() {
while (HasNext()) {
auto s = GetNext();
return s;
}
return {};
}
ArbUt::BorrowedPtr<Script> GetNext() {
auto& current = _scripts[_index];
if (!current.IsSet()) {
auto s = current.GetScript();
IncrementToNextNotNull();
return (*s);
} else {
auto& set = current.GetScriptSet()->GetIterator();
auto v = set[_setIndex];
IncrementToNextNotNull();
return v;
}
}
};
}
#endif // CREATURELIB_SCRIPTAGGREGATOR_HPP