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 "pch.h"
#include "Client.h" #include "Client.h"
#include "util.h"
namespace nf::cli { namespace nf::cli {
Client::Client(ClientConfig config) Client::Client(ClientConfig config)
: m_config(config) : m_running(true)
, m_window(m_config.appName, m_config.display) , m_config(config)
, m_renderEngine(m_window.getHandle()) , m_renderEngine()
{ {}
// Setup window and renderer
}
void Client::run() { void Client::run() {
// Main game loop // Create window on input thread and pass up a pointer for the renderer
m_window.runLoop(); 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(); void run();
private: private:
void runInputThread(std::promise<std::shared_ptr<Window>> windowPromise);
bool m_running;
ClientConfig m_config; ClientConfig m_config;
Window m_window; std::unique_ptr<render::RenderEngine> m_renderEngine;
render::RenderEngine m_renderEngine;
}; };
} }

View File

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

View File

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

View File

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

View File

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