#ifndef IN_OUT_INTERFACE_H #define IN_OUT_INTERFACE_H #include #include #include #include #include #include #define ADD_INPUT(name,ComponentType, DataType, functionName) input.insert(name,new InputInterface (name,this,&ComponentType::functionName)) #define ADD_OUTPUT(name,ComponentType, DataType) output.insert(name,new OutputInterface (name,this)) #define GET_OUTPUT(name,ComponentType, DataType) dynamic_cast *> (output.value(name)) namespace pacpus { template class InputInterface : public InputInterfaceBase { public: InputInterface(QString name, C * component, void (C::*m)(const T&)):InputInterfaceBase(name,component,component), method(m) {} ~InputInterface() {} size_t getDataSize() {return sizeof(T);} QString getDataType() {return QString(typeid(T).name());} protected: int boundingTime_; public: PacpusEvent getEventTemplate() {return PacpusTypedEvent(TYPED_EVENT); } void customEvent(QEvent* event) { switch (event->type()) { // from Component to Component (T->T) case TYPED_EVENT: { PacpusTypedEvent * typedEvent = dynamic_cast *> (event); //qDebug() << "E1 "; //qDebug() << "recived 2 thread " << QThread::currentThread(); if(typedEvent->tr_ == 0 && readingMode_ == TimeBounded) { //LOG_WARN("Incorrect TimeRange (0), switch to NeverSkip"); readingMode_ = NeverSkip;} switch (readingMode_){ case TimeBounded: qDebug() << "Input " << this->getSignature() << " Time bournded "<< road_time()- typedEvent->t_ << " " << typedEvent->tr_; if(road_time() - typedEvent->t_> typedEvent->tr_) { qDebug() << "Data skip " << this->getSignature(); break;} (dynamic_cast(_component)->*method)(typedEvent->_data); break; case GetLast: qDebug() << "Input " << this->getSignature() << "GetLast "<< road_time() - typedEvent->t_ << " " << typedEvent->tr_; (dynamic_cast(_component)->*method)(typedEvent->_data); QCoreApplication::removePostedEvents(this,TYPED_EVENT); // delete all remining events break; case NeverSkip: qDebug() << "Input " << this->getSignature() << "NeverSkip "<< road_time() - typedEvent->t_ << " " << typedEvent->tr_; default: (dynamic_cast(_component)->*method)(typedEvent->_data); } break; } // from Connection interface to Component (G->T) /* case GENERIC_EVENT2: { PacpusTypedEvent * genericEvent = dynamic_cast *> (event); T data; QByteArray& buf = (QByteArray&) genericEvent->_data; QDataStream in(&buf,QIODevice::ReadOnly); (dynamic_cast(_component)->*method)(data); // copy 8 X break; } // from Component to Connection interface (T->G) (Typed in QByteArray) case GENERIC_EVENT3: { PacpusTypedEvent * typedEvent = dynamic_cast *> (event); (dynamic_cast(_component)->*method)(typedEvent->_data); // copy 3 X break; }*/ default: qDebug() << "Unknown event ID " << event->type(); break; } } protected: void (C::*method)(const T&); }; template class OutputInterface : public OutputInterfaceBase { public: OutputInterface(QString name, C * component):OutputInterfaceBase(name,component,component) {} ~OutputInterface() {} // Used by Components to send data througth typed output void send(const T & data, road_time_t t = road_time(), road_timerange_t tr = 0) { for(QList::iterator it = _connection.begin(); it!=_connection.end(); ++it){ //if(it->getInterface()->getDataType() != QString(typeid(QByteArray).name())) QApplication::postEvent(it->getInterface(),new PacpusTypedEvent(TYPED_EVENT,data,t,tr),it->getPriority()); /*else { QByteArray buf; QDataStream out(&buf,QIODevice::ReadWrite); PacpusTypedEvent * ev =new PacpusTypedEvent(GENERIC_EVENT3,buf); QApplication::postEvent(it->getInterface(),ev,it->getPriority()); // Copy 2 (ctor) }*/ } } // Used by Connection Interfaces only to pose generic event /* void sendGenericData(char * data, size_t size) { QByteArray buf(data,size); // copy 5 for(QList::iterator it = _connection.begin(); it!=_connection.end(); ++it) QApplication::postEvent(it->getInterface(),new PacpusTypedEvent(GENERIC_EVENT2,buf),it->getPriority()); // Copy 6(ctor) } */ size_t getDataSize() {return sizeof(T);} QString getDataType() {return QString(typeid(T).name());} }; } // namespace pacpus #endif // IN_OUT_INTERFACE_H