CreatureLib/src/Battling/ScriptHandling/ScriptAggregator.hpp

68 lines
2.3 KiB
C++
Raw Normal View History

2019-11-09 11:15:45 +00:00
#ifndef CREATURELIB_SCRIPTAGGREGATOR_HPP
#define CREATURELIB_SCRIPTAGGREGATOR_HPP
#include <any>
#include <queue>
#include "Script.hpp"
#include "ScriptSet.hpp"
#include "../../Core/Exceptions/NotReachableException.hpp"
#include "ScriptWrapper.hpp"
2019-11-09 11:15:45 +00:00
namespace CreatureLib::Battling{
class ScriptAggregator{
__gnu_cxx::__normal_iterator<ScriptWrapper *, std::vector<ScriptWrapper>> _selfIterator;
__gnu_cxx::__normal_iterator<ScriptWrapper *, std::vector<ScriptWrapper>> _selfEnd;
2019-11-09 11:15:45 +00:00
bool _isSetSet = false;
std::__detail::_Node_const_iterator<std::pair<const std::string, Script *>, false, true> _setIterator;
std::__detail::_Node_const_iterator<std::pair<const std::string, Script *>, false, true> _setEnd;
2019-11-09 11:15:45 +00:00
public:
ScriptAggregator(std::vector<ScriptWrapper> scripts){
_selfIterator = scripts.begin();
_selfEnd = scripts.end();
};
2019-11-09 11:15:45 +00:00
bool HasNext(){
2019-11-10 18:55:01 +00:00
return _selfIterator != _selfEnd || (_isSetSet && _setIterator != _setEnd);
2019-11-09 11:15:45 +00:00
}
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 (_selfIterator == _selfEnd)
2019-11-09 11:15:45 +00:00
return nullptr;
auto next = *_selfIterator;
2019-11-10 18:55:01 +00:00
_selfIterator++;
if (!next.IsSet()){
auto scriptPtr = next.GetScript();
if (scriptPtr == nullptr)
return GetNext();
return *scriptPtr;
2019-11-09 11:15:45 +00:00
}
else{
auto set = next.GetScriptSet();
2019-11-09 11:15:45 +00:00
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