114 using RequestType = Request;
115 using ResponseType = Response;
124 template<
class... Args>
125 Pipeline(Args&&... args) : _default_response(std::forward<Args>(args)...)
136 template <
typename T,
typename ...Args>
139 std::unique_ptr<T> handler = std::make_unique<T>(std::forward<Args>(args)...);
144 _pipes.push_back(std::move(handler));
147 _pipes_by_name[name] = _pipes.back().get();
160 for (
auto& it : _pipes)
171 for (
auto it = _pipes.rbegin(); it != _pipes.rend(); ++it)
178 Response
run(
const Request&& request)
181 assert(!_last_step_pipe);
183 if (_pipes.size() > 0)
185 if constexpr (TopToBottom)
187 return _pipes.front()->handle(std::move(request));
191 return _pipes.back()->handle(std::move(request));
196 return _default_response;
199 Response getDefaultResponse() {
return _default_response; }
206 template<
class... Types>
209 _default_response = {args...};
212 template <
typename T>
213 T* getPipeByName(
const std::string& name)
215 return static_cast<T*
>(_pipes_by_name[name]);
218 void enableStepByStepMode()
220 _last_step_pipe.emplace(0);
222 for (
auto it = _pipes.begin(); it != _pipes.end(); ++it)
224 (*it)->_next_handler =
nullptr;
228 void disableStepByStepMode()
230 _last_step_pipe.reset();
234 bool isStepByStepMode()
236 return (
bool)_last_step_pipe;
239 std::pair<Response, bool> step(
const Request&& request)
242 assert(_last_step_pipe);
244 PipeHandler* pipe = _pipes[*_last_step_pipe].get();
246 ++(*_last_step_pipe);
248 bool has_more_pipes = _last_step_pipe < _pipes.size();
251 *_last_step_pipe = 0;
253 return {pipe->handle(std::move(request)), has_more_pipes};
257 std::vector<std::unique_ptr<PipeHandler>> _pipes;
258 Response _default_response;
260 std::map<std::string, PipeHandler*> _pipes_by_name;
262 std::optional<int32_t> _last_step_pipe = std::nullopt;
264 void _rebuildPipeOrder()
266 if constexpr (TopToBottom)
268 PipeHandler* last_handler = _pipes.back().get();
269 last_handler->_next_handler =
nullptr;
271 for (
auto it = _pipes.rbegin()+1; it != _pipes.rend(); ++it)
273 (*it)->_next_handler = last_handler;
274 last_handler = it->get();
279 PipeHandler* last_handler = _pipes.front().get();
281 last_handler->_next_handler = _pipes.size() > 1
282 ? (_pipes.begin() + 1)->get()
286 for (
auto it = _pipes.begin()+1; it != _pipes.end(); ++it)
288 (*it)->_next_handler = last_handler;
289 last_handler = it->get();