fix: compilation on gcc & clang
Some checks reported errors
continuous-integration/drone/push Build was killed

This commit is contained in:
light7734 2026-02-12 16:41:24 +03:30
parent 1dffe41180
commit d3d315e22d
Signed by: light7734
GPG key ID: 85541DEAEB3DF469
6 changed files with 249 additions and 68 deletions

View file

@ -88,8 +88,7 @@ constexpr auto total_metadata_size = //
+ sizeof(BlobMetadata::compressed_size) // + sizeof(BlobMetadata::compressed_size) //
+ sizeof(BlobMetadata::uncompressed_size); + sizeof(BlobMetadata::uncompressed_size);
ShaderAsset::ShaderAsset(const std::filesystem::path &path) ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path, std::ios::binary)
: m_stream(path, std::ios::beg | std::ios::binary)
{ {
ensure(m_stream.is_open(), "Failed to open shader asset at: {}", path.string()); ensure(m_stream.is_open(), "Failed to open shader asset at: {}", path.string());
const auto read = [this](auto &field) { const auto read = [this](auto &field) {

View file

@ -70,6 +70,7 @@ struct [[maybe_unused]] print
case warn : return "\033[1;33m| wrn |\033[0m"; case warn : return "\033[1;33m| wrn |\033[0m";
case error : return "\033[1;31m| err |\033[0m"; case error : return "\033[1;31m| err |\033[0m";
case critical: return "\033[1;41m| crt |\033[0m"; case critical: return "\033[1;41m| crt |\033[0m";
case test: /* testing framework's logs will never have location */
case off: return "off"; case off: return "off";
} }
// clang-format on // clang-format on

View file

@ -6,6 +6,8 @@ import renderer.frontend;
import surface.system; import surface.system;
import surface.events; import surface.events;
import surface.requests; import surface.requests;
import ecs.entity;
import input.codes;
import ecs.registry; import ecs.registry;
import memory.scope; import memory.scope;
import memory.reference; import memory.reference;
@ -83,7 +85,6 @@ try
debug_callback_info, debug_callback_info,
} }; } };
registry.add_
auto should_close = false; auto should_close = false;
const auto visitor = overloads { const auto visitor = overloads {

View file

@ -2,6 +2,8 @@ module;
#if defined(LIGHT_PLATFORM_LINUX) #if defined(LIGHT_PLATFORM_LINUX)
struct wl_display; struct wl_display;
struct wl_surface; struct wl_surface;
struct xdg_surface;
struct xdg_toplevel;
#else defined(LIGHT_PLATFORM_WINDOWS) #else defined(LIGHT_PLATFORM_WINDOWS)
#include <Windows.h> #include <Windows.h>
#endif #endif
@ -46,6 +48,10 @@ public:
wl_display *display; wl_display *display;
wl_surface *surface; wl_surface *surface;
xdg_surface *shell_surface;
xdg_toplevel *shell_toplevel;
}; };
#elif defined(LIGHT_PLATFORM_WINDOWS) #elif defined(LIGHT_PLATFORM_WINDOWS)
struct NativeData struct NativeData
@ -62,7 +68,7 @@ public:
// TODO(Light): add `screen_mode` flag (windowed/full_screen/windowed_full_screen) // TODO(Light): add `screen_mode` flag (windowed/full_screen/windowed_full_screen)
struct CreateInfo struct CreateInfo
{ {
std::string_view title; std::string title;
math::vec2_i32 position; math::vec2_i32 position;
@ -73,7 +79,7 @@ public:
bool visible; bool visible;
}; };
[[nodiscard]] auto get_title() const -> std::string_view [[nodiscard]] auto get_title() const -> std::string // yes copy the title, whatever...
{ {
return m_title; return m_title;
} }

View file

@ -169,8 +169,6 @@ private:
void modify_visibility(SurfaceComponent &surface, const ModifyVisibilityRequest &request); void modify_visibility(SurfaceComponent &surface, const ModifyVisibilityRequest &request);
void set_visibility(ecs::EntityId surface_entity, bool visible);
memory::Ref<ecs::Registry> m_registry; memory::Ref<ecs::Registry> m_registry;
app::TickResult m_last_tick_result {}; app::TickResult m_last_tick_result {};
@ -207,8 +205,17 @@ private:
module :private; module :private;
namespace lt::surface { namespace lt::surface {
#if defined(LIGHT_PLATFORM_LINUX) #if defined(LIGHT_PLATFORM_LINUX)
template<class... Ts>
struct overloads: Ts...
{
using Ts::operator()...;
};
void ensure_component_sanity(const SurfaceComponent &component);
void handle_shell_ping(void *data, xdg_wm_base *shell, u32 serial) void handle_shell_ping(void *data, xdg_wm_base *shell, u32 serial)
{ {
ignore = data; ignore = data;
@ -222,6 +229,7 @@ void handle_shell_surface_configure(void *data, xdg_surface *shell_surface, u32
{ {
ignore = data; ignore = data;
log::test("Surface configure: {}", (i32)serial);
xdg_surface_ack_configure(shell_surface, serial); xdg_surface_ack_configure(shell_surface, serial);
} }
const auto shell_surface_listener = xdg_surface_listener { const auto shell_surface_listener = xdg_surface_listener {
@ -237,7 +245,9 @@ void handle_toplevel_configure(
) )
{ {
// TODO(Light): handle resizing // TODO(Light): handle resizing
log::test("Toplevel configure: {}x{}", (i32)width, (i32)height);
} }
void handle_toplevel_close(void *data, xdg_toplevel *toplevel) void handle_toplevel_close(void *data, xdg_toplevel *toplevel)
{ {
// TODO(Light): handle quitting // TODO(Light): handle quitting
@ -325,6 +335,7 @@ void wayland_pointer_leave_listener(
u32 state u32 state
) )
{ {
log::debug("Pointer button");
} }
/* static */ void System::wayland_pointer_axis_listener( /* static */ void System::wayland_pointer_axis_listener(
@ -335,6 +346,7 @@ void wayland_pointer_leave_listener(
wl_fixed_t value wl_fixed_t value
) )
{ {
log::debug("Pointer axis listener");
} }
/* static */ void System::wayland_pointer_axis_source_listener( /* static */ void System::wayland_pointer_axis_source_listener(
@ -343,6 +355,7 @@ void wayland_pointer_leave_listener(
u32 axis_source u32 axis_source
) )
{ {
log::debug("Pointer axis source listener");
} }
/* static */ void System::wayland_pointer_axis_stop_listener( /* static */ void System::wayland_pointer_axis_stop_listener(
@ -352,6 +365,7 @@ void wayland_pointer_leave_listener(
u32 axis_source u32 axis_source
) )
{ {
log::debug("Pointer axis stop listener");
} }
/* static */ void System::wayland_pointer_axis_discrete_listener( /* static */ void System::wayland_pointer_axis_discrete_listener(
@ -361,6 +375,7 @@ void wayland_pointer_leave_listener(
i32 discrete i32 discrete
) )
{ {
log::debug("Pointer axis discrete listener");
} }
/* static */ void System::wayland_pointer_frame_listener(void *data, wl_pointer *pointer) /* static */ void System::wayland_pointer_frame_listener(void *data, wl_pointer *pointer)
@ -451,7 +466,8 @@ System::System(memory::Ref<ecs::Registry> registry)
} }
) )
{ {
// NOLINTNEXTLINE ensure(m_registry, "Failed to construct surface::System: null ecs::Registry");
m_wl_display = wl_display_connect({}); m_wl_display = wl_display_connect({});
ensure(m_wl_display, "Failed to connect to Wayland display"); ensure(m_wl_display, "Failed to connect to Wayland display");
@ -477,6 +493,29 @@ System::~System()
{ {
return; return;
} }
try
{
/** @todo(Light): make registry.remove not invalidate iterators */
auto entities_to_remove = std::vector<ecs::EntityId> {};
for (auto &[entity, surface] : m_registry->view<SurfaceComponent>())
{
entities_to_remove.emplace_back(entity);
}
for (auto entity : entities_to_remove)
{
m_registry->remove<SurfaceComponent>(entity);
}
m_registry->disconnect_on_construct<SurfaceComponent>();
m_registry->disconnect_on_destruct<SurfaceComponent>();
}
catch (const std::exception &exp)
{
log::error("Uncaught exception in surface::~System:");
log::error("\twhat: {}", exp.what());
}
} }
void System::on_register() void System::on_register()
@ -490,15 +529,18 @@ void System::on_unregister()
} }
void System::create_surface_component(ecs::EntityId entity, SurfaceComponent::CreateInfo info) void System::create_surface_component(ecs::EntityId entity, SurfaceComponent::CreateInfo info)
try
{ {
auto &component = m_registry->add<SurfaceComponent>(entity, info); auto &component = m_registry->add<SurfaceComponent>(entity, info);
ensure_component_sanity(component);
auto &surface = m_registry->get<SurfaceComponent>(entity); auto &surface = m_registry->get<SurfaceComponent>(entity);
const auto &resolution = surface.get_resolution(); const auto &resolution = surface.get_resolution();
const auto &position = surface.get_position(); const auto &position = surface.get_position();
auto *wayland_surface = (wl_surface *)nullptr; auto *wayland_surface = (wl_surface *)nullptr;
auto *shell_surface = (xdg_surface *)nullptr;
auto *shell_toplevel = (xdg_toplevel *)nullptr; auto *shell_toplevel = (xdg_toplevel *)nullptr;
auto *shell_surface = (xdg_surface *)nullptr;
wayland_surface = wl_compositor_create_surface(m_wl_compositor); wayland_surface = wl_compositor_create_surface(m_wl_compositor);
ensure(wayland_surface, "Failed to create Wayland surface"); ensure(wayland_surface, "Failed to create Wayland surface");
@ -511,7 +553,7 @@ void System::create_surface_component(ecs::EntityId entity, SurfaceComponent::Cr
ensure(shell_toplevel, "Failed to get XDG-shell toplevel"); ensure(shell_toplevel, "Failed to get XDG-shell toplevel");
xdg_toplevel_add_listener(shell_toplevel, &toplevel_listener, {}); xdg_toplevel_add_listener(shell_toplevel, &toplevel_listener, {});
xdg_toplevel_set_title(shell_toplevel, "Wayland Vulkan Example"); xdg_toplevel_set_title(shell_toplevel, info.title.c_str());
xdg_toplevel_set_app_id(shell_toplevel, "Wayland Vulkan Example"); xdg_toplevel_set_app_id(shell_toplevel, "Wayland Vulkan Example");
wl_surface_commit(wayland_surface); wl_surface_commit(wayland_surface);
@ -520,11 +562,136 @@ void System::create_surface_component(ecs::EntityId entity, SurfaceComponent::Cr
surface.m_native_data.surface = wayland_surface; surface.m_native_data.surface = wayland_surface;
surface.m_native_data.display = m_wl_display; surface.m_native_data.display = m_wl_display;
surface.m_native_data.shell_surface = shell_surface;
surface.m_native_data.shell_toplevel = shell_toplevel;
}
catch (const std::exception &exp)
{
log::error("Exception thrown when on_constructing surface component");
log::error("\tentity: {}", u32 { entity });
log::error("\twhat: {}", exp.what());
m_registry->remove<SurfaceComponent>(entity);
} }
void System::tick(app::TickInfo tick) void System::tick(app::TickInfo tick)
{ {
ignore = tick;
wl_display_roundtrip(m_wl_display); wl_display_roundtrip(m_wl_display);
for (auto &[id, surface] : m_registry->view<SurfaceComponent>())
{
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 System::handle_events(SurfaceComponent &surface)
{
// WIP(Light)
ignore = surface;
auto &queue = surface.m_event_queue;
queue.clear();
const auto roundtrip = wl_display_roundtrip(m_wl_display);
ensure(roundtrip != -1, "Wayland roundtrip error"); // WIP(Light)
if (roundtrip != 0)
{
log::debug("Roundtrip: {}", (int)roundtrip);
}
}
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_visibility(surface, request); }
};
for (const auto &request : surface.peek_requests())
{
std::visit(visitor, request);
}
wl_display_roundtrip(m_wl_display);
surface.m_requests.clear();
}
void System::modify_title(SurfaceComponent &surface, const ModifyTitleRequest &request)
{
auto *toplevel = surface.m_native_data.shell_toplevel;
ensure(toplevel, "Failed to modify surface title: null shell toplevel");
ensure(!request.title.empty(), "Failed to modify surface title: null titlle");
xdg_toplevel_set_title(toplevel, request.title.c_str());
wl_surface_commit(surface.m_native_data.surface);
surface.m_title = request.title;
}
void System::modify_resolution(SurfaceComponent &surface, const ModifyResolutionRequest &request)
{
auto *toplevel = surface.m_native_data.shell_toplevel;
const auto [width, height] = request.resolution;
ensure(width, "Failed to modify resolution: invalid width: {}", width);
ensure(height, "Failed to modify resolution: invalid height: {}", height);
log::test("Modifying res: {}x{}", (u32)width, (u32)height);
xdg_toplevel_set_min_size(toplevel, width, height);
xdg_toplevel_set_max_size(toplevel, width, height);
}
void System::modify_position(SurfaceComponent &surface, const ModifyPositionRequest &request)
{
}
void System::modify_visibility(SurfaceComponent &surface, const ModifyVisibilityRequest &request)
{
}
void ensure_component_sanity(const SurfaceComponent &component)
{
const auto [width, height] = component.get_resolution();
ensure(width != 0u, "Received bad values for surface component: width({}) == 0", width);
ensure(height != 0u, "Received bad values for surface component: height({}) == 0", height);
ensure(
width < SurfaceComponent::max_dimension,
"Received bad values for surface component: width({}) > max_dimension({})",
width,
SurfaceComponent::max_dimension
);
ensure(
height < SurfaceComponent::max_dimension,
"Received bad values for surface component: height({}) > max_dimension({})",
height,
SurfaceComponent::max_dimension
);
ensure(
component.get_title().size() < SurfaceComponent::max_title_length,
"Received bad values for surface component: title.size({}) > max_title_length({})",
component.get_title().size(),
SurfaceComponent::max_title_length
);
} }
#endif #endif
@ -575,7 +742,7 @@ System::~System()
try try
{ {
// TODO(Light): make registry.remove not invalidate iterators /** @todo(Light): make registry.remove not invalidate iterators */
auto entities_to_remove = std::vector<ecs::EntityId> {}; auto entities_to_remove = std::vector<ecs::EntityId> {};
for (auto &[entity, surface] : m_registry->view<SurfaceComponent>()) for (auto &[entity, surface] : m_registry->view<SurfaceComponent>())
{ {
@ -731,9 +898,7 @@ void System::handle_requests(SurfaceComponent &surface)
[&](const ModifyTitleRequest &request) { modify_title(surface, request); }, [&](const ModifyTitleRequest &request) { modify_title(surface, request); },
[&](const ModifyResolutionRequest &request) { modify_resolution(surface, request); }, [&](const ModifyResolutionRequest &request) { modify_resolution(surface, request); },
[&](const ModifyPositionRequest &request) { modify_position(surface, request); }, [&](const ModifyPositionRequest &request) { modify_position(surface, request); },
[&](const ModifyVisibilityRequest &request) { [&](const ModifyVisibilityRequest &request) { modify_visibility(surface, request); }
modify_visibility(surface, request);
}
}; };
for (const auto &request : surface.peek_requests()) for (const auto &request : surface.peek_requests())

View file

@ -1,3 +1,5 @@
/** @todo(Light): test pointer-invalidation of ecs using this system-> (?) */
#if defined(LIGHT_PLATFORM_LINUX) #if defined(LIGHT_PLATFORM_LINUX)
#elif defined(LIGHT_PLATFORM_WINDOWS) #elif defined(LIGHT_PLATFORM_WINDOWS)
#include <Windows.h> #include <Windows.h>
@ -55,8 +57,14 @@ public:
return m_registry; return m_registry;
} }
[[nodiscard]] auto system() -> lt::memory::Ref<System>
{
return m_system;
}
auto create_component( auto create_component(
SurfaceComponent::CreateInfo info = SurfaceComponent::CreateInfo { const SurfaceComponent::CreateInfo &info = SurfaceComponent::CreateInfo {
.title = title, .title = title,
.position = { position_x, position_y }, .position = { position_x, position_y },
.resolution = { width, height }, .resolution = { width, height },
@ -66,7 +74,7 @@ public:
) -> std::optional<SurfaceComponent *> ) -> std::optional<SurfaceComponent *>
{ {
auto entity = m_registry->create_entity(); auto entity = m_registry->create_entity();
m_system.create_surface_component(entity, info); m_system->create_surface_component(entity, info);
return &m_registry->get<SurfaceComponent>(entity); return &m_registry->get<SurfaceComponent>(entity);
} }
@ -88,13 +96,13 @@ public:
private: private:
lt::memory::Ref<lt::ecs::Registry> m_registry = lt::memory::create_ref<lt::ecs::Registry>(); lt::memory::Ref<lt::ecs::Registry> m_registry = lt::memory::create_ref<lt::ecs::Registry>();
System m_system { m_registry }; lt::memory::Ref<System> m_system = lt::memory::create_ref<System>(m_registry);
}; };
Suite raii = "raii"_suite = [] { Suite raii = "raii"_suite = [] {
Case { "happy paths" } = [] { Case { "happy paths" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
}; };
Case { "unhappy paths" } = [] { Case { "unhappy paths" } = [] {
@ -103,16 +111,17 @@ Suite raii = "raii"_suite = [] {
Case { "many" } = [] { Case { "many" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
for (auto idx : std::views::iota(0, 250)) for (auto idx : std::views::iota(0, 250))
{ {
ignore = idx; ignore = idx;
ignore = System { fixture.registry() }; ignore = fixture.system();
} }
}; };
Case { "post construct has correct state" } = [] { Case { "post construct has correct state" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0); expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
}; };
@ -131,18 +140,18 @@ Suite raii = "raii"_suite = [] {
Suite system_events = "system_events"_suite = [] { Suite system_events = "system_events"_suite = [] {
Case { "on_register won't throw" } = [] { Case { "on_register won't throw" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
system.on_register(); system->on_register();
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0); expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
}; };
Case { "on_unregister won't throw" } = [] { Case { "on_unregister won't throw" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
system.on_register(); system->on_register();
system.on_unregister(); system->on_unregister();
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0); expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
}; };
}; };
@ -150,25 +159,25 @@ Suite system_events = "system_events"_suite = [] {
Suite registry_events = "registry_events"_suite = [] { Suite registry_events = "registry_events"_suite = [] {
Case { "on_construct initializes component" } = [] { Case { "on_construct initializes component" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
system.tick({}); system->tick({});
system.tick({}); system->tick({});
const auto &component = fixture.create_component(); const auto &component = fixture.create_component();
system.tick({}); system->tick({});
system.tick({}); system->tick({});
system.tick({}); system->tick({});
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1); expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
system.tick({}); system->tick({});
system.tick({}); system->tick({});
system.tick({}); system->tick({});
fixture.check_values(*component); fixture.check_values(*component);
}; };
Case { "unhappy on_construct throws" } = [] { Case { "unhappy on_construct throws" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); }); expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
@ -195,7 +204,7 @@ Suite registry_events = "registry_events"_suite = [] {
Case { "unhappy on_construct removes component" } = [] { Case { "unhappy on_construct removes component" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); }); expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0); expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
@ -217,24 +226,24 @@ Suite registry_events = "registry_events"_suite = [] {
Suite tick = "ticking"_suite = [] { Suite tick = "ticking"_suite = [] {
Case { "on empty registry won't throw" } = [] { Case { "on empty registry won't throw" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
System { fixture.registry() }.tick(tick_info()); fixture.system()->tick(tick_info());
}; };
Case { "on non-empty registry won't throw" } = [] { Case { "on non-empty registry won't throw" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
fixture.create_component(); fixture.create_component();
system.tick(tick_info()); system->tick(tick_info());
}; };
Case { "clears previous tick's events" } = [] { Case { "clears previous tick's events" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
auto &surface = **fixture.create_component(); auto &surface = **fixture.create_component();
// flush window-creation events // flush window-creation events
system.tick(tick_info()); system->tick(tick_info());
expect_eq(surface.peek_events().size(), 0); expect_eq(surface.peek_events().size(), 0);
surface.push_event(lt::surface::MovedEvent({}, {})); surface.push_event(lt::surface::MovedEvent({}, {}));
@ -243,13 +252,13 @@ Suite tick = "ticking"_suite = [] {
surface.push_event(lt::surface::KeyPressedEvent({})); surface.push_event(lt::surface::KeyPressedEvent({}));
expect_eq(surface.peek_events().size(), 2); expect_eq(surface.peek_events().size(), 2);
system.tick(tick_info()); system->tick(tick_info());
expect_eq(surface.peek_events().size(), 0); expect_eq(surface.peek_events().size(), 0);
}; };
Case { "clears requests" } = [] { Case { "clears requests" } = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
auto &surface = **fixture.create_component(); auto &surface = **fixture.create_component();
const auto new_title = std::string { title } + std::string { "_" }; const auto new_title = std::string { title } + std::string { "_" };
@ -260,7 +269,7 @@ Suite tick = "ticking"_suite = [] {
surface.push_request(lt::surface::ModifyVisibilityRequest(true)); surface.push_request(lt::surface::ModifyVisibilityRequest(true));
expect_eq(surface.peek_requests().size(), 1); expect_eq(surface.peek_requests().size(), 1);
system.tick(tick_info()); system->tick(tick_info());
expect_eq(surface.peek_requests().size(), 0); expect_eq(surface.peek_requests().size(), 0);
surface.push_request(lt::surface::ModifyTitleRequest(new_title)); surface.push_request(lt::surface::ModifyTitleRequest(new_title));
@ -275,7 +284,7 @@ Suite tick = "ticking"_suite = [] {
surface.push_request(lt::surface::ModifyVisibilityRequest(false)); surface.push_request(lt::surface::ModifyVisibilityRequest(false));
expect_eq(surface.peek_requests().size(), 1 + 2 + 3); expect_eq(surface.peek_requests().size(), 1 + 2 + 3);
system.tick(tick_info()); system->tick(tick_info());
expect_eq(surface.peek_requests().size(), 0); expect_eq(surface.peek_requests().size(), 0);
}; };
}; };
@ -287,14 +296,14 @@ Suite requests = "requests"_suite = [] {
using ::lt::surface::ModifyVisibilityRequest; using ::lt::surface::ModifyVisibilityRequest;
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
auto &surface = **fixture.create_component(); auto &surface = **fixture.create_component();
Case { "ModifyTitleRequest" } = [&] { Case { "ModifyTitleRequest" } = [&] {
const auto new_title = std::string { title } + std::string { "_" }; const auto new_title = std::string { title } + std::string { "_" };
surface.push_request({ ModifyTitleRequest { new_title } }); surface.push_request({ ModifyTitleRequest { new_title } });
system.tick({}); system->tick({});
expect_eq(surface.get_title(), new_title); expect_eq(surface.get_title(), new_title);
}; };
@ -302,7 +311,7 @@ Suite requests = "requests"_suite = [] {
constexpr auto new_resolution = lt::math::vec2_u32 { width + 50, height + 50 }; constexpr auto new_resolution = lt::math::vec2_u32 { width + 50, height + 50 };
surface.push_request({ ModifyResolutionRequest { new_resolution } }); surface.push_request({ ModifyResolutionRequest { new_resolution } });
system.tick({}); system->tick({});
expect_eq(surface.get_resolution(), new_resolution); expect_eq(surface.get_resolution(), new_resolution);
}; };
@ -310,17 +319,17 @@ Suite requests = "requests"_suite = [] {
constexpr auto new_position = lt::math::vec2_i32 { position_x + 50, position_y + 50 }; constexpr auto new_position = lt::math::vec2_i32 { position_x + 50, position_y + 50 };
surface.push_request({ ModifyPositionRequest { new_position } }); surface.push_request({ ModifyPositionRequest { new_position } });
system.tick({}); system->tick({});
expect_eq(surface.get_position(), new_position); expect_eq(surface.get_position(), new_position);
}; };
Case { "ModifyVisibilityRequest" } = [&] { Case { "ModifyVisibilityRequest" } = [&] {
surface.push_request({ ModifyVisibilityRequest { .visible = false } }); surface.push_request({ ModifyVisibilityRequest { .visible = false } });
system.tick({}); system->tick({});
expect_eq(surface.is_visible(), false); expect_eq(surface.is_visible(), false);
surface.push_request({ ModifyVisibilityRequest { .visible = true } }); surface.push_request({ ModifyVisibilityRequest { .visible = true } });
system.tick({}); system->tick({});
expect_eq(surface.is_visible(), true); expect_eq(surface.is_visible(), true);
}; };
}; };
@ -329,12 +338,12 @@ Suite requests = "requests"_suite = [] {
Suite windows_window_proc = "windows_window_proc"_suite = [] { Suite windows_window_proc = "windows_window_proc"_suite = [] {
auto fixture = Fixture {}; auto fixture = Fixture {};
auto system = System { fixture.registry() }; auto system = fixture.system();
auto &surface = **fixture.create_component(); auto &surface = **fixture.create_component();
auto [hwnd] = surface.get_native_data(); auto [hwnd] = surface.get_native_data();
const auto &events = surface.peek_events(); const auto &events = surface.peek_events();
system.tick({}); system->tick({});
Case { "WM_SETFOCUS" } = [&] { Case { "WM_SETFOCUS" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_SETFOCUS, {}, {}); ::SendMessage(hwnd, WM_SETFOCUS, {}, {});
@ -344,7 +353,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
::lt::log::trace("{}", event.to_string()); // make sure it's not optimized away? ::lt::log::trace("{}", event.to_string()); // make sure it's not optimized away?
}; };
system.tick({}); system->tick({});
Case { "WM_KILLFOCUS" } = [&] { Case { "WM_KILLFOCUS" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_KILLFOCUS, {}, {}); ::SendMessage(hwnd, WM_KILLFOCUS, {}, {});
@ -354,7 +363,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
::lt::log::trace("{}", event.to_string()); // make sure it's not optimized away? ::lt::log::trace("{}", event.to_string()); // make sure it's not optimized away?
}; };
system.tick({}); system->tick({});
Case { "WM_SIZE" } = [&] { Case { "WM_SIZE" } = [&] {
const auto new_width = width + 50; const auto new_width = width + 50;
const auto new_height = height + 60; const auto new_height = height + 60;
@ -371,7 +380,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(surface.get_resolution().y, new_height); expect_eq(surface.get_resolution().y, new_height);
}; };
system.tick({}); system->tick({});
Case { "WM_MOVE" } = [&] { Case { "WM_MOVE" } = [&] {
const auto new_x = position_x + 120; const auto new_x = position_x + 120;
const auto new_y = position_y + 150; const auto new_y = position_y + 150;
@ -388,7 +397,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(surface.get_position().y, new_y); expect_eq(surface.get_position().y, new_y);
}; };
system.tick({}); system->tick({});
Case { "WM_MOUSEWHEEL" } = [&] { Case { "WM_MOUSEWHEEL" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), {}); ::SendMessage(hwnd, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), {});
@ -405,7 +414,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[3]).get_key(), Key::wheel_down); expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[3]).get_key(), Key::wheel_down);
}; };
system.tick({}); system->tick({});
Case { "WM_LBUTTONDOWN" } = [&] { Case { "WM_LBUTTONDOWN" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_LBUTTONDOWN, {}, {}); ::SendMessage(hwnd, WM_LBUTTONDOWN, {}, {});
@ -415,7 +424,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyPressedEvent>(events[0]).get_key(), Key::left_button); expect_eq(std::get<lt::surface::KeyPressedEvent>(events[0]).get_key(), Key::left_button);
}; };
system.tick({}); system->tick({});
Case { "WM_LBUTTONUP" } = [&] { Case { "WM_LBUTTONUP" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_LBUTTONUP, {}, {}); ::SendMessage(hwnd, WM_LBUTTONUP, {}, {});
@ -425,7 +434,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[0]).get_key(), Key::left_button); expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[0]).get_key(), Key::left_button);
}; };
system.tick({}); system->tick({});
Case { "WM_RBUTTONDOWN" } = [&] { Case { "WM_RBUTTONDOWN" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_RBUTTONDOWN, {}, {}); ::SendMessage(hwnd, WM_RBUTTONDOWN, {}, {});
@ -435,7 +444,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyPressedEvent>(events[0]).get_key(), Key::right_button); expect_eq(std::get<lt::surface::KeyPressedEvent>(events[0]).get_key(), Key::right_button);
}; };
system.tick({}); system->tick({});
Case { "WM_RBUTTONUP" } = [&] { Case { "WM_RBUTTONUP" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_RBUTTONUP, {}, {}); ::SendMessage(hwnd, WM_RBUTTONUP, {}, {});
@ -445,7 +454,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[0]).get_key(), Key::right_button); expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[0]).get_key(), Key::right_button);
}; };
system.tick({}); system->tick({});
Case { "WM_MBUTTONDOWN" } = [&] { Case { "WM_MBUTTONDOWN" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_MBUTTONDOWN, {}, {}); ::SendMessage(hwnd, WM_MBUTTONDOWN, {}, {});
@ -455,7 +464,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyPressedEvent>(events[0]).get_key(), Key::middle_button); expect_eq(std::get<lt::surface::KeyPressedEvent>(events[0]).get_key(), Key::middle_button);
}; };
system.tick({}); system->tick({});
Case { "WM_MBUTTONUP" } = [&] { Case { "WM_MBUTTONUP" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_MBUTTONUP, {}, {}); ::SendMessage(hwnd, WM_MBUTTONUP, {}, {});
@ -466,7 +475,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
}; };
system.tick({}); system->tick({});
Case { "WM_XBUTTONDOWN" } = [&] { Case { "WM_XBUTTONDOWN" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_XBUTTONDOWN, MAKEWPARAM(0, XBUTTON1), {}); ::SendMessage(hwnd, WM_XBUTTONDOWN, MAKEWPARAM(0, XBUTTON1), {});
@ -478,7 +487,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyPressedEvent>(events[1]).get_key(), Key::x_button_2); expect_eq(std::get<lt::surface::KeyPressedEvent>(events[1]).get_key(), Key::x_button_2);
}; };
system.tick({}); system->tick({});
Case { "WM_XBUTTONUP" } = [&] { Case { "WM_XBUTTONUP" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_XBUTTONUP, MAKEWPARAM(0, XBUTTON1), {}); ::SendMessage(hwnd, WM_XBUTTONUP, MAKEWPARAM(0, XBUTTON1), {});
@ -490,7 +499,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[1]).get_key(), Key::x_button_2); expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[1]).get_key(), Key::x_button_2);
}; };
system.tick({}); system->tick({});
Case { "WM_KEYDOWN" } = [&] { Case { "WM_KEYDOWN" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_KEYDOWN, System::to_native_key(Key::escape), {}); ::SendMessage(hwnd, WM_KEYDOWN, System::to_native_key(Key::escape), {});
@ -499,7 +508,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyPressedEvent>(events[0]).get_key(), Key::escape); expect_eq(std::get<lt::surface::KeyPressedEvent>(events[0]).get_key(), Key::escape);
}; };
system.tick({}); system->tick({});
Case { "WM_KEYUP" } = [&] { Case { "WM_KEYUP" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_KEYUP, System::to_native_key(Key::escape), {}); ::SendMessage(hwnd, WM_KEYUP, System::to_native_key(Key::escape), {});
@ -508,7 +517,7 @@ Suite windows_window_proc = "windows_window_proc"_suite = [] {
expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[0]).get_key(), Key::escape); expect_eq(std::get<lt::surface::KeyReleasedEvent>(events[0]).get_key(), Key::escape);
}; };
system.tick({}); system->tick({});
Case { "WM_CLOSE" } = [&] { Case { "WM_CLOSE" } = [&] {
expect_eq(events.size(), 0u); expect_eq(events.size(), 0u);
::SendMessage(hwnd, WM_CLOSE, {}, {}); ::SendMessage(hwnd, WM_CLOSE, {}, {});