CreatureLib/src/Battling/ScriptHandling/ScriptAggregator.hpp

62 lines
2.0 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 "../../Library/Exceptions/NotReachableException.hpp"
2019-11-09 11:15:45 +00:00
#include "Script.hpp"
#include "ScriptSet.hpp"
#include "ScriptWrapper.hpp"
2019-11-09 11:15:45 +00:00
namespace CreatureLib::Battling {
class ScriptAggregator {
2019-11-11 19:04:59 +00:00
std::vector<ScriptWrapper> _scripts;
size_t _index = 0;
2019-11-09 11:15:45 +00:00
bool _isSetSet = false;
const std::vector<Script*>* _setScripts;
size_t _setIndex;
2019-11-09 11:15:45 +00:00
public:
ScriptAggregator(std::vector<ScriptWrapper> scripts) : _scripts(std::move(scripts)){};
2019-11-09 11:15:45 +00:00
bool HasNext() { return _index < _scripts.size() || (_isSetSet && _setIndex < _setScripts->size()); }
2019-11-09 11:15:45 +00:00
Script* GetNext() {
2019-11-09 11:15:45 +00:00
// We can probably do this in a cleaner version once C++ 20 drops with Coroutine support.
if (_isSetSet) {
if (_setIndex >= _setScripts->size()) {
2019-11-09 11:15:45 +00:00
_isSetSet = false;
return GetNext();
}
auto s = _setScripts->at(_setIndex);
_setIndex++;
if (_setIndex >= _setScripts->size()) {
2019-11-09 11:15:45 +00:00
_isSetSet = false;
}
return s;
}
2019-11-11 19:04:59 +00:00
if (_index >= _scripts.size())
2019-11-09 11:15:45 +00:00
return nullptr;
2019-11-11 19:04:59 +00:00
auto next = _scripts[_index];
_index++;
if (!next.IsSet()) {
auto scriptPtr = next.GetScript();
if (scriptPtr == nullptr)
return GetNext();
return *scriptPtr;
} else {
auto set = next.GetScriptSet();
2019-11-09 11:15:45 +00:00
if (set->Count() == 0)
return GetNext();
_setScripts = set->GetIterator();
2019-11-09 11:15:45 +00:00
_isSetSet = true;
_setIndex = 0;
2019-11-09 11:15:45 +00:00
return GetNext();
}
throw NotReachableException();
}
};
}
#endif // CREATURELIB_SCRIPTAGGREGATOR_HPP