From 556cf073d61875368fe8511b75f5cb7db04ccb52 Mon Sep 17 00:00:00 2001 From: Marc Sunet Date: Wed, 19 Nov 2025 11:24:21 -0800 Subject: Use C++ modules --- .gitignore | 1 + CMakeLists.txt | 16 ++++--- contrib/glfw/CMakeLists.txt | 2 +- dxcommon/CMakeLists.txt | 16 +++++-- dxcommon/dxcommon.h | 17 +++++++ dxcommon/dxcommon.ixx | 53 +++++++++++++++++++++ dxcommon/include/dxcommon.h | 58 ----------------------- dxcommon/src/dxcommon.cc | 8 ---- dxwindow/CMakeLists.txt | 10 ++-- dxwindow/dxwindow.ixx | 113 ++++++++++++++++++++++++++++++++++++++++++++ dxwindow/include/dxwindow.h | 50 -------------------- dxwindow/src/dxwindow.cc | 80 ------------------------------- hello/CMakeLists.txt | 9 ++-- hello/main.cc | 9 ++-- 14 files changed, 221 insertions(+), 221 deletions(-) create mode 100644 .gitignore create mode 100644 dxcommon/dxcommon.h create mode 100644 dxcommon/dxcommon.ixx delete mode 100644 dxcommon/include/dxcommon.h delete mode 100644 dxcommon/src/dxcommon.cc create mode 100644 dxwindow/dxwindow.ixx delete mode 100644 dxwindow/include/dxwindow.h delete mode 100644 dxwindow/src/dxwindow.cc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c4c4ffc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.zip diff --git a/CMakeLists.txt b/CMakeLists.txt index c916974..631e1e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,16 @@ -cmake_minimum_required(VERSION 3.20) - -project(dx12) +cmake_minimum_required(VERSION 3.25) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") +set(CMAKE_CXX_SCAN_FOR_MODULES ON) -# -MT, multi-threaded statically-linked runtime library. -#set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded) -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd /DDEBUG") +# Multi-threaded statically-linked runtime library (-MT) +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + +project(dx12) # External dependencies. add_subdirectory(contrib/DirectX-Headers) diff --git a/contrib/glfw/CMakeLists.txt b/contrib/glfw/CMakeLists.txt index 3521151..5635cfb 100644 --- a/contrib/glfw/CMakeLists.txt +++ b/contrib/glfw/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.25) add_library(glfw INTERFACE) diff --git a/dxcommon/CMakeLists.txt b/dxcommon/CMakeLists.txt index 08fa178..dfb52bf 100644 --- a/dxcommon/CMakeLists.txt +++ b/dxcommon/CMakeLists.txt @@ -1,10 +1,18 @@ -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.25) -add_library(dxcommon - src/dxcommon.cc) +project(dxcommon) + +add_library(dxcommon) + +target_sources(dxcommon PUBLIC + dxcommon.h) + +target_sources(dxcommon PUBLIC + FILE_SET cxx_modules TYPE CXX_MODULES FILES + dxcommon.ixx) target_include_directories(dxcommon PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include) + .) target_link_libraries(dxcommon PUBLIC DirectX-Headers diff --git a/dxcommon/dxcommon.h b/dxcommon/dxcommon.h new file mode 100644 index 0000000..addb8c3 --- /dev/null +++ b/dxcommon/dxcommon.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include + +#define THROW(error) throw exception(error, __FILE__, __LINE__) + +#define ThrowIfFailed(result) \ +{\ + if (result != S_OK) \ + {\ + THROW(result);\ + }\ +} + +//#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), static_cast(ppType) diff --git a/dxcommon/dxcommon.ixx b/dxcommon/dxcommon.ixx new file mode 100644 index 0000000..b06ae95 --- /dev/null +++ b/dxcommon/dxcommon.ixx @@ -0,0 +1,53 @@ +module; + +#include +#include + +export module dxcommon; + +using Microsoft::WRL::ComPtr; + +namespace dx { + +export { + +class exception : public std::exception +{ +public: + exception() noexcept = default; + + exception(HRESULT result, const char* file, int line) noexcept + { + sprintf_s(m_error, sizeof(m_error), "%s:%d Failed with HRESULT = %08X", + file, line, static_cast(result)); + } + + exception(const char* error, const char* file, int line) noexcept + { + sprintf_s(m_error, sizeof(m_error), "%s:%d %s", file, line, error); + } + + [[nodiscard]] const char* what() const noexcept final + { + return m_error; + } + +private: + static thread_local char m_error[1024]; +}; + +template +void SafeRelease(ComPtr& ptr) +{ + if (ptr) + { + ptr->Release(); + ptr = nullptr; + } +} + +} // export + +thread_local char exception::m_error[1024]; + +} // dx diff --git a/dxcommon/include/dxcommon.h b/dxcommon/include/dxcommon.h deleted file mode 100644 index 35ec0e2..0000000 --- a/dxcommon/include/dxcommon.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include - -#include - -//#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), static_cast(ppType) - -namespace dx { - -using Microsoft::WRL::ComPtr; - -class exception : public std::exception -{ -public: - exception() noexcept = default; - - exception(HRESULT result, const char* file, int line) noexcept - { - sprintf_s(m_error, sizeof(m_error), "%s:%d Failed with HRESULT = %08X", - file, line, static_cast(result)); - } - - exception(const char* error, const char* file, int line) noexcept - { - sprintf_s(m_error, sizeof(m_error), "%s:%d %s", file, line, error); - } - - [[nodiscard]] const char* what() const noexcept final - { - return m_error; - } - -private: - static thread_local char m_error[1024]; -}; - -#define THROW(error) throw exception(error, __FILE__, __LINE__) - -#define ThrowIfFailed(result) \ -{\ - if (result != S_OK) \ - {\ - THROW(result);\ - }\ -} - -template -void SafeRelease(ComPtr& ptr) -{ - if (ptr) - { - ptr->Release(); - ptr = nullptr; - } -} - -} // dx diff --git a/dxcommon/src/dxcommon.cc b/dxcommon/src/dxcommon.cc deleted file mode 100644 index 2139136..0000000 --- a/dxcommon/src/dxcommon.cc +++ /dev/null @@ -1,8 +0,0 @@ -#include "dxcommon.h" - -namespace dx -{ - -thread_local char exception::m_error[1024]; - -} // namespace dx diff --git a/dxwindow/CMakeLists.txt b/dxwindow/CMakeLists.txt index baf99de..16c1709 100644 --- a/dxwindow/CMakeLists.txt +++ b/dxwindow/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.25) -add_library(dxwindow - src/dxwindow.cc) +add_library(dxwindow) -target_include_directories(dxwindow PUBLIC - include/) +target_sources(dxwindow PUBLIC + FILE_SET cxx_modules TYPE CXX_MODULES FILES + dxwindow.ixx) target_link_libraries(dxwindow PUBLIC glfw) diff --git a/dxwindow/dxwindow.ixx b/dxwindow/dxwindow.ixx new file mode 100644 index 0000000..6efcc18 --- /dev/null +++ b/dxwindow/dxwindow.ixx @@ -0,0 +1,113 @@ +module; + +// Include Windows.h before GLFW to avoid macro redefinition warnings. +#define WIN32_LEAN_AND_MEAN +#include + +#define GLFW_INCLUDE_NONE // Do not include OpenGL headers. +#include + +#define GLFW_EXPOSE_NATIVE_WIN32 +#include + +#include +#include + +export module dxwindow; + +namespace dx { + +char glfw_error[1024] = {}; + +void glfw_error_callback(int error, const char* description) +{ + sprintf_s(glfw_error, sizeof(glfw_error), + "GLFW error %d: %s", error, description); +} + +export { + +class Window +{ +public: + ~Window() + { + if (m_window != nullptr) + { + glfwDestroyWindow(m_window); + } + } + + /// Creates the window. + bool Initialise(int width, int height, const char* title) + { + // GLFW by default creates an OpenGL context with the window. + // Use GLFW_NO_API to tell it not to do so. + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + + if ((m_window = glfwCreateWindow( + width, height, title, /*monitor=*/NULL, /*share=*/NULL)) == nullptr) + { + return false; + } + + return true; + } + + /// Returns the native window handle. + /// If the window has not been initialized, returns an invalid handle. + HWND GetWindowHandle() + { + if (!m_window) + { + return NULL; + } + return glfwGetWin32Window(m_window); + } + + /// Updates the window by polling for user input. + void Update() + { + assert(m_window); + glfwPollEvents(); + } + + /// Returns true if the user tried to close the window, false otherwise. + bool ShouldClose() const + { + assert(m_window); + return glfwWindowShouldClose(m_window) == GLFW_TRUE; + } + +private: + GLFWwindow* m_window = nullptr; +}; + +/// Initialise the window subsystem. +/// +/// This function must be called at the start of your application before any +/// Windows are created. +bool WindowInitialise() +{ + glfwSetErrorCallback(glfw_error_callback); + return glfwInit() == GLFW_TRUE; +} + +/// Terminate the window subsystem. +/// +/// This function should be called at the end of your application. Any existing +/// Windows are destroyed and are invalid beyond this call. +void WindowTerminate() +{ + glfwTerminate(); +} + +/// Returns the last Window error. +const char* GetWindowError() +{ + return glfw_error; +} + +} // export + +} // namespace dx diff --git a/dxwindow/include/dxwindow.h b/dxwindow/include/dxwindow.h deleted file mode 100644 index e8f551a..0000000 --- a/dxwindow/include/dxwindow.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -// Include Windows.h before GLFW to avoid macro redefinition warnings. -#define WIN32_LEAN_AND_MEAN -#include - -#define GLFW_INCLUDE_NONE // Do not include OpenGL headers. -#include - -namespace dx -{ - -class Window -{ -public: - ~Window(); - - /// Creates the window. - bool Initialise(int width, int height, const char* title); - - /// Returns the native window handle. - /// If the window has not been initialized, returns an invalid handle. - HWND GetWindowHandle(); - - /// Updates the window by polling for user input. - void Update(); - - /// Returns true if the user tried to close the window, false otherwise. - bool ShouldClose() const; - -private: - GLFWwindow* m_window = nullptr; -}; - -/// Initialise the window subsystem. -/// -/// This function must be called at the start of your application before any -/// Windows are created. -bool WindowInitialise(); - -/// Terminate the window subsystem. -/// -/// This function should be called at the end of your application. Any existing -/// Windows are destroyed and are invalid beyond this call. -void WindowTerminate(); - -/// Returns the last Window error. -const char* GetWindowError(); - -} // namespace dx diff --git a/dxwindow/src/dxwindow.cc b/dxwindow/src/dxwindow.cc deleted file mode 100644 index 8848a7e..0000000 --- a/dxwindow/src/dxwindow.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include "dxwindow.h" - -#define GLFW_EXPOSE_NATIVE_WIN32 -#include - -#include -#include - -namespace dx -{ - -static char glfw_error[1024] = {}; - -static void glfw_error_callback(int error, const char* description) -{ - sprintf_s(glfw_error, sizeof(glfw_error), - "GLFW error %d: %s", error, description); -} - -Window::~Window() -{ - if (m_window != nullptr) - { - glfwDestroyWindow(m_window); - } -} - -bool Window::Initialise(int width, int height, const char* title) -{ - // GLFW by default creates an OpenGL context with the window. - // Use GLFW_NO_API to tell it not to do so. - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - - if ((m_window = glfwCreateWindow( - width, height, title, /*monitor=*/NULL, /*share=*/NULL)) == nullptr) - { - return false; - } - - return true; -} - -HWND Window::GetWindowHandle() -{ - if (!m_window) - { - return NULL; - } - return glfwGetWin32Window(m_window); -} - -void Window::Update() -{ - assert(m_window); - glfwPollEvents(); -} - -bool Window::ShouldClose() const -{ - assert(m_window); - return glfwWindowShouldClose(m_window) == GLFW_TRUE; -} - -bool WindowInitialise() -{ - glfwSetErrorCallback(glfw_error_callback); - return glfwInit() == GLFW_TRUE; -} - -void WindowTerminate() -{ - glfwTerminate(); -} - -const char* GetWindowError() -{ - return glfw_error; -} - -} // namespace dx diff --git a/hello/CMakeLists.txt b/hello/CMakeLists.txt index 90a0d78..ac9f285 100644 --- a/hello/CMakeLists.txt +++ b/hello/CMakeLists.txt @@ -1,7 +1,10 @@ -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.25) -add_executable(hello main.cc) +project(hello) -target_link_libraries(hello +add_executable(hello + main.cc) + +target_link_libraries(hello PRIVATE dxcommon dxwindow) diff --git a/hello/main.cc b/hello/main.cc index 8e41d4b..47a2aba 100644 --- a/hello/main.cc +++ b/hello/main.cc @@ -1,14 +1,13 @@ #include -#include - -#include -#include -#include #include #include +import dxcommon; +import dxwindow; + using namespace dx; +using Microsoft::WRL::ComPtr; struct D3DSettings { -- cgit v1.2.3