#ifndef IN_OUT_INTERFACE_H #define IN_OUT_INTERFACE_H #include #include #include #include #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() {} enum ReadingMode { NeverSkip, TimeBounded, GetLast }; void setReadingMode(ReadingMode mode) { readingMode_ = mode;} size_t getDataSize() {return sizeof(T);} QString getDataType() {return QString(typeid(T).name());} protected: ReadingMode readingMode_; int boundingTime_; public: 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: if(road_time() - typedEvent->t_> typedEvent->tr_) break; (dynamic_cast(_component)->*method)(typedEvent->_data); break; case GetLast: (dynamic_cast(_component)->*method)(typedEvent->_data); QCoreApplication::removePostedEvents(this,TYPED_EVENT); // delete all remining events break; case NeverSkip: default: (dynamic_cast(_component)->*method)(typedEvent->_data); } break; } // from Connection interface to Component (G->T) case GENERIC_EVENT2: { PacpusTypedEvent * genericEvent = dynamic_cast *> (event); qDebug() << "E2 "; //if(sizeof(T) != genericEvent->_data.size()) // qDebug() << "Incorrecte size " << sizeof(T) << " " << genericEvent->_data.size(); qDebug() << "t[18]= " << road_time(); T data; QByteArray& buf = (QByteArray&) genericEvent->_data; //qDebug() << "DataSize " <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) { for(QList::iterator it = _connection.begin(); it!=_connection.end(); ++it){ if(it->getInputInterface()->getDataType() != QString(typeid(QByteArray).name())) QApplication::postEvent(it->getInputInterface(),new PacpusTypedEvent(QEvent::Type(TYPED_EVENT),data),it->getPriority()); else { qDebug() << "t[1]= " << road_time(); //QByteArray buf((char*)(&data),sizeof(T)); QByteArray buf; QDataStream out(&buf,QIODevice::ReadWrite); qDebug() << "t[2]= " << road_time(); // out << data; // Copy 1 qDebug() << "t[3]= " << road_time(); PacpusTypedEvent * ev =new PacpusTypedEvent(QEvent::Type(GENERIC_EVENT3),buf); qDebug() << "t[4]= " << road_time(); QApplication::postEvent(it->getInputInterface(),ev,it->getPriority()); // Copy 2 (ctor) qDebug() << "t[5]= " << road_time(); //QApplication::postEvent(it->getInputInterface(),new PacpusTypedEvent(QEvent::Type(GENERIC_EVENT3),buf),it->getPriority()); // Copy 2 (ctor) } //qDebug() << "send thread " << QThread::currentThread(); } } // Used by Connection Interfaces only to pose generic event void sendGenericData(char * data, size_t size) { qDebug() << "t[15]= " << road_time(); QByteArray buf(data,size); // copy 5 qDebug() << "t[16]= " << road_time(); for(QList::iterator it = _connection.begin(); it!=_connection.end(); ++it) QApplication::postEvent(it->getInputInterface(),new PacpusTypedEvent(QEvent::Type(GENERIC_EVENT2),buf),it->getPriority()); // Copy 6(ctor) qDebug() << "t[17]= " << road_time(); //qDebug() << "send thread " << QThread::currentThread(); } size_t getDataSize() {return sizeof(T);} QString getDataType() {return QString(typeid(T).name());} }; } // namespace pacpus #endif // IN_OUT_INTERFACE_H