Skip to content

Commit

Permalink
platform: ensure pending changes in the DisplayBuffer are flushed in …
Browse files Browse the repository at this point in the history
…time

This fixes an issue with TVISION_MAX_FPS when TProgram::eventTimeoutMs is negative (infinite timeout).
  • Loading branch information
magiblot committed Oct 22, 2024
1 parent 3518c8c commit ca00eab
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 7 deletions.
8 changes: 7 additions & 1 deletion include/tvision/internal/dispbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class DisplayBuffer
{
friend FlushScreenAlgorithm;

using Clock = std::chrono::steady_clock;
using TimePoint = Clock::time_point;

struct Range {
int begin, end;
};
Expand All @@ -42,7 +45,8 @@ class DisplayBuffer

bool limitFPS;
std::chrono::microseconds flushDelay {};
std::chrono::time_point<std::chrono::steady_clock> lastFlush {};
TimePoint lastFlush {};
TimePoint pendingFlush {};

#ifdef _WIN32
static constexpr int defaultFPS = 120; // Just 60 feels notably slower on Windows, I don't know why.
Expand Down Expand Up @@ -79,6 +83,8 @@ class DisplayBuffer

void setCursorPosition(int x, int y) noexcept;
void setCursorVisibility(bool visible) noexcept;

int timeUntilPendingFlushMs() noexcept;
};

inline bool DisplayBuffer::inBounds(int x, int y) const noexcept
Expand Down
2 changes: 1 addition & 1 deletion include/tvision/internal/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class Platform
{ console.lock([&] (auto *&c) { this->restoreConsole(c); }); }

bool getEvent(TEvent &ev) noexcept;
void waitForEvents(int ms) noexcept { checkConsole(); waiter.waitForEvents(ms); }
void waitForEvents(int ms) noexcept;
void interruptEventWait() noexcept { waiter.interruptEventWait(); }

int getButtonCount() noexcept
Expand Down
27 changes: 22 additions & 5 deletions source/platform/dispbuff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#include <internal/codepage.h>
#include <internal/getenv.h>
#include <chrono>
using std::chrono::microseconds;
using std::chrono::steady_clock;

#ifdef _MSC_VER
#define __builtin_expect(x, y) x
Expand All @@ -28,7 +26,7 @@ DisplayBuffer::DisplayBuffer() noexcept :
int fps = getEnv<int>("TVISION_MAX_FPS", defaultFPS);
limitFPS = (fps > 0);
if (limitFPS)
flushDelay = microseconds((int) 1e6/fps);
flushDelay = std::chrono::microseconds((int) 1e6/fps);
}

TScreenCell *DisplayBuffer::reloadScreenInfo(DisplayStrategy &display) noexcept
Expand Down Expand Up @@ -119,15 +117,34 @@ bool DisplayBuffer::timeToFlush() noexcept
// Avoid flushing faster than the maximum FPS.
if (limitFPS)
{
auto now = steady_clock::now();
if (now - lastFlush >= flushDelay)
auto now = Clock::now();
auto flushTime = lastFlush + flushDelay;
if (flushTime <= now)
{
lastFlush = now;
pendingFlush = TimePoint();
}
else
{
pendingFlush = flushTime;
return false;
}
}
return true;
}

int DisplayBuffer::timeUntilPendingFlushMs() noexcept
{
using namespace std::chrono;
if (pendingFlush != TimePoint())
{
auto time = pendingFlush - Clock::now();
if (time >= milliseconds::zero())
return duration_cast<milliseconds>(time).count();
}
return -1;
}

void DisplayBuffer::setCursorPosition(int x, int y) noexcept
{
TPoint pos {x, y};
Expand Down
16 changes: 16 additions & 0 deletions source/platform/platfcon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,22 @@ bool Platform::getEvent(TEvent &ev) noexcept
return false;
}

void Platform::waitForEvents(int ms) noexcept
{
checkConsole();

int waitTimeoutMs = ms;
// When the DisplayBuffer has pending changes, ensure we wake up so that
// they can be flushed in time.
int flushTimeoutMs = displayBuf.timeUntilPendingFlushMs();
if (ms < 0)
waitTimeoutMs = flushTimeoutMs;
else if (flushTimeoutMs >= 0)
waitTimeoutMs = min(ms, flushTimeoutMs);

waiter.waitForEvents(waitTimeoutMs);
}

void Platform::signalCallback(bool enter) noexcept
{
if (instance && !instance->console.lockedByCurrentThread())
Expand Down

0 comments on commit ca00eab

Please sign in to comment.