#include "rapidPiPoHost.h" //===================== P I P O = H O S T = U T I L S ========================// static const unsigned int maxWordLen = 256; static bool getPiPoInstanceAndAttrName(const char *attrName, char *instanceName, char *pipoAttrName) { const char *dot = std::strrchr(attrName, '.'); if (dot != NULL) { unsigned int pipoAttrNameLen = dot - attrName; std::strcpy(pipoAttrName, dot + 1); if (pipoAttrNameLen > maxWordLen) { pipoAttrNameLen = maxWordLen; } std::strncpy(instanceName, attrName, pipoAttrNameLen); instanceName[pipoAttrNameLen] = '\0'; return true; } return false; } static void fromPiPoStreamAttributes(PiPoStreamAttributes &src, pipoStreamAttributes &dst) { unsigned int numCols = src.dims[0]; unsigned int numLabels = src.numLabels; if (numLabels > PIPO_MAX_LABELS) { numLabels = PIPO_MAX_LABELS; } if (numLabels > numCols) { numLabels = numCols; } dst.hasTimeTags = src.hasTimeTags; if (src.rate <= MIN_PIPO_SAMPLERATE) { dst.rate = MIN_PIPO_SAMPLERATE; } else if (src.rate >= MAX_PIPO_SAMPLERATE) { dst.rate = MAX_PIPO_SAMPLERATE; } else { dst.rate = src.rate; } dst.rate = src.rate; dst.offset = src.offset; dst.dims = { src.dims[0], src.dims[1] }; dst.labels = std::vector<std::string>(); for (unsigned int i = 0; i < numLabels; ++i) { dst.labels.push_back(std::string(src.labels[i])); } dst.hasVarSize = src.hasVarSize; dst.domain = src.domain; dst.maxFrames = src.maxFrames; } static void toPiPoStreamAttributes(pipoStreamAttributes &src, PiPoStreamAttributes &dst) { const char *labs[src.labels.size()]; for (unsigned int i = 0; i < src.labels.size(); ++i) { labs[i] = labels[i].c_str(); } dst = PiPoStreamAttributes( src.hasTimeTags, src.rate, src.offset, { src.dims[0], src.dims[1] }, &labs[0], src.hasVarSize, src.domain; src.maxFrames ); } //========================= H O S T = M E T H O D S ==========================// PiPoHost::PiPoHost() : inputStreamAttrs(PIPO_MAX_LABELS), outputStreamAttrs(PIPO_MAX_LABELS) { PiPoCollection::init(); this->out = new PiPoOut(this); this->graph = nullptr; } PiPoHost::~PiPoHost() { if (this->graph != nullptr) { delete this->graph; } delete this->out; } bool PiPoHost::setPiPoGraph(std::string name) { if (this->graph != nullptr) { delete this->graph; } this->graph = PiPoCollection::create(name); if (this->graph != NULL) { this->graphName = name; this->graph->connect((PiPo *)this->out); return true; } this->graph = nullptr; this->graphName = "undefined"; return false; } void PiPoHost::clearPiPoGraph() { if (this->graph != nullptr) { delete this->graph; this->graph = nullptr; } } void PiPoHost::onNewFrameOut(double time, std::vector<PiPoValue> &frame) { std::cout << time << std::endl; std::cout << "please override this method" << std::endl; } std::vector<PiPoValue> PiPoHost::getLastFrameOut() { return this->out->getLastFrame(); } void PiPoHost::setInputStreamAttributes(pipoStreamAttributes &sa, bool propagate) { toPiPoStreamAttributes(sa, inputStreamAttrs); if (propagate) { this->propagateInputStreamAttributes(); } } pipoStreamAttributes PiPoHost::getOutputStreamAttributes() { pipoStreamAttributes sa; return fromPiPoStreamAttributes(this->outputStreamAttrs, sa); } int PiPoHost::frames(double time, double weight, PiPoValue *values, unsigned int size, unsigned int num) { return this->graph->frames(time, weight, values, size, num); } // bool // setAttr(const std::string &attrName, bool value) // { // } // bool // setAttr(const std::string &attrName, int value) // { // } bool setAttr(const std::string &attrName, double value) { PiPo::Attr *attr = this->graph->getAttr(attrName.c_str()); if (attr != NULL) { int iAttr = attr->getIndex(); return this->pipo->setAttr(iAttr, value); } return false; } bool setAttr(const std::string &attrName, const std::vector<double> &values) { PiPo::Attr *attr = this->pipo->getAttr(attrName.c_str()); if (attr != NULL) { int iAttr = attr->getIndex(); double vals[values.size()]; unsigned int i = 0; for (auto &value : values) { vals[i] = value; i++; } return this->pipo->setAttr(iAttr, &vals[0], values.size()); } return false; } bool setAttr(const std::string &attrName, const std::string &value) // for enums { PiPo::Attr *attr = this->pipo->getAttr(attrName.c_str()); if (attr != NULL) { int iAttr = attr->getIndex(); PiPo::Type type = attr->getType(); if (type == PiPo::Type::Enum) { std::vector<const char *> *list = attr->getEnumList(); for (int i = 0; i < list->size(); i++) { if (strcmp(list->at(i), value.c_str()) == 0) { attr->set(0, i); return true; } } } } return false; } void PiPoHost::propagateInputStreamAttributes() { if (this->graph != nullptr) { this->graph->streamAttributes(this->inputStreamAttrs.hasTimeTags, this->inputStreamAttrs.rate, this->inputStreamAttrs.offset, this->inputStreamAttrs.dims[0], this->inputStreamAttrs.dims[1], this->inputStreamAttrs.labels, this->inputStreamAttrs.hasVarSize, this->inputStreamAttrs.domain, this->inputStreamAttrs.maxFrames); } } // void // PiPoHost::streamAttributesChanged(PiPo *pipo, PiPo::Attr *attr) { // this->propagateInputAttributes(); // } // void // PiPoHost::signalError(PiPo *pipo, std::string errorMsg) { // // todo // } // void // PiPoHost::signalWarning(PiPo *pipo, std::string warningMsg) { // // todo // } //--------------------- INPUT STREAM ATTRIBUTES SETTERS ----------------------// /* void PiPoHost::setInputHasTimeTags(bool hasTimeTags, bool propagate) { this->inputStreamAttrs.hasTimeTags = hasTimeTags; if (propagate) { this->propagateInputAttributes(); } } #define MIN_PIPO_SAMPLERATE (1.0 / 31536000000.0) // once a year #define MAX_PIPO_SAMPLERATE (96000000000.0) void PiPoHost::setInputFrameRate(double rate, bool propagate) { if (rate <= MIN_PIPO_SAMPLERATE) { this->inputStreamAttrs.rate = MIN_PIPO_SAMPLERATE; } else if (rate >= MAX_PIPO_SAMPLERATE) { this->inputStreamAttrs.rate = MAX_PIPO_SAMPLERATE; } else { this->inputStreamAttrs.rate = rate; } if (propagate) { this->propagateInputAttributes(); } } void PiPoHost::setInputFrameOffset(double offset, bool propagate) { this->inputStreamAttrs.offset = offset; if (propagate) { this->propagateInputAttributes(); } } void PiPoHost::setInputDims(int width, int height, bool propagate) { this->inputStreamAttrs.dims[0] = width; this->inputStreamAttrs.dims[1] = height; if (propagate) { this->propagateInputAttributes(); } } void PiPoHost::setInputLabels(const std::vector<std::string> &labels, bool propagate) { const char *labs[labels.size()]; for (unsigned int i = 0; i < labels.size(); ++i) { labs[i] = labels[i].c_str(); } this->inputStreamAttrs.labels = &labs[0]; if (propagate) { this->propagateInputAttributes(); } } void PiPoHost::setInputHasVarSize(bool hasVarSize, bool propagate) { this->inputStreamAttrs.hasVarSize = hasVarSize; if (propagate) { this->propagateInputAttributes(); } } void PiPoHost::setInputDomain(double domain, bool propagate) { this->inputStreamAttrs.domain = domain; if (propagate) { this->propagateInputAttributes(); } } void PiPoHost::setInputMaxFrames(int maxFrames, bool propagate) { this->inputStreamAttrs.maxFrames = maxFrames; if (propagate) { this->propagateInputAttributes(); } } //--------------------- INPUT STREAM ATTRIBUTES GETTERS ----------------------// bool PiPoHost::getInputHasTimeTags() { return this->inputStreamAttrs.hasTimeTags; } double PiPoHost::getInputFrameRate() { return this->inputStreamAttrs.rate; } double PiPoHost::getInputFrameOffset() { return this->inputStreamAttrs.offset; } void PiPoHost::getInputDims(int &width, int &height) { width = this->inputStreamAttrs.dims[0]; height = this->inputStreamAttrs.dims[1]; } void PiPoHost::getInputLabels(std::vector<std::string> &labels) { //for (unsigned int i = 0; i < ) } bool PiPoHost::getInputHasVarSize() { return this->inputStreamAttrs.hasVarSize; } double PiPoHost::getInputDomain() { return this->inputStreamAttrs.domain; } int PiPoHost::getInputMaxFrames() { return this->inputStreamAttrs.maxFrames; } //*/ //--------------------- OUTPUT STREAM ATTRIBUTES GETTERS ---------------------// void PiPoHost::setOutputAttributes(bool hasTimeTags, double rate, double offset, unsigned int width, unsigned int height, const char **labels, bool hasVarSize, double domain, unsigned int maxFrames) { if (labels != NULL) { int numLabels = width; if (numLabels > PIPO_MAX_LABELS) { numLabels = PIPO_MAX_LABELS; } for (unsigned int i = 0; i < numLabels; i++) { try { this->outputStreamAttrs.labels[i] = labels[i]; } catch(std::exception e) { this->outputStreamAttrs.labels[i] = "unnamed"; } } this->outputStreamAttrs.numLabels = numLabels; } else { this->outputStreamAttrs.numLabels = 0; } this->outputStreamAttrs.hasTimeTags = hasTimeTags; this->outputStreamAttrs.rate = rate; this->outputStreamAttrs.offset = offset; this->outputStreamAttrs.dims[0] = width; this->outputStreamAttrs.dims[1] = height; this->outputStreamAttrs.hasVarSize = hasVarSize; this->outputStreamAttrs.domain = domain; this->outputStreamAttrs.maxFrames = maxFrames; } bool PiPoHost::getOutputHasTimeTags() { return this->outputStreamAttrs.hasTimeTags; } double PiPoHost::getOutputFrameRate() { return this->outputStreamAttrs.rate; } double PiPoHost::getOutputFrameOffset() { return this->outputStreamAttrs.offset; } void PiPoHost::getOutputDims(int &width, int &height) { width = this->outputStreamAttrs.dims[0]; height = this->outputStreamAttrs.dims[1]; } void PiPoHost::getOutputLabels(std::vector<std::string> &labels) { labels.clear(); for (unsigned int i = 0; this->outputStreamAttrs.numLabels; ++i) { if (this->outputStreamAttrs.labels[i] != NULL) { labels.push_back(std::string(this->outputStreamAttrs.labels[i])); } else { labels.push_back("unnamed"); } } } bool PiPoHost::getOutputHasVarSize() { return this->outputStreamAttrs.hasVarSize; } double PiPoHost::getOutputDomain() { return this->outputStreamAttrs.domain; } int PiPoHost::getOutputMaxFrames() { return this->outputStreamAttrs.maxFrames; } //===================== PIPO HOST CLASS IMPLEMENTATION =======================// rapidPiPoHost::rapidPiPoHost(rapidPiPoOwner *rpo) : owner(rpo), inputStreamAttrs(PIPO_MAX_LABELS), outputStreamAttrs(PIPO_MAX_LABELS) { PiPoCollection::init(); outputter = new rapidPiPoOutputter(this); chain = nullptr; } rapidPiPoHost::~rapidPiPoHost() { if (chain != nullptr) { delete chain; } delete outputter; } rapidPiPoOwner * rapidPiPoHost::getOwner() { return owner; } void rapidPiPoHost::onNewFrame(double time, std::vector<PiPoValue> &frame) { std::cout << time << std::endl; owner->onNewFrame(frame); } // void // rapidPiPoHost::onNewFrame(const std::function<void(std::vector<PiPoValue>, // rapidPiPoOwner *rpo)> cb) { // outputter->setFrameCallback(cb); // } // void // rapidPiPoHost::onNewFrame(std::function<void(std::vector<PiPoValue>)> cb) { // outputter->setSimpleFrameCallback(cb); // } std::vector<PiPoValue> rapidPiPoHost::getLastFrame() { return outputter->getLastFrame(); } rapidPiPo * rapidPiPoHost::setPiPoChain(std::string name) { if (chain != nullptr) { delete chain; } chain = new rapidPiPo(name); chain->connect((PiPo *)outputter); return chain; } void rapidPiPoHost::clearPiPoChain() { delete chain; chain = nullptr; } void rapidPiPoHost::propagateInputAttributes() { if (chain != nullptr) { const char *colNameStr[PIPO_MAX_LABELS]; unsigned int numCols = this->inputStreamAttrs.dims[0]; unsigned int numLabels = this->inputStreamAttrs.numLabels; if (numLabels > PIPO_MAX_LABELS) { numLabels = PIPO_MAX_LABELS; } if (numLabels > numCols) { numLabels = numCols; } std::vector<std::string> labels(numLabels); if (numLabels > 0) { for (unsigned int i = 0; i < numLabels; i++) { colNameStr[i] = this->inputStreamAttrs.labels[i]; } for (unsigned int i = numLabels; i < numCols; i++) { colNameStr[i] = "unnamed"; } for (unsigned int i = 0; i < numCols; ++i) { labels[i] = std::string(colNameStr[i]); } } chain->streamAttributes(this->inputStreamAttrs.hasTimeTags, this->inputStreamAttrs.rate, this->inputStreamAttrs.offset, this->inputStreamAttrs.dims[0], this->inputStreamAttrs.dims[1], labels, this->inputStreamAttrs.hasVarSize, this->inputStreamAttrs.domain, this->inputStreamAttrs.maxFrames); } } // void // rapidPiPoHost::streamAttributesChanged(PiPo *pipo, PiPo::Attr *attr) { // this->propagateInputAttributes(); // } // void // rapidPiPoHost::signalError(PiPo *pipo, std::string errorMsg) { // // todo // } // void // rapidPiPoHost::signalWarning(PiPo *pipo, std::string warningMsg) { // // todo // } //--------------------- INPUT STREAM ATTRIBUTES SETTERS ----------------------// void rapidPiPoHost::setInputHasTimeTags(bool hasTimeTags, bool propagate) { this->inputStreamAttrs.hasTimeTags = hasTimeTags; if (propagate) { this->propagateInputAttributes(); } } #define MIN_PIPO_SAMPLERATE (1.0 / 31536000000.0) /* once a year */ #define MAX_PIPO_SAMPLERATE (96000000000.0) void rapidPiPoHost::setInputFrameRate(double rate, bool propagate) { if (rate <= MIN_PIPO_SAMPLERATE) { this->inputStreamAttrs.rate = MIN_PIPO_SAMPLERATE; } else if (rate >= MAX_PIPO_SAMPLERATE) { this->inputStreamAttrs.rate = MAX_PIPO_SAMPLERATE; } else { this->inputStreamAttrs.rate = rate; } if (propagate) { this->propagateInputAttributes(); } } void rapidPiPoHost::setInputFrameOffset(double offset, bool propagate) { this->inputStreamAttrs.offset = offset; if (propagate) { this->propagateInputAttributes(); } } void rapidPiPoHost::setInputDims(int width, int height, bool propagate) { this->inputStreamAttrs.dims[0] = width; this->inputStreamAttrs.dims[1] = height; if (propagate) { this->propagateInputAttributes(); } } void rapidPiPoHost::setInputLabels(const std::vector<std::string> &labels, bool propagate) { const char *labs[labels.size()]; for (unsigned int i = 0; i < labels.size(); ++i) { labs[i] = labels[i].c_str(); } this->inputStreamAttrs.labels = &labs[0]; if (propagate) { this->propagateInputAttributes(); } } void rapidPiPoHost::setInputHasVarSize(bool hasVarSize, bool propagate) { this->inputStreamAttrs.hasVarSize = hasVarSize; if (propagate) { this->propagateInputAttributes(); } } void rapidPiPoHost::setInputDomain(double domain, bool propagate) { this->inputStreamAttrs.domain = domain; if (propagate) { this->propagateInputAttributes(); } } void rapidPiPoHost::setInputMaxFrames(int maxFrames, bool propagate) { this->inputStreamAttrs.maxFrames = maxFrames; if (propagate) { this->propagateInputAttributes(); } } //--------------------- INPUT STREAM ATTRIBUTES GETTERS ----------------------// bool rapidPiPoHost::getInputHasTimeTags() { return this->inputStreamAttrs.hasTimeTags; } double rapidPiPoHost::getInputFrameRate() { return this->inputStreamAttrs.rate; } double rapidPiPoHost::getInputFrameOffset() { return this->inputStreamAttrs.offset; } void rapidPiPoHost::getInputDims(int &width, int &height) { width = this->inputStreamAttrs.dims[0]; height = this->inputStreamAttrs.dims[1]; } void rapidPiPoHost::getInputLabels(std::vector<std::string> &labels) { //for (unsigned int i = 0; i < ) } bool rapidPiPoHost::getInputHasVarSize() { return this->inputStreamAttrs.hasVarSize; } double rapidPiPoHost::getInputDomain() { return this->inputStreamAttrs.domain; } int rapidPiPoHost::getInputMaxFrames() { return this->inputStreamAttrs.maxFrames; } //--------------------- OUTPUT STREAM ATTRIBUTES GETTERS ---------------------// void rapidPiPoHost::setOutputAttributes(bool hasTimeTags, double rate, double offset, unsigned int width, unsigned int height, const char **labels, bool hasVarSize, double domain, unsigned int maxFrames) { if (labels != NULL) { int numLabels = width; if (numLabels > PIPO_MAX_LABELS) { numLabels = PIPO_MAX_LABELS; } for (unsigned int i = 0; i < numLabels; i++) { try { this->outputStreamAttrs.labels[i] = labels[i]; } catch(std::exception e) { this->outputStreamAttrs.labels[i] = "unnamed"; } } this->outputStreamAttrs.numLabels = numLabels; } else { this->outputStreamAttrs.numLabels = 0; } this->outputStreamAttrs.hasTimeTags = hasTimeTags; this->outputStreamAttrs.rate = rate; this->outputStreamAttrs.offset = offset; this->outputStreamAttrs.dims[0] = width; this->outputStreamAttrs.dims[1] = height; this->outputStreamAttrs.hasVarSize = hasVarSize; this->outputStreamAttrs.domain = domain; this->outputStreamAttrs.maxFrames = maxFrames; } bool rapidPiPoHost::getOutputHasTimeTags() { return this->outputStreamAttrs.hasTimeTags; } double rapidPiPoHost::getOutputFrameRate() { return this->outputStreamAttrs.rate; } double rapidPiPoHost::getOutputFrameOffset() { return this->outputStreamAttrs.offset; } void rapidPiPoHost::getOutputDims(int &width, int &height) { width = this->outputStreamAttrs.dims[0]; height = this->outputStreamAttrs.dims[1]; } void rapidPiPoHost::getOutputLabels(std::vector<std::string> &labels) { labels.clear(); for (unsigned int i = 0; this->outputStreamAttrs.numLabels; ++i) { if (this->outputStreamAttrs.labels[i] != NULL) { labels.push_back(std::string(this->outputStreamAttrs.labels[i])); } else { labels.push_back("unnamed"); } } } bool rapidPiPoHost::getOutputHasVarSize() { return this->outputStreamAttrs.hasVarSize; } double rapidPiPoHost::getOutputDomain() { return this->outputStreamAttrs.domain; } int rapidPiPoHost::getOutputMaxFrames() { return this->outputStreamAttrs.maxFrames; } // void // rapidPiPoHost::setRapidPiPoParam(rapidPiPoParam *param) { // char instanceName[maxWordLen]; // char pipoAttrName[maxWordLen]; // if (getPiPoInstanceAndAttrName(param->getName(), instanceName, pipoAttrName)) { // // todo (or not todo) // } // } // void // rapidPiPoHost::getPiPoParams(std::vector<rapidPiPoParam> ¶ms) { // }