#include "PipeLine.h" #include "logger.h" PipeMaterial::PipeMaterial() : type(PMT__FIRST), buffer(nullptr), buffSize(0), former(nullptr), deleter(nullptr), args(nullptr) { } void PipeMaterial::exec_deleter() { if (deleter != nullptr) { deleter(this); deleter = nullptr; } } PipeLine::PipeLine() : global_params_map(), elem_create_func_map(), elems() { } PipeLine::~PipeLine() { // pipe stop for(elem_vec_t::iterator iter = elems.begin(); iter != elems.end(); ++iter) { PipeLineElem* elem = *iter; if (elem != nullptr) { elem->finit(); delete *iter; } } elems.clear(); } bool PipeLine::register_elem_creator(const std::string& type, elem_create_func_t func) { if (type.empty() || func == nullptr) return false; elem_create_func_map_t::iterator iter = elem_create_func_map.find(type); if (iter != elem_create_func_map.end()) return false; elem_create_func_map.insert(std::make_pair(type, func)); return true; } void PipeLine::push_elem(PipeLineElem* elem) { if(elem != nullptr) { elem->manager = this; elems.push_back(elem); } } PipeLineElem* PipeLine::push_elem(const std::string& type) { elem_create_func_map_t::iterator iter = elem_create_func_map.find(type); if (iter == elem_create_func_map.end()) return nullptr; elem_create_func_t func = iter->second; if (func == nullptr) return nullptr; PipeLineElem* elem = func(); if (elem == nullptr) return nullptr; elem->manager = this; push_elem(elem); return elem; } class PipeDebugger { private: PipeLine* pipeLine; public: PipeLineElem* retElem; PipeMaterial* pm; PipeDebugger(PipeLine* _pipeLine) : pipeLine(_pipeLine), retElem(nullptr), pm(nullptr) { LOG(DEBUG) << "pipe line begin"; } ~PipeDebugger() { bool retOK = (*(pipeLine->elems).rbegin() == retElem); if (retOK) LOG(DEBUG) << "pipe line end, ret OK"; else LOG(WARN) << "pipe line end, ret ERROR"; } }; PipeLineElem* PipeLine::pipe(PipeMaterial* pm /*= nullptr*/) { PipeDebugger debugger(this); PipeLineElem* elem_begin = *elems.begin(); PipeLineElem* elem_last = *elems.rbegin(); if (elems.empty() || elem_begin == nullptr || elem_last == nullptr) return nullptr; uint8_t pmPlacement[sizeof(PipeMaterial)]; if (pm == nullptr) pm = new (pmPlacement) PipeMaterial; debugger.pm = pm; if (elems.size() == 1) { elem_begin->gain(*pm); pm->exec_deleter(); return debugger.retElem = elem_begin; } else if (elems.size() == 2) { if (elem_begin->gain(*pm)) { elem_last->pay(*pm); pm->exec_deleter(); } else return debugger.retElem = elem_begin; return debugger.retElem = elem_last; } else { if (!elem_begin->gain(*pm)) return debugger.retElem = elem_begin; bool lastRet = true; elem_vec_t::iterator iter = elems.begin(); ++iter; elem_begin = *iter; while (elem_begin != elem_last) { if (lastRet && (lastRet = elem_begin->pay(*pm)) ) { pm->exec_deleter(); lastRet = elem_begin->gain(*pm); } else return debugger.retElem = elem_begin; ++iter; elem_begin = *iter; } if (lastRet) { elem_last->pay(*pm); pm->exec_deleter(); } return debugger.retElem = elem_last; } return nullptr; } void PipeLine::set_global_param(const std::string& name, const std::string& value) { if (name.empty()) return; global_params_map_t::iterator iter = global_params_map.find(name); if (iter == global_params_map.end()) global_params_map.insert(std::make_pair(name, value)); else iter->second = value; } std::string PipeLine::get_global_param(const std::string& name) const { global_params_map_t::const_iterator iter = global_params_map.find(name); if (iter == global_params_map.end()) return ""; else return iter->second; }