From 90c0147660f6cacb954ed774832fc75f7a3722d5 Mon Sep 17 00:00:00 2001 From: light7734 Date: Fri, 14 Nov 2025 18:58:02 +0330 Subject: [PATCH] wip: convert from include style to module import style :D --- modules/CMakeLists.txt | 51 ++- modules/app/system.cppm | 4 +- modules/asset_baker/bakers.cppm | 22 +- modules/ecs/registry.cppm | 11 +- modules/logger/logger.cppm | 4 +- modules/surface/components.cppm | 11 +- modules/surface/constants.cppm | 7 + modules/surface/platform_linux.cpp | 2 +- modules/surface/platform_windows.cpp | 553 ++++++++++++++++++++++----- modules/surface/system.test.cpp | 1 - tools/cmake/definitions.cmake | 2 + 11 files changed, 545 insertions(+), 123 deletions(-) create mode 100644 modules/surface/constants.cppm diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 2f7306c..094fa2d 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,3 +1,11 @@ +add_library_module(NAME logger INTERFACES logger.cppm) +add_library_module(NAME bitwise INTERFACES operations.cppm) +add_library_module(NAME env INTERFACES constants.cppm) +add_library_module( + NAME memory INTERFACES null_on_move.cppm reference.cppm scope.cppm +) +add_library_module(NAME time INTERFACES timer.cppm) + add_library_module( NAME test @@ -11,18 +19,6 @@ add_library_module( logger ) -add_library_module(NAME logger INTERFACES logger.cppm) - -add_library_module(NAME bitwise INTERFACES operations.cppm) - -add_library_module(NAME env INTERFACES constants.cppm) - -add_library_module( - NAME memory INTERFACES null_on_move.cppm reference.cppm scope.cppm -) - -add_library_module(NAME time INTERFACES timer.cppm) - add_library_module( NAME lt_debug @@ -104,11 +100,36 @@ add_library_module( memory ) -if(NOT WIN32) +if(WIN32) add_library_module( NAME surface INTERFACES + constants.cppm + system.cppm + requests.cppm + events.cppm + components.cppm + SOURCES + platform_windows.cpp + DEPENDENCIES + ecs + app + math + memory + tbb + PRIVATE_DEPENDENCIES + logger + lt_debug + time + ) + +elseif(UNIX) + add_library_module( + NAME + surface + INTERFACES + constants.cppm system.cppm requests.cppm events.cppm @@ -127,7 +148,9 @@ if(NOT WIN32) lt_debug time ) + else() + message(FATAL "Failed to generate cmake: unsupported platform") endif() @@ -176,6 +199,8 @@ add_library_module( surface ) +return() + add_library_module( NAME libmirror diff --git a/modules/app/system.cppm b/modules/app/system.cppm index 885f156..f0a731e 100644 --- a/modules/app/system.cppm +++ b/modules/app/system.cppm @@ -69,9 +69,9 @@ export class SystemStats public: void push_diagnosis(SystemDiagnosis &&diagnosis) { - auto diag = m_diagnosis.emplace_back(std::move(diagnosis)); + auto &diag = m_diagnosis.emplace_back(std::move(diagnosis)); - log::debug("message: {}", diag.message); + log::info("message: {}", std::string { diag.message }); } [[nodiscard]] auto empty_diagnosis() const -> bool diff --git a/modules/asset_baker/bakers.cppm b/modules/asset_baker/bakers.cppm index 59823e8..522ce59 100644 --- a/modules/asset_baker/bakers.cppm +++ b/modules/asset_baker/bakers.cppm @@ -15,26 +15,24 @@ export void bake_shader( using lt::assets::ShaderAsset; using enum lt::assets::ShaderAsset::Type; - auto glsl_path = in_path.string(); + auto glsl_path = std::string { in_path.string() }; auto spv_path = std::format("{}.spv", glsl_path); lt::log::trace( "Compiling {} shader {} -> {}", type == vertex ? "vertex" : "fragment", - glsl_path, - spv_path + std::string { glsl_path }, + std::string { spv_path } ); // Don't bother linking to shaderc, just invoke the command with a system call. // NOLINTNEXTLINE(concurrency-mt-unsafe) - std::system( - std::format( - "glslc --target-env=vulkan1.4 -std=450core -fshader-stage={} {} -o {}", - type == vertex ? "vert" : "frag", - glsl_path, - spv_path - ) - .c_str() - ); + std::system(std::format( + "glslc --target-env=vulkan1.4 -std=450core -fshader-stage={} {} -o {}", + type == vertex ? "vert" : "frag", + glsl_path, + spv_path + ) + .c_str()); auto stream = std::ifstream(spv_path, std::ios::binary); lt::debug::ensure( diff --git a/modules/ecs/registry.cppm b/modules/ecs/registry.cppm index 1784352..6b47bf0 100644 --- a/modules/ecs/registry.cppm +++ b/modules/ecs/registry.cppm @@ -251,11 +251,16 @@ private: TypeId m_entity_count; - std::flat_map> m_sparsed_sets; + /** MSVC DOES NOT SUPPORT FLAT MAP!! + * IT"S YEAR ~2026, great... + * using ::std::map for the time being. + */ - std::flat_map m_on_construct_hooks; + std::map> m_sparsed_sets; - std::flat_map m_on_destruct_hooks; + std::map m_on_construct_hooks; + + std::map m_on_destruct_hooks; }; } // namespace lt::ecs diff --git a/modules/logger/logger.cppm b/modules/logger/logger.cppm index eb29f0c..4e39d8c 100644 --- a/modules/logger/logger.cppm +++ b/modules/logger/logger.cppm @@ -52,7 +52,7 @@ struct [[maybe_unused]] print // clang-format off switch (level) { - using enum Level; + using enum ::lt::log::Level; case trace : return "\033[1;37m| trc |\033[0m"; case debug : return "\033[1;36m| dbg |\033[0m"; case info : return "\033[1;32m| inf |\033[0m"; @@ -71,7 +71,7 @@ struct [[maybe_unused]] print std::println( "{} {} ==> {}", to_string(level, location), - std::format("{}:{}", path.filename().c_str(), location.line()), + std::format("{}:{}", path.filename().string(), location.line()), std::format(format, std::forward(arguments)...) ); } diff --git a/modules/surface/components.cppm b/modules/surface/components.cppm index 0bffa16..527decf 100644 --- a/modules/surface/components.cppm +++ b/modules/surface/components.cppm @@ -1,6 +1,8 @@ module; -#ifdef LIGHT_PLATFORM_LINUX +#if defined(LIGHT_PLATFORM_LINUX) typedef struct _XDisplay Display; +#else defined(LIGHT_PLATFORM_WINDOWS) + #include #endif export module surface.system:components; @@ -38,13 +40,18 @@ public: ModifyPositionRequest, ModifyVisibilityRequest>; -#ifdef LIGHT_PLATFORM_LINUX +#if defined(LIGHT_PLATFORM_LINUX) struct NativeData { Display *display; std::uint32_t window; unsigned long wm_delete_message; }; +#elif defined(LIGHT_PLATFORM_WINDOWS) + struct NativeData + { + HWND window; + }; #endif static constexpr auto max_dimension = 4096; diff --git a/modules/surface/constants.cppm b/modules/surface/constants.cppm new file mode 100644 index 0000000..76b899b --- /dev/null +++ b/modules/surface/constants.cppm @@ -0,0 +1,7 @@ +export module surface.constants; + +export namespace lt::surface::constants { + +constexpr auto *class_name = "light_engine_window_class_name:3"; + +} diff --git a/modules/surface/platform_linux.cpp b/modules/surface/platform_linux.cpp index 946908a..412dc6b 100644 --- a/modules/surface/platform_linux.cpp +++ b/modules/surface/platform_linux.cpp @@ -75,7 +75,7 @@ System::~System() try { - // TODO(Light): make registry.remove not validate iterators + // TODO(Light): make registry.remove not invalidate iterators auto entities_to_remove = std::vector {}; for (auto &[entity, surface] : m_registry->view()) { diff --git a/modules/surface/platform_windows.cpp b/modules/surface/platform_windows.cpp index 2a156e0..f95fc8f 100644 --- a/modules/surface/platform_windows.cpp +++ b/modules/surface/platform_windows.cpp @@ -1,139 +1,508 @@ -#include -#include -#include +module; +#include +module surface.system; +import surface.constants; +import debug.assertions; +import memory.reference; +import surface.requests; +import surface.events; +import logger; +import ecs.registry; +import ecs.entity; +import time; +import std; namespace lt::surface { -System::System(memory::Ref registry, memory::Ref event_mediator) - : m_registry(std::move(registry)) - , m_event_mediator(std::move(event_mediator)) +template +struct overloads: Ts... { - ensure(m_registry, "Failed to initialize surface system: null registry"); + using Ts::operator()...; +}; - ensure( - m_registry->view().size() == 0, +void ensure_component_sanity(const SurfaceComponent &component); + +auto CALLBACK native_window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT; + +System::System(memory::Ref registry): m_registry(std::move(registry)) +{ + debug::ensure(m_registry, "Failed to initialize surface system: null registry"); + + debug::ensure( + m_registry->view().get_size() == 0, "Failed to initialize surface system: registry has surface component(s)" ); - m_registry->get_entt_registry() - .on_construct() - .connect<&System::on_surface_construct>(this); + m_registry->connect_on_destruct( + [this](ecs::Registry ®istry, ecs::EntityId entity) { + on_surface_destruct(registry, entity); + } + ); - m_registry->get_entt_registry() - .on_update() - .connect<&System::on_surface_update>(this); - - m_registry->get_entt_registry() - .on_destroy() - .connect<&System::on_surface_destroy>(this); + auto window_class = WNDCLASS { + .lpfnWndProc = native_window_proc, + .hInstance = GetModuleHandle(nullptr), + .lpszClassName = constants::class_name, + }; + RegisterClass(&window_class); } System::~System() { - m_registry->get_entt_registry() - .on_construct() - .disconnect<&System::on_surface_construct>(this); + if (!m_registry) + { + return; + } - m_registry->get_entt_registry() - .on_update() - .connect<&System::on_surface_update>(this); - - m_registry->get_entt_registry() - .on_destroy() - .disconnect<&System::on_surface_destroy>(this); - - - m_registry->view().each([&](const entt::entity entity, SurfaceComponent &) { - m_registry->get_entt_registry().remove(entity); - }); -} - -void System::on_surface_construct(entt::registry ®istry, entt::entity entity) -{ try { - auto &surface = registry.get(entity); - const auto &resolution = surface.get_resolution(); - const auto &position = surface.get_position(); - ensure_component_sanity(surface); + // TODO(Light): make registry.remove not invalidate iterators + auto entities_to_remove = std::vector {}; + for (auto &[entity, surface] : m_registry->view()) + { + entities_to_remove.emplace_back(entity); + } + + for (auto entity : entities_to_remove) + { + m_registry->remove(entity); + } + + m_registry->disconnect_on_construct(); + m_registry->disconnect_on_destruct(); } - catch (...) + catch (const std::exception &exp) { - registry.remove(entity); - throw; + log::error("Uncaught exception in surface::~System:"); + log::error("\twhat: {}", exp.what()); } } -void System::on_surface_update(entt::registry ®istry, entt::entity entity) +void System::on_register() { - auto &surface = registry.get(entity); } -void System::on_surface_destroy(entt::registry ®istry, entt::entity entity) +void System::on_unregister() { - auto &surface = registry.get(entity); } -void System::set_title(ecs::Entity entity, std::string_view new_title) +void System::create_surface_component(ecs::EntityId entity, SurfaceComponent::CreateInfo info) +try { - auto &surface = entity.get_component(); + auto &component = m_registry->add(entity, info); + auto &surface = m_registry->get(entity); + const auto &resolution = surface.get_resolution(); + const auto &position = surface.get_position(); + ensure_component_sanity(surface); - surface.m_title = new_title; + surface.m_native_data.window = CreateWindowEx( + 0, + constants::class_name, + info.title.data(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + nullptr, + nullptr, + GetModuleHandle(nullptr), + nullptr + ); + debug::ensure(surface.m_native_data.window, "Failed to create Windows surface component"); + + ShowWindow(surface.m_native_data.window, SW_NORMAL); + + // TODO(Light): refactor "environment" into standalone module + // NOLINTNEXTLINE(concurrency-mt-unsafe) + // auto *display_env = std::getenv("DISPLAY"); + // debug::ensure(display_env != nullptr, "DISPLAY env var not found!"); + // + // auto *display = XOpenDisplay(display_env); + // debug::ensure(display, "Failed to open XDisplay with DISPLAY: {}", display_env); + // + // auto root_window = XDefaultRootWindow(display); + // + // auto border_width = 0; + // auto depth = std::int32_t { CopyFromParent }; + // auto window_class = CopyFromParent; + // auto *visual = (Visual *)CopyFromParent; + // + // auto attribute_value_mask = CWBackPixel | CWEventMask; + // auto attributes = XSetWindowAttributes { + // .background_pixel = 0xffafe9af, + // .event_mask = all_events_mask, + // }; + // + // typedef struct Hints + // { + // unsigned long flags; + // unsigned long functions; + // unsigned long decorations; + // long inputMode; + // unsigned long status; + // } Hints; + // + // auto main_window = XCreateWindow( + // display, + // root_window, + // position.x, + // position.y, + // resolution.x, + // resolution.y, + // border_width, + // depth, + // window_class, + // visual, + // attribute_value_mask, + // &attributes + // ); + // surface.m_native_data.display = display; + // surface.m_native_data.window = main_window; + // + // surface.m_native_data.wm_delete_message = XInternAtom(display, "WM_DELETE_WINDOW", False); + // XSetWMProtocols(display, main_window, &surface.m_native_data.wm_delete_message, 1); + // + // // code to remove decoration + // auto hints = std::array { 2, 0, 0, 0, 0 }; + // const auto motif_hints = XInternAtom(display, "_MOTIF_WM_HINTS", False); + // + // XChangeProperty( + // display, + // surface.m_native_data.window, + // motif_hints, + // motif_hints, + // 32, + // PropModeReplace, + // hints.data(), + // 5 + // ); + // + // XMapWindow(display, main_window); + // XStoreName(display, main_window, surface.m_title.c_str()); + // XFlush(display); + // + // if (!surface.is_visible()) + // { + // XUnmapWindow(display, main_window); + // } +} +catch (const std::exception &exp) +{ + log::error("Exception thrown when on_constructing surface component"); + log::error("\tentity: {}", std::uint32_t { entity }); + log::error("\twhat: {}", exp.what()); + m_registry->remove(entity); } -auto System::tick() -> bool +void System::on_surface_destruct(ecs::Registry ®istry, ecs::EntityId entity) { - return false; -} - -void System::set_size(ecs::Entity surface_entity, const math::uvec2 &new_size) -{ - auto &surface = surface_entity.get_component(); - surface.m_resolution = new_size; -} - -void System::set_v_sync(ecs::Entity surface_entity, bool vsync) -{ - auto &surface = surface_entity.get_component(); - surface.m_vsync = vsync; -} - -void System::set_visibility(ecs::Entity surface_entity, bool visible) -{ - auto &surface = surface_entity.get_component(); - surface.m_visible = visible; - - if (visible) - { - } - else + auto *window = registry.get(entity).get_native_data().window; + if (!window) { + log::warn("Surface component destroyed with null window handle"); + return; } + + DestroyWindow(window); } -void System::ensure_component_sanity(const SurfaceComponent &component) +void System::handle_events(SurfaceComponent &surface) +{ + auto &queue = surface.m_event_queue; + queue.clear(); + + auto message = MSG {}; + while (PeekMessage(&message, 0, {}, {}, PM_REMOVE)) + { + switch (message.message) + { + } + + log::debug("Window message type: {}", std::uint32_t { message.message }); + } + + // auto event = XEvent {}; + // auto &[display, window, wm_delete_message] = surface.m_native_data; + // + // XFlush(display); + // while (XEventsQueued(display, QueuedAlready) != 0) + // { + // XNextEvent(surface.m_native_data.display, &event); + // + // switch (event.type) + // { + // case KeyPress: + // { + // queue.emplace_back( + // static_cast(XLookupKeysym(&event.xkey, 0)) + // ); + // break; + // } + // case KeyRelease: + // { + // queue.emplace_back( + // static_cast(XLookupKeysym(&event.xkey, 0)) + // ); + // break; + // } + // case ButtonPress: + // { + // queue.emplace_back(static_cast(event.xbutton.button)); + // break; + // } + // case ButtonRelease: + // { + // queue.emplace_back(static_cast(event.xbutton.button)); + // break; + // } + // case FocusIn: + // { + // queue.emplace_back({}); + // break; + // } + // case FocusOut: + // { + // queue.emplace_back({}); + // break; + // } + // case ClientMessage: + // { + // if (event.xclient.data.l[0] == wm_delete_message) + // { + // queue.emplace_back({}); + // } + // + // break; + // } + // case MotionNotify: + // { + // queue.emplace_back(MouseMovedEvent { + // static_cast(event.xmotion.x), + // static_cast(event.xmotion.y), + // }); + // break; + // } + // case ConfigureNotify: + // { + // const auto [prev_width, prev_height] = surface.get_resolution(); + // const auto new_width = event.xconfigure.width; + // const auto new_height = event.xconfigure.height; + // if (prev_width != new_width || prev_height != new_height) + // { + // surface.m_resolution.x = new_width; + // surface.m_resolution.y = new_height; + // queue.emplace_back(ResizedEvent { + // static_cast(new_width), + // static_cast(new_height), + // }); + // } + // + // const auto [prev_x, prev_y] = surface.get_position(); + // const auto new_x = event.xconfigure.x; + // const auto new_y = event.xconfigure.y; + // if (prev_x != new_x || prev_y != new_y) + // { + // surface.m_position.x = new_x; + // surface.m_position.y = new_y; + // queue.emplace_back(MovedEvent { + // new_x, + // new_y, + // }); + // } + // break; + // } + // + // default: break; /* pass */ + // } + // } +} + +void System::handle_requests(SurfaceComponent &surface) +{ + const auto visitor = overloads { + [&](const ModifyTitleRequest &request) { modify_title(surface, request); }, + [&](const ModifyResolutionRequest &request) { modify_resolution(surface, request); }, + [&](const ModifyPositionRequest &request) { modify_position(surface, request); }, + [&](const ModifyVisibilityRequest &request) { modify_visiblity(surface, request); }, + [&](const auto &) { log::error("Unknown surface request"); }, + }; + + for (const auto &request : surface.peek_requests()) + { + std::visit(visitor, request); + } + + surface.m_requests.clear(); +} + +void System::modify_title(SurfaceComponent &surface, const ModifyTitleRequest &request) +{ + surface.m_title = request.title; + + // const auto &[display, window, _] = surface.get_native_data(); + // XStoreName(display, window, request.title.c_str()); +} + +void System::modify_resolution(SurfaceComponent &surface, const ModifyResolutionRequest &request) +{ + // surface.m_resolution = request.resolution; + + // auto &[display, window, _] = surface.m_native_data; + // const auto &[width, height] = request.resolution; + // // XResizeWindow(display, window, width, height); + // + // // get baseline serial number for X requests generated from XResizeWindow + // auto serial = NextRequest(display); + // + // // request a new window size from the X server + // XResizeWindow( + // display, + // window, + // static_cast(width), + // static_cast(height) + // ); + // + // // flush output queue and wait for X server to processes the request + // XSync(display, False); + // // The documentation for XResizeWindow includes this important note: + // // + // // If the override-redirect flag of the window is False and some + // // other client has selected SubstructureRedirectMask on the parent, + // // the X server generates a ConfigureRequest event, and no further + // // processing is performed. + // // + // // What this means, essentially, is that if this window is a top-level + // // window, then it's the window manager (the "other client") that is + // // responsible for changing this window's size. So when we call + // // XResizeWindow() on a top-level window, then instead of resizing + // // the window immediately, the X server informs the window manager, + // // and then the window manager sets our new size (usually it will be + // // the size we asked for). We receive a ConfigureNotify event when + // // our new size has been set. + // constexpr auto lifespan = std::chrono::milliseconds { 10 }; + // auto timer = time::Timer {}; + // auto event = XEvent {}; + // while (!XCheckIfEvent( + // display, + // &event, + // XEventTypeEquals, + // reinterpret_cast(&window) // NOLINT + // ) + // || event.xconfigure.serial < serial) + // { + // std::this_thread::sleep_for(std::chrono::microseconds { 100 }); + // if (timer.elapsed_time() > lifespan) + // { + // log::error("Timed out waiting for XResizeWindow's event"); + // return; + // } + // } + // // We don't need to update the component's state and handle the event in this funcion. + // // Since handle_requests is called before handle_events. + // // So we just put the event back into the queue and move on. + // XPutBackEvent(display, &event); + // XSync(display, False); + // XFlush(display); +} + +void System::modify_position(SurfaceComponent &surface, const ModifyPositionRequest &request) +{ + // surface.m_position = request.position; + + // auto &[display, window, _] = surface.m_native_data; + // const auto &[x, y] = request.position; + // + // // get baseline serial number for X requests generated from XResizeWindow + // auto serial = NextRequest(display); + // XMoveWindow(display, window, static_cast(x), static_cast(y)); + // + // // flush output queue and wait for X server to processes the request + // XSync(display, False); + // constexpr auto lifespan = std::chrono::milliseconds { 10 }; + // auto timer = time::Timer {}; + // auto event = XEvent {}; + // while (!XCheckIfEvent( + // display, + // &event, + // XEventTypeEquals, + // reinterpret_cast(&window) // NOLINT + // ) + // || event.xconfigure.serial < serial) + // { + // std::this_thread::sleep_for(std::chrono::microseconds { 100 }); + // if (timer.elapsed_time() > lifespan) + // { + // log::error("Timed out waiting for XMoveWindow's event"); + // return; + // } + // } + // // We don't need to update the component's state and handle the event in this funcion. + // // Since handle_requests is called before handle_events. + // // So we just put the event back into the queue and move on. + // XPutBackEvent(display, &event); + // XSync(display, False); + // XFlush(display); +} + +void System::modify_visiblity(SurfaceComponent &surface, const ModifyVisibilityRequest &request) +{ + // const auto &[display, window, _] = surface.get_native_data(); + // surface.m_visible = request.visible; + + // if (request.visible) + // { + // XMapWindow(display, window); + // } + // else + // { + // XUnmapWindow(display, window); + // } +} + +void System::tick(app::TickInfo tick) +{ + for (auto &[id, surface] : m_registry->view()) + { + handle_requests(surface); + handle_events(surface); + } + + const auto now = std::chrono::steady_clock::now(); + m_last_tick_result = app::TickResult { + .info = tick, + .duration = now - tick.start_time, + .end_time = now, + }; +} + +void ensure_component_sanity(const SurfaceComponent &component) { auto [width, height] = component.get_resolution(); - ensure(width != 0u, "Received bad values for surface component: width({}) == 0", width); + debug::ensure(width != 0u, "Received bad values for surface component: width({}) == 0", width); - ensure(height != 0u, "Received bad values for surface component: height({}) == 0", height); + debug::ensure( + height != 0u, + "Received bad values for surface component: height({}) == 0", + height + ); - ensure( + debug::ensure( width < SurfaceComponent::max_dimension, "Received bad values for surface component: width({}) > max_dimension({})", width, SurfaceComponent::max_dimension ); - ensure( + debug::ensure( height < SurfaceComponent::max_dimension, "Received bad values for surface component: height({}) > max_dimension({})", height, SurfaceComponent::max_dimension ); - ensure( + debug::ensure( component.get_title().size() < SurfaceComponent::max_title_length, "Received bad values for surface component: title.size({}) > max_title_length({})", component.get_title().size(), @@ -141,8 +510,18 @@ void System::ensure_component_sanity(const SurfaceComponent &component) ); } +auto CALLBACK native_window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT +{ + switch (uMsg) + { + case WM_DESTROY: + { + PostQuitMessage(0); + return 0; + } + } + + return DefWindowProcA(hwnd, uMsg, wParam, lParam); +} + } // namespace lt::surface - -namespace lt { - -} // namespace lt diff --git a/modules/surface/system.test.cpp b/modules/surface/system.test.cpp index 2b5b07d..aab181b 100644 --- a/modules/surface/system.test.cpp +++ b/modules/surface/system.test.cpp @@ -11,7 +11,6 @@ import math.vec2; import app.system; import std; - using ::lt::surface::SurfaceComponent; using ::lt::surface::System; using ::lt::test::Case; diff --git a/tools/cmake/definitions.cmake b/tools/cmake/definitions.cmake index 6dfda8e..3bbb44d 100644 --- a/tools/cmake/definitions.cmake +++ b/tools/cmake/definitions.cmake @@ -2,4 +2,6 @@ if(WIN32) add_compile_definitions(LIGHT_PLATFORM_WINDOWS) elseif(UNIX) add_compile_definitions(LIGHT_PLATFORM_LINUX) +else() + message(FATAL "Failed to generate cmake: unsupported platform") endif()