#ifndef CREATURELIB_SCRIPTAGGREGATOR_HPP #define CREATURELIB_SCRIPTAGGREGATOR_HPP #include #include #include "Script.hpp" #include "ScriptSet.hpp" #include "../../Core/Exceptions/NotReachableException.hpp" #include "ScriptWrapper.hpp" namespace CreatureLib::Battling{ class ScriptAggregator{ std::vector _scripts; int _index = 0; bool _isSetSet = false; const std::vector* _setScripts; int _setIndex; public: ScriptAggregator(std::vector scripts) : _scripts(std::move(scripts)){ }; bool HasNext(){ return _index < _scripts.size() || (_isSetSet && _setIndex < _setScripts->size()); } Script* GetNext(){ // We can probably do this in a cleaner version once C++ 20 drops with Coroutine support. if (_isSetSet){ if (_setIndex >= _setScripts->size()){ _isSetSet = false; return GetNext(); } auto s = _setScripts->at(_setIndex); _setIndex++; if (_setIndex >= _setScripts->size()){ _isSetSet = false; } return s; } if (_index >= _scripts.size()) return nullptr; auto next = _scripts[_index]; _index++; if (!next.IsSet()){ auto scriptPtr = next.GetScript(); if (scriptPtr == nullptr) return GetNext(); return *scriptPtr; } else{ auto set = next.GetScriptSet(); if (set->Count() == 0) return GetNext(); _setScripts = set->GetIterator(); _isSetSet = true; _setIndex = 0; return GetNext(); } throw NotReachableException(); } }; } #endif //CREATURELIB_SCRIPTAGGREGATOR_HPP