Create Window on separate input thread

This commit is contained in:
Grayson Riffe 2025-02-08 03:01:55 -06:00
parent 0205f70ba6
commit b87c2164ad
6 changed files with 59 additions and 24 deletions

View File

@ -2,18 +2,39 @@
#include "pch.h"
#include "Client.h"
#include "util.h"
namespace nf::cli {
Client::Client(ClientConfig config)
: m_config(config)
, m_window(m_config.appName, m_config.display)
, m_renderEngine(m_window.getHandle())
{
// Setup window and renderer
}
: m_running(true)
, m_config(config)
, m_renderEngine()
{}
void Client::run() {
// Main game loop
m_window.runLoop();
// Create window on input thread and pass up a pointer for the renderer
std::promise<std::shared_ptr<Window>> windowPromise;
auto windowFuture = windowPromise.get_future();
std::thread inputThread(&Client::runInputThread, this, std::move(windowPromise));
m_renderEngine = std::make_unique<render::RenderEngine>(std::move(windowFuture.get()), m_config.display);
while (m_running) {
NFLog("Client running...");
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
inputThread.join();
}
void Client::runInputThread(std::promise<std::shared_ptr<Window>> windowPromise) {
#ifdef _DEBUG
SetThreadDescription(GetCurrentThread(), L"NF Input Thread");
#endif
std::shared_ptr<Window> window = std::make_shared<Window>(m_config.appName);
windowPromise.set_value(window);
window->runLoop();
m_running = false;
}
}

View File

@ -12,8 +12,10 @@ namespace nf::cli {
void run();
private:
void runInputThread(std::promise<std::shared_ptr<Window>> windowPromise);
bool m_running;
ClientConfig m_config;
Window m_window;
render::RenderEngine m_renderEngine;
std::unique_ptr<render::RenderEngine> m_renderEngine;
};
}

View File

@ -5,12 +5,13 @@
#include "util.h"
namespace nf::cli {
Window::Window(const char* windowTitle, DisplayConfig config)
Window::Window(const char* windowTitle)
: m_handle(nullptr)
, m_wndClassName("NothinFancyWindow")
, m_windowedStyle(WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
, m_fullscreenStyle(WS_POPUP)
, m_config()
, m_width()
, m_height()
{
NFLog("Creating window");
@ -20,7 +21,6 @@ namespace nf::cli {
registerWindowClass();
m_handle = CreateWindow(m_wndClassName, windowTitle, NULL, 0, 0, 0, 0, nullptr, nullptr, nullptr, this);
setDisplay(config);
}
HWND Window::getHandle() const {
@ -29,7 +29,7 @@ namespace nf::cli {
void Window::setDisplay(DisplayConfig config) {
NFLog("Setting window display");
m_config = config;
m_width = config.width, m_height = config.height;
bool wasShown = IsWindowVisible(m_handle);
show(false);
@ -47,7 +47,7 @@ namespace nf::cli {
switch (config.mode) {
case DisplayMode::Windowed: {
SetWindowLongPtr(m_handle, GWL_STYLE, m_windowedStyle);
windowX = monitorX + (monitorWidth / 2) - (m_config.width / 2), windowY = monitorY + (monitorHeight / 2) - (m_config.height / 2);
windowX = monitorX + (monitorWidth / 2) - (m_width / 2), windowY = monitorY + (monitorHeight / 2) - (m_height / 2);
SIZE windowSize = getWindowSize();
windowWidth = windowSize.cx, windowHeight = windowSize.cy;
break;
@ -67,7 +67,8 @@ namespace nf::cli {
}
void Window::runLoop() {
show();
// At some point, the window started to show unselected at first.
SetFocus(m_handle);
MSG msg = {};
while (GetMessage(&msg, nullptr, NULL, NULL)) {
TranslateMessage(&msg);
@ -120,8 +121,8 @@ namespace nf::cli {
SIZE Window::getWindowSize() {
RECT cli = {};
cli.right = m_config.width;
cli.bottom = m_config.height;
cli.right = m_width;
cli.bottom = m_height;
AdjustWindowRectExForDpi(&cli, m_windowedStyle, FALSE, NULL, GetDpiForWindow(m_handle));
int width = cli.right - cli.left, height = cli.bottom - cli.top;
return { width, height };

View File

@ -8,7 +8,7 @@
namespace nf::cli {
class Window {
public:
Window(const char* windowTitle, DisplayConfig config);
Window(const char* windowTitle);
HWND getHandle() const;
void setDisplay(DisplayConfig config);
@ -25,6 +25,6 @@ namespace nf::cli {
const DWORD m_windowedStyle;
const DWORD m_fullscreenStyle;
DisplayConfig m_config;
unsigned int m_width, m_height;
};
}

View File

@ -5,13 +5,18 @@
#include "util.h"
namespace nf::cli::render {
RenderEngine::RenderEngine(HWND window)
: m_instance()
RenderEngine::RenderEngine(std::shared_ptr<Window> window, DisplayConfig display)
: m_window(window)
, m_display(display)
, m_instance()
, m_surface()
{
NFLog("Initializing render engine");
createInstance();
createSurface(window);
createSurface(m_window->getHandle());
m_window->setDisplay(m_display);
m_window->show();
}
void RenderEngine::createInstance() {

View File

@ -1,16 +1,22 @@
// RenderEngine class header
#pragma once
#include "client/Window.h"
#include "nf/config.h"
namespace nf::cli::render {
class RenderEngine {
public:
RenderEngine(HWND window);
RenderEngine(std::shared_ptr<Window> window, DisplayConfig display);
~RenderEngine();
private:
void createInstance();
void createSurface(HWND window);
std::shared_ptr<Window> m_window;
DisplayConfig m_display;
VkInstance m_instance;
VkSurfaceKHR m_surface;
};