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