refactor: surface, app, tests, ecs refactors
Some checks reported errors
continuous-integration/drone/push Build was killed
Some checks reported errors
continuous-integration/drone/push Build was killed
This commit is contained in:
parent
a102db0699
commit
638a009047
16 changed files with 336 additions and 141 deletions
|
@ -5,11 +5,6 @@ namespace lt::app {
|
|||
|
||||
void Application::game_loop()
|
||||
{
|
||||
for (auto &system : m_systems)
|
||||
{
|
||||
system->init();
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
for (auto &system : m_systems)
|
||||
|
@ -20,7 +15,12 @@ void Application::game_loop()
|
|||
}
|
||||
}
|
||||
|
||||
for (auto &system : m_systems_to_be_removed)
|
||||
for (auto &system : m_systems_to_be_registered)
|
||||
{
|
||||
m_systems.emplace_back(system)->on_register();
|
||||
}
|
||||
|
||||
for (auto &system : m_systems_to_be_unregistered)
|
||||
{
|
||||
m_systems.erase(
|
||||
std::remove(m_systems.begin(), m_systems.end(), system),
|
||||
|
@ -42,7 +42,7 @@ void Application::register_system(Ref<app::ISystem> system)
|
|||
|
||||
void Application::unregister_system(Ref<app::ISystem> system)
|
||||
{
|
||||
m_systems_to_be_removed.emplace_back(std::move(system));
|
||||
m_systems_to_be_unregistered.emplace_back(std::move(system));
|
||||
}
|
||||
|
||||
} // namespace lt::app
|
||||
|
|
|
@ -35,7 +35,9 @@ protected:
|
|||
private:
|
||||
std::vector<Ref<app::ISystem>> m_systems;
|
||||
|
||||
std::vector<Ref<app::ISystem>> m_systems_to_be_removed;
|
||||
std::vector<Ref<app::ISystem>> m_systems_to_be_unregistered;
|
||||
|
||||
std::vector<Ref<app::ISystem>> m_systems_to_be_registered;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ public:
|
|||
|
||||
auto operator=(const ISystem &) -> ISystem & = delete;
|
||||
|
||||
virtual void init() = 0;
|
||||
virtual void on_register() = 0;
|
||||
|
||||
virtual void on_unregister() = 0;
|
||||
|
||||
virtual auto tick() -> bool = 0;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <format>
|
||||
#include <logger/logger.hpp>
|
||||
#include <source_location>
|
||||
|
||||
namespace lt {
|
||||
|
||||
|
@ -12,15 +14,6 @@ struct FailedAssertion: std::exception
|
|||
}
|
||||
};
|
||||
|
||||
template<typename Expression_T, typename... Args>
|
||||
constexpr void ensure(Expression_T &&expression, std::format_string<Args...> fmt, Args &&...args)
|
||||
{
|
||||
if (!static_cast<bool>(expression))
|
||||
{
|
||||
Logger::log(LogLvl::critical, fmt, std::forward<Args>(args)...);
|
||||
throw ::lt::FailedAssertion(__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Expression_T>
|
||||
constexpr void ensure(Expression_T &&expression, const char *message)
|
||||
|
|
|
@ -11,21 +11,6 @@ auto Scene::create_entity(const std::string &name, const TransformComponent &tra
|
|||
|
||||
auto Scene::get_entity_by_tag(const std::string &tag) -> Entity
|
||||
{
|
||||
// TagComponent tagComp(tag);
|
||||
// entt::entity entity = entt::to_entity(m_registry, tagComp);
|
||||
auto entity = Entity {};
|
||||
|
||||
m_registry.view<TagComponent>().each([&](TagComponent &tagComp) {
|
||||
// if (tagComp.tag == tag)
|
||||
// entity = entity(entt::to_entity(m_registry, tagComp), this);
|
||||
});
|
||||
|
||||
if (entity.is_valid())
|
||||
{
|
||||
return entity;
|
||||
}
|
||||
|
||||
ensure(false, "Scene::get_entity_by_tag: failed to find entity by tag: {}", tag);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,12 @@ public:
|
|||
return m_registry.group(entt::get<T...>);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto view()
|
||||
{
|
||||
return m_registry.view<T>();
|
||||
}
|
||||
|
||||
auto create_entity(
|
||||
const std::string &name,
|
||||
const TransformComponent &transform = TransformComponent()
|
||||
|
@ -31,6 +37,7 @@ public:
|
|||
return m_registry;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
friend class Entity;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
namespace lt::math {
|
||||
|
||||
|
||||
/**
|
||||
* let...
|
||||
* a = h / w ==> for aspect ratio adjustment
|
||||
|
|
|
@ -22,23 +22,26 @@ public:
|
|||
setup_window_system();
|
||||
register_systems();
|
||||
|
||||
m_window_system->add_event_listener([&](const surface::System::Event &event) {
|
||||
const auto visitor = overloads {
|
||||
[&](const lt::surface::KeyPressedEvent &event) {
|
||||
std::cout << "key pressed: " << event.to_string() << std::endl;
|
||||
m_window_system->add_event_listener(
|
||||
m_window,
|
||||
[&](const surface::SurfaceComponent::Event &event) {
|
||||
const auto visitor = overloads {
|
||||
[&](const lt::surface::KeyPressedEvent &event) {
|
||||
std::cout << "key pressed: " << event.to_string() << std::endl;
|
||||
|
||||
if (event.get_key() == 81)
|
||||
{
|
||||
unregister_system(m_window_system);
|
||||
log_inf("Quitting...");
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[](const auto &) { return false; },
|
||||
};
|
||||
if (event.get_key() == 81)
|
||||
{
|
||||
unregister_system(m_window_system);
|
||||
log_inf("Quitting...");
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[](const auto &) { return false; },
|
||||
};
|
||||
|
||||
return std::visit(visitor, event);
|
||||
});
|
||||
return std::visit(visitor, event);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void setup_window_system()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
if (NOT WIN32)
|
||||
add_library_module(surface system.cpp linux/system.cpp)
|
||||
add_library_module(surface linux/system.cpp)
|
||||
else()
|
||||
endif()
|
||||
|
||||
|
@ -11,3 +11,6 @@ target_link_libraries(surface PUBLIC
|
|||
logger
|
||||
lt_debug
|
||||
)
|
||||
|
||||
add_test_module(surface system.test.cpp)
|
||||
target_link_libraries(surface_tests PRIVATE glfw)
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <GLFW/glfw3native.h>
|
||||
#include <surface/system.hpp>
|
||||
|
||||
namespace lt::surface {
|
||||
|
||||
void handle_event(GLFWwindow *window, const System::Event &event)
|
||||
void handle_event(GLFWwindow *window, const SurfaceComponent::Event &event)
|
||||
{
|
||||
auto &callbacks = *static_cast<std::vector<System::EventCallback> *>(
|
||||
auto &callbacks = *static_cast<std::vector<SurfaceComponent::EventCallback> *>(
|
||||
glfwGetWindowUserPointer(window)
|
||||
);
|
||||
|
||||
|
@ -90,6 +92,50 @@ void bind_glfw_events(GLFWwindow *handle)
|
|||
});
|
||||
}
|
||||
|
||||
System::System(Ref<ecs::Registry> registry): m_registry(std::move(registry))
|
||||
{
|
||||
ensure(m_registry, "Failed to initialize surface system: null registry");
|
||||
ensure(
|
||||
m_registry->view<SurfaceComponent>().size() == 0,
|
||||
"Failed to initialize surface system: registry has surface component(s)"
|
||||
);
|
||||
|
||||
m_registry->get_entt_registry()
|
||||
.on_construct<SurfaceComponent>()
|
||||
.connect<&System::on_surface_construct>(this);
|
||||
|
||||
m_registry->get_entt_registry()
|
||||
.on_update<SurfaceComponent>()
|
||||
.connect<&System::on_surface_update>(this);
|
||||
|
||||
m_registry->get_entt_registry()
|
||||
.on_destroy<SurfaceComponent>()
|
||||
.connect<&System::on_surface_destroy>(this);
|
||||
}
|
||||
|
||||
System::~System()
|
||||
{
|
||||
m_registry->get_entt_registry()
|
||||
.on_construct<SurfaceComponent>()
|
||||
.disconnect<&System::on_surface_construct>(this);
|
||||
|
||||
m_registry->get_entt_registry()
|
||||
.on_update<SurfaceComponent>()
|
||||
.connect<&System::on_surface_update>(this);
|
||||
|
||||
m_registry->get_entt_registry()
|
||||
.on_destroy<SurfaceComponent>()
|
||||
.disconnect<&System::on_surface_destroy>(this);
|
||||
|
||||
|
||||
m_registry->view<SurfaceComponent>().each([&](const entt::entity entity, SurfaceComponent &) {
|
||||
std::cout << "REMOVED SURFACE COMPONENT ON DESTRUCTION" << std::endl;
|
||||
m_registry->get_entt_registry().remove<SurfaceComponent>(entity);
|
||||
});
|
||||
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
void System::on_surface_construct(entt::registry ®istry, entt::entity entity)
|
||||
{
|
||||
ensure(glfwInit(), "Failed to initialize 'glfw'");
|
||||
|
@ -111,10 +157,17 @@ void System::on_surface_construct(entt::registry ®istry, entt::entity entity)
|
|||
);
|
||||
ensure(surface.m_glfw_handle, "Failed to create 'GLFWwindow'");
|
||||
|
||||
glfwSetWindowUserPointer(surface.m_glfw_handle, &m_event_callbacks);
|
||||
glfwSetWindowUserPointer(surface.m_glfw_handle, &surface.m_event_callbacks);
|
||||
surface.m_native_handle = glfwGetX11Window(surface.m_glfw_handle);
|
||||
bind_glfw_events(surface.m_glfw_handle);
|
||||
}
|
||||
|
||||
void System::on_surface_update(entt::registry ®istry, entt::entity entity)
|
||||
{
|
||||
auto &surface = registry.get<SurfaceComponent>(entity);
|
||||
glfwSetWindowUserPointer(surface.m_glfw_handle, &surface.m_event_callbacks);
|
||||
}
|
||||
|
||||
void System::on_surface_destroy(entt::registry ®istry, entt::entity entity)
|
||||
{
|
||||
auto &surface = registry.get<SurfaceComponent>(entity);
|
||||
|
@ -170,29 +223,17 @@ void System::set_visibility(ecs::Entity surface_entity, bool visible)
|
|||
}
|
||||
}
|
||||
|
||||
void System::add_event_listener(
|
||||
ecs::Entity surface_entity,
|
||||
SurfaceComponent::EventCallback callback
|
||||
)
|
||||
{
|
||||
auto &surface = surface_entity.get_component<SurfaceComponent>();
|
||||
surface.m_event_callbacks.emplace_back(std::move(callback));
|
||||
}
|
||||
|
||||
} // namespace lt::surface
|
||||
|
||||
namespace lt {
|
||||
|
||||
// void System::on_event(const Event &event)
|
||||
// {
|
||||
// switch (event.get_event_type())
|
||||
// {
|
||||
// /* closed */
|
||||
// case EventType::WindowClosed: b_Closed = true; break;
|
||||
//
|
||||
// /* resized */
|
||||
// case EventType::WindowResized:
|
||||
// on_surface_resize(dynamic_cast<const WindowResizedEvent &>(event));
|
||||
// break;
|
||||
//
|
||||
// default: break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// void System::on_surface_resize(const WindowResizedEvent &event)
|
||||
// {
|
||||
// m_properties.size = event.get_size();
|
||||
// }
|
||||
|
||||
} // namespace lt
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#include <surface/system.hpp>
|
||||
|
||||
namespace lt::surface {
|
||||
|
||||
System::System(Ref<ecs::Registry> registry): m_registry(std::move(registry))
|
||||
{
|
||||
m_registry->get_entt_registry()
|
||||
.on_construct<SurfaceComponent>()
|
||||
.connect<&System::on_surface_construct>(this);
|
||||
|
||||
m_registry->get_entt_registry()
|
||||
.on_destroy<SurfaceComponent>()
|
||||
.connect<&System::on_surface_destroy>(this);
|
||||
}
|
||||
|
||||
System::~System()
|
||||
{
|
||||
m_registry->get_entt_registry()
|
||||
.on_construct<SurfaceComponent>()
|
||||
.disconnect<&System::on_surface_construct>(this);
|
||||
|
||||
m_registry->get_entt_registry()
|
||||
.on_destroy<SurfaceComponent>()
|
||||
.disconnect<&System::on_surface_destroy>(this);
|
||||
}
|
||||
|
||||
} // namespace lt::surface
|
|
@ -0,0 +1,151 @@
|
|||
#include <surface/system.hpp>
|
||||
#include <test/test.hpp>
|
||||
|
||||
using namespace lt;
|
||||
using std::ignore;
|
||||
using surface::SurfaceComponent;
|
||||
using surface::System;
|
||||
using test::Case;
|
||||
using test::expect_eq;
|
||||
using test::expect_ne;
|
||||
using test::expect_not_nullptr;
|
||||
using test::expect_throw;
|
||||
using test::Suite;
|
||||
|
||||
constexpr auto title = "TestWindow";
|
||||
constexpr auto width = 800u;
|
||||
constexpr auto height = 600u;
|
||||
constexpr auto vsync = true;
|
||||
constexpr auto visible = false;
|
||||
|
||||
class Fixture
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] auto registry() -> Ref<ecs::Registry>
|
||||
{
|
||||
return m_registry;
|
||||
}
|
||||
|
||||
auto add_surface_component() -> SurfaceComponent &
|
||||
{
|
||||
auto entity = m_registry->create_entity("");
|
||||
return entity.add_component<SurfaceComponent>(SurfaceComponent::CreateInfo {
|
||||
.title = title,
|
||||
.size = { width, height },
|
||||
.vsync = vsync,
|
||||
.visible = visible,
|
||||
});
|
||||
}
|
||||
|
||||
void check_values(const SurfaceComponent &component)
|
||||
{
|
||||
expect_ne(std::get<SurfaceComponent::X11NativeHandle>(component.get_native_handle()), 0);
|
||||
expect_eq(component.get_size().x, width);
|
||||
expect_eq(component.get_size().y, height);
|
||||
expect_eq(component.get_title(), title);
|
||||
expect_eq(component.is_vsync(), vsync);
|
||||
expect_eq(component.is_visible(), visible);
|
||||
}
|
||||
|
||||
private:
|
||||
Ref<ecs::Registry> m_registry = create_ref<ecs::Registry>();
|
||||
};
|
||||
|
||||
Suite raii = [] {
|
||||
Case { "happy path won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
ignore = System { fixture.registry() };
|
||||
};
|
||||
|
||||
Case { "many won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
for (auto idx : std::views::iota(0, 100'001))
|
||||
{
|
||||
ignore = System { fixture.registry() };
|
||||
}
|
||||
};
|
||||
|
||||
Case { "unhappy path throws" } = [] {
|
||||
expect_throw([] { ignore = System { {} }; });
|
||||
|
||||
auto fixture = Fixture {};
|
||||
fixture.add_surface_component();
|
||||
expect_throw([&] { ignore = System { { fixture.registry() } }; });
|
||||
};
|
||||
|
||||
Case { "post construct has correct state" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>()->size(), 0);
|
||||
};
|
||||
};
|
||||
|
||||
Suite system_events = [] {
|
||||
Case { "on_register won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
|
||||
system.on_register();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().size(), 0);
|
||||
};
|
||||
|
||||
Case { "on_unregister won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
system.on_register();
|
||||
|
||||
system.on_unregister();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().size(), 0);
|
||||
};
|
||||
};
|
||||
|
||||
Suite registry_events = [] {
|
||||
Case { "on_construct<SurfaceComponent> initializes component" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
|
||||
const auto &component = fixture.add_surface_component();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().size(), 1);
|
||||
fixture.check_values(component);
|
||||
};
|
||||
|
||||
Case { "on_destrroy<SurfaceComponent> cleans up component" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = create_scope<System>(fixture.registry());
|
||||
|
||||
const auto &component = fixture.add_surface_component();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().size(), 1);
|
||||
fixture.check_values(component);
|
||||
|
||||
system.reset();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().size(), 0);
|
||||
};
|
||||
};
|
||||
|
||||
Suite tick = [] {
|
||||
Case { "ticking on empty registry won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
System { fixture.registry() }.tick();
|
||||
};
|
||||
|
||||
Case { "ticking on non-empty registry won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
|
||||
fixture.add_surface_component();
|
||||
system.tick();
|
||||
};
|
||||
|
||||
Case { "ticking on chaotic registry won't throw" } = [] {
|
||||
}
|
||||
};
|
||||
|
||||
Suite property_setters = [] {
|
||||
|
||||
};
|
||||
|
||||
Suite listeners = [] {
|
||||
};
|
||||
|
||||
Suite fuzzy = [] {
|
||||
};
|
|
@ -1,16 +1,52 @@
|
|||
#pragma once
|
||||
|
||||
#include <math/vec2.hpp>
|
||||
#include <surface/events/keyboard.hpp>
|
||||
#include <surface/events/mouse.hpp>
|
||||
#include <surface/events/surface.hpp>
|
||||
#include <variant>
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
namespace lt::surface {
|
||||
|
||||
/** Represents a platform's surface (eg. a Window).
|
||||
*
|
||||
* @note Read-only component, should only be modified through a system.
|
||||
*/
|
||||
class SurfaceComponent
|
||||
{
|
||||
public:
|
||||
friend class System;
|
||||
|
||||
using Event = std::variant<
|
||||
// surface events
|
||||
ClosedEvent,
|
||||
MovedEvent,
|
||||
ResizedEvent,
|
||||
LostFocusEvent,
|
||||
GainFocusEvent,
|
||||
|
||||
// keyboard events
|
||||
KeyPressedEvent,
|
||||
KeyRepeatEvent,
|
||||
KeyReleasedEvent,
|
||||
KeySetCharEvent,
|
||||
|
||||
// mouse events
|
||||
MouseMovedEvent,
|
||||
WheelScrolledEvent,
|
||||
ButtonPressedEvent,
|
||||
ButtonReleasedEvent>;
|
||||
|
||||
using EventCallback = std::function<bool(const Event &)>;
|
||||
|
||||
using WindowsNativeHandle = void *;
|
||||
|
||||
using X11NativeHandle = unsigned long;
|
||||
|
||||
using NativeHandle = std::variant<WindowsNativeHandle, X11NativeHandle>;
|
||||
|
||||
struct CreateInfo
|
||||
{
|
||||
std::string_view title;
|
||||
|
@ -50,17 +86,17 @@ public:
|
|||
return m_visible;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_native_handle() const -> void *
|
||||
[[nodiscard]] auto get_native_handle() const -> NativeHandle
|
||||
{
|
||||
return m_native_handle;
|
||||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto get_glfw_handle() const -> GLFWwindow *
|
||||
{
|
||||
return m_glfw_handle;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string_view m_title;
|
||||
|
||||
math::uvec2 m_size;
|
||||
|
@ -69,9 +105,11 @@ private:
|
|||
|
||||
bool m_visible;
|
||||
|
||||
void *m_native_handle {};
|
||||
NativeHandle m_native_handle;
|
||||
|
||||
GLFWwindow *m_glfw_handle {};
|
||||
|
||||
std::vector<EventCallback> m_event_callbacks;
|
||||
};
|
||||
|
||||
} // namespace lt::surface
|
||||
|
|
|
@ -4,38 +4,13 @@
|
|||
#include <ecs/entity.hpp>
|
||||
#include <ecs/scene.hpp>
|
||||
#include <surface/components.hpp>
|
||||
#include <surface/events/keyboard.hpp>
|
||||
#include <surface/events/mouse.hpp>
|
||||
#include <surface/events/surface.hpp>
|
||||
|
||||
namespace lt::surface {
|
||||
|
||||
class System: public app::ISystem
|
||||
{
|
||||
public:
|
||||
using Event = std::variant<
|
||||
// surface events
|
||||
ClosedEvent,
|
||||
MovedEvent,
|
||||
ResizedEvent,
|
||||
LostFocusEvent,
|
||||
GainFocusEvent,
|
||||
|
||||
// keyboard events
|
||||
KeyPressedEvent,
|
||||
KeyRepeatEvent,
|
||||
KeyReleasedEvent,
|
||||
KeySetCharEvent,
|
||||
|
||||
// mouse events
|
||||
MouseMovedEvent,
|
||||
WheelScrolledEvent,
|
||||
ButtonPressedEvent,
|
||||
ButtonReleasedEvent>;
|
||||
|
||||
using EventCallback = std::function<bool(const Event &)>;
|
||||
|
||||
System(Ref<ecs::Registry> registry);
|
||||
[[nodiscard]] System(Ref<ecs::Registry> registry);
|
||||
|
||||
~System() override;
|
||||
|
||||
|
@ -47,7 +22,11 @@ public:
|
|||
|
||||
auto operator=(const System &) -> System & = delete;
|
||||
|
||||
void init() override
|
||||
void on_register() override
|
||||
{
|
||||
}
|
||||
|
||||
void on_unregister() override
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -61,19 +40,16 @@ public:
|
|||
|
||||
void set_visibility(ecs::Entity surface_entity, bool visible);
|
||||
|
||||
void add_event_listener(EventCallback callback)
|
||||
{
|
||||
m_event_callbacks.emplace_back(std::move(callback));
|
||||
}
|
||||
void add_event_listener(ecs::Entity surface_entity, SurfaceComponent::EventCallback callback);
|
||||
|
||||
private:
|
||||
void on_surface_construct(entt::registry ®istry, entt::entity entity);
|
||||
|
||||
void on_surface_update(entt::registry ®istry, entt::entity entity);
|
||||
|
||||
void on_surface_destroy(entt::registry ®istry, entt::entity entity);
|
||||
|
||||
Ref<ecs::Registry> m_registry;
|
||||
|
||||
std::vector<EventCallback> m_event_callbacks;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -140,6 +140,27 @@ constexpr void expect_false(
|
|||
}
|
||||
}
|
||||
|
||||
constexpr void expect_not_nullptr(
|
||||
auto *pointer,
|
||||
std::source_location source_location = std::source_location::current()
|
||||
)
|
||||
{
|
||||
if (pointer == nullptr)
|
||||
{
|
||||
throw std::runtime_error {
|
||||
std::format(
|
||||
"Failed true expectation:\n"
|
||||
"\tactual: nullptr\n"
|
||||
"\texpected: not nullptr\n"
|
||||
"\tlocation: {}:{}",
|
||||
source_location.file_name(),
|
||||
source_location.line()
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
constexpr void expect_le(
|
||||
Testable auto lhs,
|
||||
Testable auto rhs,
|
||||
|
|
|
@ -84,7 +84,8 @@ struct Case
|
|||
{
|
||||
auto operator=(std::invocable auto test) -> void // NOLINT
|
||||
{
|
||||
std::cout << "Running... " << name;
|
||||
std::cout << "[Running-----------] --> ";
|
||||
std::cout << name << '\n';
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -92,14 +93,14 @@ struct Case
|
|||
}
|
||||
catch (const std::exception &exp)
|
||||
{
|
||||
std::cout << " --> FAIL !" << '\n';
|
||||
std::cout << exp.what() << "\n\n";
|
||||
std::cout << exp.what() << "\n";
|
||||
std::cout << "[-----------FAIL !!]" << "\n\n";
|
||||
details::Registry::increment_failed_count();
|
||||
return; // TODO(Light): Should we run the remaining tests after a failure?
|
||||
}
|
||||
|
||||
details::Registry::increment_passed_count();
|
||||
std::cout << " --> SUCCESS :D" << "\n";
|
||||
std::cout << "[--------SUCCESS :D]" << "\n\n";
|
||||
}
|
||||
|
||||
std::string_view name;
|
||||
|
|
Loading…
Add table
Reference in a new issue