/** * This idle function allows progressive scanning of visibility etc */ bool GlueMapWindow::Idle() { if (!render_projection.IsValid()) return false; if (idle_robin == unsigned(-1)) { /* draw the first frame as quickly as possible, so the user can start interacting with XCSoar immediately */ idle_robin = 2; return true; } if (!IsUserIdle(2500)) /* don't hold back the UI thread while the user is interacting */ return true; PeriodClock clock; clock.Update(); bool still_dirty; bool topography_dirty = true; /* scan topography in every Idle() call */ bool terrain_dirty = true; bool weather_dirty = true; do { idle_robin = (idle_robin + 1) % 3; switch (idle_robin) { case 0: topography_dirty = UpdateTopography(1) > 0; break; case 1: terrain_dirty = UpdateTerrain(); break; case 2: weather_dirty = UpdateWeather(); break; } still_dirty = terrain_dirty || topography_dirty || weather_dirty; } while (!clock.Check(700) && /* stop after 700ms */ #ifndef ENABLE_OPENGL !draw_thread->IsTriggered() && #endif IsUserIdle(2500) && still_dirty); return still_dirty; }
bool FlarmDevice::Receive(const char *prefix, char *buffer, size_t length, unsigned timeout_ms) { assert(!in_binary_mode); assert(prefix != NULL); PeriodClock timeout; timeout.Update(); if (!port.ExpectString(prefix, timeout_ms)) return false; char *p = (char *)buffer, *end = p + length; while (p < end) { if (timeout.Check(timeout_ms)) return false; // Read single character from port int c = port.GetChar(); // On failure try again until timed out if (c == -1) continue; // Break on line break or checksum if (c == '*' || c == '\n') { *p = '\0'; break; } // Skip carriage return if (c == '\r') continue; // Write received character to buffer *p = c; p++; } return true; }
/** * This idle function allows progressive scanning of visibility etc */ bool GlueMapWindow::Idle() { if (!render_projection.IsValid()) return false; if (skip_idle) { /* draw the first frame as quickly as possible, so the user can start interacting with XCSoar immediately */ skip_idle = false; return true; } /* hack: update RASP weather maps as quickly as possible; they only ever need to be updated after the user has selected a new map, so this is not a UI latency problem (quite contrary, don't let the user wait until he sees the new map) */ UpdateWeather(); if (!IsUserIdle(2500)) /* don't hold back the UI thread while the user is interacting */ return true; PeriodClock clock; clock.Update(); bool still_dirty; do { still_dirty = UpdateWeather() || UpdateTerrain(); } while (!clock.Check(700) && /* stop after 700ms */ #ifndef ENABLE_OPENGL !draw_thread->IsTriggered() && #endif IsUserIdle(2500) && still_dirty); return still_dirty; }
static bool TryConnect(Port &port, char *user_data, size_t max_user_data, OperationEnvironment &env) { port.Write('\x02'); // send IO Mode command unsigned user_size = 0; bool started = false; PeriodClock clock; clock.Update(); int i; while ((i = port.GetChar()) != EOF && !clock.Check(8000) && !env.IsCancelled()) { char ch = (char)i; if (!started && ch == '-') started = true; if (started) { if (ch == 0x13) { port.Write('\x16'); user_data[user_size] = 0; // found end of file return true; } else { if (user_size < max_user_data - 1) { user_data[user_size] = ch; user_size++; } } } } return false; }
bool IsUserIdle(unsigned duration_ms) { return user_idle_clock.Check(duration_ms); }