#ifndef IN_OUT_INTERFACE_H #define IN_OUT_INTERFACE_H #include #include #include #include #include #include #include //#define ADD_INPUT(name, ComponentType, DataType, functionName) \ // inputs().insert((name), new InputInterface ((name), this, &ComponentType::functionName)) //#define ADD_OUTPUT(name, ComponentType, DataType) \ // outputs().insert((name), new OutputInterface ((name), this)) //#define GET_INPUT(name, ComponentType, DataType) \ // dynamic_cast *> (input.value(name)) //#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()); } PacpusEvent* getEventTemplate() { return new PacpusTypedEvent(TYPED_EVENT); } void customEvent(QEvent* event) { // TODO check component state started switch (event->type()) { case TYPED_EVENT: { // cast from Component to Component (T->T) PacpusTypedEvent * typedEvent = dynamic_cast *> (event); //qDebug() << "Reciever " << getSignature() << " thread " << QThread::currentThread() << " Data & " << & typedEvent->data_; //if(_component) get state if (typedEvent->timerange() < 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->time() > typedEvent->timerange()) { 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 = connections().begin(); it != connections().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