source: pacpusframework/trunk/include/Pacpus/kernel/InputOutputInterface.h@ 202

Last change on this file since 202 was 202, checked in by Marek Kurdej, 11 years ago

Added: OutputInterface::checkedSend.
Added: ComponentManager: prints InputsMap, OutputsMap.

  • Property svn:executable set to *
File size: 4.7 KB
RevLine 
[89]1#ifndef IN_OUT_INTERFACE_H
2#define IN_OUT_INTERFACE_H
3
[199]4#include <Pacpus/kernel/InputOutputBase.h>
[95]5#include <Pacpus/kernel/Log.h>
[199]6
[153]7#include <QByteArray>
[200]8#include <QCoreApplication>
[110]9#include <typeinfo>
[89]10
11namespace pacpus {
12
[152]13template <typename T, class C>
[148]14class InputInterface
15 : public InputInterfaceBase
[89]16{
17public:
[199]18 typedef T data_type;
19 typedef C component_type;
20 typedef void (C::*process_data_function_type)(const T &);
21
22 InputInterface(QString name, C * component, process_data_function_type processMethod)
[152]23 : InputInterfaceBase(name, component, component)
[199]24 , method(processMethod)
[148]25 {}
[89]26
[148]27 ~InputInterface()
28 {}
[89]29
[199]30 std::size_t getDataSize() const
[148]31 {
32 return sizeof(T);
33 }
[89]34
[199]35 const std::type_info & getDataType() const
[148]36 {
[199]37 return typeid(T);
[148]38 }
[96]39
[199]40 // FIXME: what's the purpose of this function?
41 PacpusEvent * getEventTemplate()
[148]42 {
43 return new PacpusTypedEvent<T>(TYPED_EVENT);
44 }
45
[199]46 // FIXME: what's the purpose of this function?
[184]47 void customEvent(QEvent * event)
[148]48 {
49 // TODO check component state started
[182]50 //if (_component) get state
[89]51 switch (event->type()) {
[148]52 case TYPED_EVENT:
53 {
[110]54 PacpusTypedEvent<T> * typedEvent = dynamic_cast<PacpusTypedEvent<T> *> (event);
[89]55
[200]56 LOG_DEBUG("Receiver: " << getSignature());
[110]57
[148]58 if (typedEvent->timerange() < 500 && readingMode() == TimeBounded) {
[153]59 LOG_WARN("Incorrect TimeRange (0), switch to NeverSkip");
60 readingMode() = NeverSkip;
61 }
[110]62
[148]63 switch (readingMode()) {
[110]64 case TimeBounded:
65
[148]66 if (road_time() - typedEvent->time() > typedEvent->timerange()) {
[200]67 LOG_DEBUG("Data skipped, receiver: " << this->getSignature());
[148]68 break;
69 }
[110]70
[148]71 (dynamic_cast<C*>(component())->*method)(typedEvent->data());
[89]72 break;
[110]73
74 case GetLast:
75
[148]76 (dynamic_cast<C*>(component())->*method)(typedEvent->data());
[153]77 // delete all remaining events
78 QCoreApplication::removePostedEvents(this, TYPED_EVENT);
[110]79 break;
80
81 case NeverSkip:
[159]82 (dynamic_cast<C*>(component())->*method)(typedEvent->data());
83 break;
[110]84
85 default:
[159]86 LOG_WARN("Unknown reading mode " << readingMode());
[89]87 }
[110]88 break;
89 }
[89]90
[184]91 // Add here new event type if needed
[89]92
[110]93 default:
[153]94 LOG_WARN("Unknown event ID " << event->type());
[110]95 break;
[89]96 }
[110]97 event->accept();
98 }
[89]99
[159]100 // TODO for Pulling mode (not yet implemented !!!)
[185]101 T & getData() {
[110]102 T data;
103 // TODO ask output data;
[89]104
[110]105 return data;
[89]106 }
107
108protected:
[199]109 process_data_function_type method;
[89]110};
111
[152]112template <typename T, class C>
[185]113class OutputInterface
114 : public OutputInterfaceBase
[89]115{
116public:
[199]117 typedef T data_type;
118 typedef C component_type;
119
[184]120 OutputInterface(QString name, C * component)
[185]121 : OutputInterfaceBase(name, component, component)
[184]122 {}
[89]123
[199]124 ~OutputInterface()
125 {}
126
[89]127 // Used by Components to send data througth typed output
[184]128 void send(const T & data, road_time_t t = road_time(), road_timerange_t tr = 0);
129
[199]130 std::size_t getDataSize() const
[148]131 {
132 return sizeof(T);
133 }
134
[199]135 const std::type_info & getDataType() const
[148]136 {
[199]137 return typeid(T);
[148]138 }
[89]139};
140
[185]141template <typename T, class C>
142void OutputInterface<T, C>::send(const T & data, road_time_t t, road_timerange_t tr)
143{
144 // FIXME Data Shared
145 //QSharedPointer<T> sharedPointer = new T(data);
146
[200]147 for (QList<ConnectionBase>::iterator it = connections().begin(), itend = connections().end(); it != itend; ++it) {
[202]148 // Qt documentatino:
149 // The event must be allocated on the heap since the post event queue will take ownership of the event and delete it once it has been posted.
150 // It is not safe to access the event after it has been posted.
151 QEvent * newEvent = new PacpusTypedEvent<T>(TYPED_EVENT, data, t, tr);
152 QCoreApplication::postEvent(it->getInterface(), newEvent, it->getPriority());
153 LOG_DEBUG("Sender: " << it->getInterface()->getSignature());
154 LOG_DEBUG("Data &: " << &data);
[185]155 }
156}
157
[202]158template <typename T1, typename T2, class C>
159bool checkedSend(OutputInterface<T1, C> * sender, const T2 & data, road_time_t t = road_time(), road_timerange_t tr = 0);
160
161template <typename T1, typename T2, class C>
162bool checkedSend(OutputInterface<T1, C> * sender, const T2 & data, road_time_t t, road_timerange_t tr)
163{
164 if (sender && sender->hasConnection()) {
165 sender->send(data, t, tr);
166 return true;
167 }
168 return false;
169}
170
[89]171} // namespace pacpus
172
173#endif // IN_OUT_INTERFACE_H
Note: See TracBrowser for help on using the repository browser.