#ifndef CREATURELIB_SCRIPTAGGREGATOR_HPP #define CREATURELIB_SCRIPTAGGREGATOR_HPP #include #include #include "Script.hpp" #include "ScriptSet.hpp" namespace CreatureLib::Battling{ class ScriptAggregator{ std::queue _queue; bool _isSetSet = false; std::__detail::_Node_iterator, false, true> _setIterator; std::__detail::_Node_iterator, false, true> _setEnd; public: ScriptAggregator() = default; void Add(Script* script){ _queue.push(script); } void Add(ScriptSet* scriptSet){ _queue.push(scriptSet); } bool HasNext(){ return !_queue.empty() || _isSetSet; } Script* GetNext(){ // We can probably do this in a cleaner version once C++ 20 drops with Coroutine support. if (_isSetSet){ if (_setIterator == _setEnd){ _isSetSet = false; return GetNext(); } auto s = _setIterator->second; _setIterator.operator++(); if (_setIterator == _setEnd){ _isSetSet = false; } return s; } if (_queue.empty()) return nullptr; auto next = _queue.front(); _queue.pop(); if (next.type() == typeid(Script*)){ return std::any_cast(next); } else{ auto set = std::any_cast(next); if (set->Count() == 0) return GetNext(); auto it = set->GetIterator(); _setIterator = it->begin(); _setEnd = it->end(); _isSetSet = true; return GetNext(); } throw NotReachableException(); } }; } #endif //CREATURELIB_SCRIPTAGGREGATOR_HPP