#ifndef IN_OUT_INTERFACE_H #define IN_OUT_INTERFACE_H #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)) #define GET_INPUT(name,ComponentType, DataType) dynamic_cast *> (input.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: public: PacpusEvent* getEventTemplate() {return new 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() << "Revever " << getSignature() << " thread " << QThread::currentThread() << " Data & " << & typedEvent->data_; //if(_component) get state if(typedEvent->tr_ < 500 && readingMode_ == TimeBounded) { //LOG_WARN("Incorrect TimeRange (0), switch to NeverSkip"); qDebug() << "Incorrect TimeRange (0), switch to NeverSkip"; readingMode_ = NeverSkip;} switch (readingMode_){ case TimeBounded: qDebug() << "Input " << this->getSignature().leftJustified(20) << QString("Time bournded").leftJustified(15) << road_time()- typedEvent->t_ << "\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().leftJustified(20) << QString("GetLast").leftJustified(15) << road_time() - typedEvent->t_ << "\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().leftJustified(20) << QString("NeverSkip").leftJustified(15) << road_time() - typedEvent->t_ << "\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; } event->accept(); } T& getData() { T data; // TODO ask output data; //LOG4CXX_INFO(getLogger(), "Hello, World"); return data; } protected: void (C::*method)(const T&); /* log4cxx::LoggerPtr& getLogger() { static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger( LOG4CXX_LOCATION.getClassName())); return logger; }*/ }; 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) { //QSharedPointer sharedPointer = new T(data); for(QList::iterator it = _connection.begin(); it!=_connection.end(); ++it){ QApplication::postEvent(it->getInterface(),new PacpusTypedEvent(TYPED_EVENT,data,t,tr),it->getPriority()); // Event is delete by the event loop handler qDebug() << "sender " << it->getInterface()->getSignature() << " thread " << QThread::currentThread() << " Data & " << &data << " "; // TODO DAta SHAred } } /* 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