diff --git a/include/tvision/internal/conctl.h b/include/tvision/internal/conctl.h index a8e42dea..678f7283 100644 --- a/include/tvision/internal/conctl.h +++ b/include/tvision/internal/conctl.h @@ -36,9 +36,7 @@ class ConsoleCtl // On Windows, the ConsoleCtl instance is created every time the alternate // screen buffer is enabled and it is destroyed when restoring the console. - // On Unix, the ConsoleCtl instance is created just once at the beginning - // of the program execution (in static initialization) and destroyed when - // exiting the program. + // On Unix, the ConsoleCtl instance is created just once. // Creates a global instance if none exists, and returns it. static ConsoleCtl &getInstance() noexcept; diff --git a/include/tvision/internal/platform.h b/include/tvision/internal/platform.h index dfcc2a29..4af18e23 100644 --- a/include/tvision/internal/platform.h +++ b/include/tvision/internal/platform.h @@ -100,9 +100,10 @@ class Platform static int (*charWidth)(uint32_t) noexcept; - // Platform is a singleton. It gets created and destroyed by THardwareInfo. + // Platform is a singleton. It gets created by THardwareInfo, but it is + // never destroyed in order to support invocations to 'interruptEventWait' + // from secondary threads. Platform() noexcept; - ~Platform(); // Note: explicit 'this' required by GCC 5. void setUpConsole() noexcept @@ -138,6 +139,8 @@ class Platform { console.lock([&] (auto *c) { displayBuf.flushScreen(c->display); }); } TScreenCell *reloadScreenInfo() noexcept { return console.lock([&] (auto *c) { return displayBuf.reloadScreenInfo(c->display); }); } + void freeScreenBuffer() noexcept + { displayBuf.~DisplayBuffer(); new (&displayBuf) DisplayBuffer; } bool setClipboardText(TStringView text) noexcept { return console.lock([&] (auto *c) { return c->setClipboardText(text); }); } diff --git a/source/platform/hardware.cpp b/source/platform/hardware.cpp index 36d42ec7..7ba8cbf9 100644 --- a/source/platform/hardware.cpp +++ b/source/platform/hardware.cpp @@ -21,15 +21,15 @@ static tvision::Platform *platf; THardwareInfo::THardwareInfo() noexcept { using namespace tvision; + static int initPlatform = + (platf = new Platform(), (void) initPlatform, 0); + pendingEvent = 0; alwaysFlush = getEnv("TVISION_MAX_FPS", 0) < 0; - platf = new Platform(); } THardwareInfo::~THardwareInfo() { - delete platf; - platf = nullptr; } void THardwareInfo::setCaretSize( ushort size ) noexcept { platf->setCaretSize(size); } @@ -48,7 +48,7 @@ void THardwareInfo::screenWrite( ushort x, ushort y, TScreenCell *buf, DWORD len flushScreen(); } TScreenCell *THardwareInfo::allocateScreenBuffer() noexcept { return platf->reloadScreenInfo(); } -void THardwareInfo::freeScreenBuffer( TScreenCell * ) noexcept {} +void THardwareInfo::freeScreenBuffer(TScreenCell *) noexcept { platf->freeScreenBuffer(); } DWORD THardwareInfo::getButtonCount() noexcept { return platf->getButtonCount(); } void THardwareInfo::cursorOn() noexcept { platf->cursorOn(); } void THardwareInfo::cursorOff() noexcept { platf->cursorOff(); } diff --git a/source/platform/platform.cpp b/source/platform/platform.cpp index d50bb9ed..b9e7fc37 100644 --- a/source/platform/platform.cpp +++ b/source/platform/platform.cpp @@ -16,7 +16,7 @@ Platform *Platform::instance; // This is used by TText. It is a global function pointer (instead of an // instance method) so that it can be used regardless of whether the global -// Platform instance has been created/destroyed or not. +// Platform instance has been created or not. int (*Platform::charWidth)(uint32_t) noexcept = &Platform::initAndGetCharWidth; int Platform::initAndGetCharWidth(uint32_t wc) noexcept @@ -55,15 +55,6 @@ Platform::Platform() noexcept initEncodingStuff(); } -Platform::~Platform() -{ - restoreConsole(); -#ifndef _WIN32 - ConsoleCtl::destroyInstance(); -#endif - instance = nullptr; -} - void Platform::restoreConsole(ConsoleStrategy *&c) noexcept { if (c != &dummyConsole) @@ -75,6 +66,9 @@ void Platform::restoreConsole(ConsoleStrategy *&c) noexcept SignalHandler::disable(); delete c; c = &dummyConsole; +#ifdef _WIN32 + ConsoleCtl::destroyInstance(); +#endif } } diff --git a/source/platform/win32con.cpp b/source/platform/win32con.cpp index 1bcc0fd1..b8149a4b 100644 --- a/source/platform/win32con.cpp +++ b/source/platform/win32con.cpp @@ -110,7 +110,6 @@ Win32ConsoleStrategy::~Win32ConsoleStrategy() delete &input; SetConsoleCP(cpInput); SetConsoleOutputCP(cpOutput); - ConsoleCtl::destroyInstance(); } bool Win32ConsoleStrategy::isAlive() noexcept