retry harder to output data fast, update to current frame quickly if last frame had been dropped
Stefan Schuermans

Stefan Schuermans commited on 2011-12-27 19:23:46
Showing 2 changed files, with 60 additions and 18 deletions.

... ...
@@ -86,11 +86,19 @@ void Output::setFrame(const std::string &stream, stBlinkenFrame *pFrame)
86 86
 /// callback when requested time reached
87 87
 void Output::timeCall()
88 88
 {
89
-  // if device is not open, try to (re-)open it
90
-  if (!m_pDevice)
89
+  // device is not open -> try to (re-)open it
90
+  if (!m_pDevice) {
91 91
     openDevice();
92
+    return;
93
+  }
94
+
95
+  // buffer not empty -> try to output rest of data
96
+  if (!m_buffer.empty()) {
97
+    outputBufferedData();
98
+    return;
99
+  }
92 100
 
93
-  // re-output current frame
101
+  // (re-)output current frame
94 102
   outputFrame();
95 103
 }
96 104
 
... ...
@@ -136,11 +144,11 @@ void Output::closeDevice()
136 144
     m_pDevice = NULL;
137 145
   }
138 146
 
139
-  // clear buffered data
147
+  // reset internal status
140 148
   m_buffer.clear();
149
+  m_dropped = false;
141 150
 
142
-  // request time callback in one second (for trying to re-open device)
143
-  m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + Time(1));
151
+  updateTimeCallback();
144 152
 }
145 153
 
146 154
 /// output current frame to device
... ...
@@ -169,12 +177,9 @@ void Output::outputFrame()
169 177
     len = 0;
170 178
   data.assign(buf, len);
171 179
 
172
-  // output data to device
173 180
   outputFrameData(data);
174 181
 
175
-  /* request time callback in one second
176
-     (for outputting current frame again or reopening device) */
177
-  m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + Time(1));
182
+  updateTimeCallback();
178 183
 }
179 184
 
180 185
 /**
... ...
@@ -183,20 +188,50 @@ void Output::outputFrame()
183 188
  */
184 189
 void Output::outputFrameData(const std::string &data)
185 190
 {
186
-  // no device -> leave
187
-  if (!m_pDevice)
188
-    return;
189
-
190 191
   // add data to buffer (if current buffer contains less than 10 frames)
191
-  if (m_buffer.size() < data.size() * 10)
192
+  if (m_buffer.size() < data.size() * 10) {
192 193
     m_buffer += data;
194
+    m_dropped = false; // last frame was not dropped
195
+  } else {
196
+    m_dropped = true; // remember that last frame was dropped
197
+  }
198
+
199
+  outputBufferedData();
200
+}
201
+
202
+/// write data in output buffer to device
203
+void Output::outputBufferedData()
204
+{
205
+  // no device -> forget buffered data, leave
206
+  if (!m_pDevice) {
207
+    m_buffer.clear();
208
+    return;
209
+  }
193 210
 
194 211
   // write (at least some) data to device
195 212
   std::string::size_type len;
196
-  if (!m_pDevice->write(m_buffer, len))
213
+  if (!m_pDevice->write(m_buffer, len)) {
197 214
     closeDevice(); // error -> close device
198
-  else
199
-    m_buffer = m_buffer.substr(len); // done -> remove written data from buffer
215
+    return;
216
+  }
217
+
218
+  // remove written data from buffer
219
+  m_buffer = m_buffer.substr(len);
220
+
221
+  updateTimeCallback();
222
+}
223
+
224
+/// update time callback request
225
+void Output::updateTimeCallback()
226
+{
227
+  /* no device -> call in 1s for re-opening device
228
+     buffer empty, last frame not dropped -> call in 1s for re-outputting
229
+     buffer not empty -> call in 50ms for outputting more data
230
+     last frame dropped -> call in 50ms for frame update */
231
+  Time delay(1);
232
+  if (m_pDevice && (!m_buffer.empty() || m_dropped))
233
+    delay.fromMs(50);
234
+  m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + delay);
200 235
 }
201 236
 
202 237
 } // namespace Blinker
... ...
@@ -81,6 +81,12 @@ protected:
81 81
    */
82 82
   void outputFrameData(const std::string &data);
83 83
 
84
+  /// write data in output buffer to device
85
+  void outputBufferedData();
86
+
87
+  /// update time callback request
88
+  void updateTimeCallback();
89
+
84 90
 protected:
85 91
   InStreamFile m_fileInStream; ///< input stream name file
86 92
   ProtocolFile m_fileProtocol; ///< protocol file
... ...
@@ -88,6 +94,7 @@ protected:
88 94
   SerCfgFile   m_fileSerCfg;   ///< serial port configuration file
89 95
   Device       *m_pDevice;     ///< device to output to
90 96
   std::string  m_buffer;       ///< buffered data still to be output to device
97
+  bool         m_dropped;      ///< if the last frame has been dropped
91 98
 }; // class Output
92 99
 
93 100
 } // namespace Blinker
94 101