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
Line 
1#ifndef IN_OUT_INTERFACE_H
2#define IN_OUT_INTERFACE_H
3
4#include <Pacpus/kernel/InputOutputBase.h>
5#include <Pacpus/kernel/Log.h>
6
7#include <QByteArray>
8#include <QCoreApplication>
9#include <typeinfo>
10
11namespace pacpus {
12
13template <typename T, class C>
14class InputInterface
15 : public InputInterfaceBase
16{
17public:
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)
23 : InputInterfaceBase(name, component, component)
24 , method(processMethod)
25 {}
26
27 ~InputInterface()
28 {}
29
30 std::size_t getDataSize() const
31 {
32 return sizeof(T);
33 }
34
35 const std::type_info & getDataType() const
36 {
37 return typeid(T);
38 }
39
40 // FIXME: what's the purpose of this function?
41 PacpusEvent * getEventTemplate()
42 {
43 return new PacpusTypedEvent<T>(TYPED_EVENT);
44 }
45
46 // FIXME: what's the purpose of this function?
47 void customEvent(QEvent * event)
48 {
49 // TODO check component state started
50 //if (_component) get state
51 switch (event->type()) {
52 case TYPED_EVENT:
53 {
54 PacpusTypedEvent<T> * typedEvent = dynamic_cast<PacpusTypedEvent<T> *> (event);
55
56 LOG_DEBUG("Receiver: " << getSignature());
57
58 if (typedEvent->timerange() < 500 && readingMode() == TimeBounded) {
59 LOG_WARN("Incorrect TimeRange (0), switch to NeverSkip");
60 readingMode() = NeverSkip;
61 }
62
63 switch (readingMode()) {
64 case TimeBounded:
65
66 if (road_time() - typedEvent->time() > typedEvent->timerange()) {
67 LOG_DEBUG("Data skipped, receiver: " << this->getSignature());
68 break;
69 }
70
71 (dynamic_cast<C*>(component())->*method)(typedEvent->data());
72 break;
73
74 case GetLast:
75
76 (dynamic_cast<C*>(component())->*method)(typedEvent->data());
77 // delete all remaining events
78 QCoreApplication::removePostedEvents(this, TYPED_EVENT);
79 break;
80
81 case NeverSkip:
82 (dynamic_cast<C*>(component())->*method)(typedEvent->data());
83 break;
84
85 default:
86 LOG_WARN("Unknown reading mode " << readingMode());
87 }
88 break;
89 }
90
91 // Add here new event type if needed
92
93 default:
94 LOG_WARN("Unknown event ID " << event->type());
95 break;
96 }
97 event->accept();
98 }
99
100 // TODO for Pulling mode (not yet implemented !!!)
101 T & getData() {
102 T data;
103 // TODO ask output data;
104
105 return data;
106 }
107
108protected:
109 process_data_function_type method;
110};
111
112template <typename T, class C>
113class OutputInterface
114 : public OutputInterfaceBase
115{
116public:
117 typedef T data_type;
118 typedef C component_type;
119
120 OutputInterface(QString name, C * component)
121 : OutputInterfaceBase(name, component, component)
122 {}
123
124 ~OutputInterface()
125 {}
126
127 // Used by Components to send data througth typed output
128 void send(const T & data, road_time_t t = road_time(), road_timerange_t tr = 0);
129
130 std::size_t getDataSize() const
131 {
132 return sizeof(T);
133 }
134
135 const std::type_info & getDataType() const
136 {
137 return typeid(T);
138 }
139};
140
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
147 for (QList<ConnectionBase>::iterator it = connections().begin(), itend = connections().end(); it != itend; ++it) {
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);
155 }
156}
157
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
171} // namespace pacpus
172
173#endif // IN_OUT_INTERFACE_H
Note: See TracBrowser for help on using the repository browser.