feat: add preliminary
This commit is contained in:
parent
71da4ea47a
commit
20f62433f9
82 changed files with 985 additions and 2247 deletions
|
|
@ -1,12 +1,14 @@
|
|||
add_module(NAME logger INTERFACES logger.cppm TESTS logger.test.cpp)
|
||||
add_module(NAME bitwise INTERFACES operations.cppm)
|
||||
add_module(NAME env INTERFACES constants.cppm)
|
||||
add_module(NAME memory INTERFACES null_on_move.cppm reference.cppm scope.cppm
|
||||
add_module(NAME preliminary INTERFACES module.cppm fundumental_types.cppm)
|
||||
|
||||
add_module(NAME logger INTERFACES logger.cppm TESTS logger.test.cpp DEPENDENCIES preliminary)
|
||||
add_module(NAME bitwise INTERFACES operations.cppm DEPENDENCIES preliminary)
|
||||
add_module(NAME env INTERFACES constants.cppm DEPENDENCIES preliminary)
|
||||
add_module(NAME memory INTERFACES null_on_move.cppm reference.cppm scope.cppm
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
logger
|
||||
)
|
||||
add_module(NAME time INTERFACES timer.cppm TESTS timer.test.cpp)
|
||||
add_module(NAME time INTERFACES timer.cppm TESTS timer.test.cpp DEPENDENCIES preliminary)
|
||||
|
||||
add_module(
|
||||
NAME
|
||||
|
|
@ -18,6 +20,7 @@ add_module(
|
|||
SOURCES
|
||||
entrypoint.cpp
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
logger
|
||||
TESTS
|
||||
test.test.cpp
|
||||
|
|
@ -32,6 +35,7 @@ add_module(
|
|||
instrumentor.cppm
|
||||
assertions.cppm
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
logger
|
||||
)
|
||||
|
||||
|
|
@ -40,13 +44,14 @@ add_module(
|
|||
math
|
||||
INTERFACES
|
||||
algebra.cppm
|
||||
mat4.cppm
|
||||
trig.cppm
|
||||
vec2.cppm
|
||||
vec3.cppm
|
||||
vec4.cppm
|
||||
mat4.cppm
|
||||
components.cppm
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
lt_debug
|
||||
)
|
||||
|
||||
|
|
@ -57,6 +62,7 @@ add_module(
|
|||
shader.cppm
|
||||
metadata.cppm
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
logger
|
||||
lt_debug
|
||||
TESTS
|
||||
|
|
@ -73,17 +79,16 @@ add_module(
|
|||
ENTRYPOINT
|
||||
entrypoint.cpp
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
assets
|
||||
logger
|
||||
lt_debug
|
||||
TESTS
|
||||
bakers.test.cpp
|
||||
)
|
||||
|
||||
# add_executable(asset_baker entrypoint.cpp) target_link_libraries(asset_baker
|
||||
# PRIVATE libasset_baker)
|
||||
|
||||
add_module(NAME camera INTERFACES components.cppm DEPENDENCIES math)
|
||||
add_module(NAME camera INTERFACES components.cppm DEPENDENCIES preliminary math)
|
||||
|
||||
add_module(
|
||||
NAME
|
||||
|
|
@ -92,6 +97,7 @@ add_module(
|
|||
application.cppm
|
||||
system.cppm
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
memory
|
||||
PRIVATE_DEPENDENCIES
|
||||
lt_debug
|
||||
|
|
@ -113,7 +119,7 @@ add_module(
|
|||
sparse_set.test.cpp
|
||||
)
|
||||
|
||||
add_module(NAME input_codes INTERFACES input_codes.cppm)
|
||||
add_module(NAME input_codes INTERFACES input_codes.cppm DEPENDENCIES preliminary)
|
||||
|
||||
if(WIN32)
|
||||
add_module(
|
||||
|
|
@ -126,6 +132,7 @@ if(WIN32)
|
|||
events.cppm
|
||||
components.cppm
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
ecs
|
||||
app
|
||||
math
|
||||
|
|
@ -150,6 +157,7 @@ elseif(UNIX)
|
|||
events.cppm
|
||||
components.cppm
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
ecs
|
||||
app
|
||||
math
|
||||
|
|
@ -190,6 +198,7 @@ add_module(
|
|||
components.cppm
|
||||
events.cppm
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
input_codes
|
||||
surface
|
||||
math
|
||||
|
|
@ -220,6 +229,7 @@ add_module(
|
|||
vk/renderer.cppm
|
||||
vk/debugger.cppm
|
||||
DEPENDENCIES
|
||||
preliminary
|
||||
app
|
||||
ecs
|
||||
memory
|
||||
|
|
@ -232,12 +242,12 @@ add_module(
|
|||
PRIVATE_DEPENDENCIES
|
||||
surface
|
||||
TESTS
|
||||
# _tests/buffer.cpp
|
||||
# _tests/debugger.cpp
|
||||
# _tests/device.cpp
|
||||
# _tests/pass.cpp
|
||||
# _tests/renderer.cpp
|
||||
# _tests/surface.cpp
|
||||
_tests/buffer.cpp
|
||||
_tests/debugger.cpp
|
||||
_tests/device.cpp
|
||||
_tests/pass.cpp
|
||||
_tests/renderer.cpp
|
||||
_tests/surface.cpp
|
||||
_tests/system.cpp
|
||||
TEST_INTERFACES
|
||||
_tests/utils.cppm
|
||||
|
|
@ -258,25 +268,8 @@ add_module(
|
|||
surface
|
||||
renderer
|
||||
camera
|
||||
# TESTS system.test.cpp
|
||||
)
|
||||
|
||||
add_executable(exectest ${CMAKE_CURRENT_SOURCE_DIR}/mirror/entrypoint.cpp)
|
||||
|
||||
target_link_libraries(
|
||||
exectest
|
||||
PRIVATE mirror
|
||||
app
|
||||
time
|
||||
input
|
||||
surface
|
||||
renderer
|
||||
camera
|
||||
)
|
||||
|
||||
# add_executable_module(mirror entrypoint/mirror.cpp)
|
||||
# target_link_libraries(mirror PRIVATE libmirror input)
|
||||
|
||||
if(ENABLE_SANDBOX)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/sandbox/)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
export module app;
|
||||
|
||||
import preliminary;
|
||||
import app.system;
|
||||
import memory.reference;
|
||||
import memory.scope;
|
||||
import std;
|
||||
|
||||
namespace lt::app {
|
||||
export namespace lt::app {
|
||||
|
||||
/** The main application class.
|
||||
* Think of this like an aggregate of systems, you register systems through this interface.
|
||||
* Then they'll tick every "application frame".
|
||||
*/
|
||||
export class Application
|
||||
class Application
|
||||
{
|
||||
public:
|
||||
Application(const Application &) = delete;
|
||||
|
|
@ -54,11 +55,13 @@ void Application::game_loop()
|
|||
const auto &last_tick = system->get_last_tick_result();
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
|
||||
system->tick(TickInfo {
|
||||
.delta_time = now - last_tick.end_time,
|
||||
.budget = std::chrono::milliseconds { 10 },
|
||||
.start_time = now,
|
||||
});
|
||||
system->tick(
|
||||
TickInfo {
|
||||
.delta_time = now - last_tick.end_time,
|
||||
.budget = std::chrono::milliseconds { 10 },
|
||||
.start_time = now,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
for (auto &system : m_systems_to_be_registered)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
export module app.system;
|
||||
import logger;
|
||||
import std;
|
||||
|
||||
namespace lt::app {
|
||||
import preliminary;
|
||||
import logger;
|
||||
|
||||
export namespace lt::app {
|
||||
|
||||
/** Information required to tick a system.
|
||||
* @note May be used across an entire application-frame (consisting of multiple systems ticking)
|
||||
*/
|
||||
export struct TickInfo
|
||||
struct TickInfo
|
||||
{
|
||||
using Timepoint_T = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
|
||||
using Duration_T = std::chrono::duration<double>;
|
||||
using Duration_T = std::chrono::duration<f64>;
|
||||
|
||||
/** Duration since previous tick's end_time to current tick's start_time. */
|
||||
Duration_T delta_time {};
|
||||
|
|
@ -30,11 +31,11 @@ export struct TickInfo
|
|||
};
|
||||
|
||||
/** Information about how a system's tick performed */
|
||||
export struct TickResult
|
||||
struct TickResult
|
||||
{
|
||||
using Timepoint_T = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
|
||||
using Duration_T = std::chrono::duration<double>;
|
||||
using Duration_T = std::chrono::duration<f64>;
|
||||
|
||||
/** The info supplied to the system for ticking. */
|
||||
TickInfo info;
|
||||
|
|
@ -46,9 +47,9 @@ export struct TickResult
|
|||
Timepoint_T end_time;
|
||||
};
|
||||
|
||||
export struct SystemDiagnosis
|
||||
struct SystemDiagnosis
|
||||
{
|
||||
enum class Severity : std::uint8_t
|
||||
enum class Severity : u8
|
||||
{
|
||||
verbose,
|
||||
info,
|
||||
|
|
@ -64,7 +65,7 @@ export struct SystemDiagnosis
|
|||
Severity severity;
|
||||
};
|
||||
|
||||
export class SystemStats
|
||||
class SystemStats
|
||||
{
|
||||
public:
|
||||
void push_diagnosis(SystemDiagnosis &&diagnosis)
|
||||
|
|
@ -83,7 +84,7 @@ private:
|
|||
std::vector<SystemDiagnosis> m_diagnosis;
|
||||
};
|
||||
|
||||
export class ISystem
|
||||
class ISystem
|
||||
{
|
||||
public:
|
||||
ISystem() = default;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
export module bakers;
|
||||
|
||||
import preliminary;
|
||||
import debug.assertions;
|
||||
import assets.metadata;
|
||||
import assets.shader;
|
||||
import logger;
|
||||
import std;
|
||||
|
||||
export void bake_shader(
|
||||
const std::filesystem::path &in_path,
|
||||
|
|
@ -47,7 +47,7 @@ export void bake_shader(
|
|||
stream.seekg(0, std::ios::end);
|
||||
const auto size = stream.tellg();
|
||||
|
||||
auto bytes = std::vector<std::byte>(size);
|
||||
auto bytes = std::vector<byte>(size);
|
||||
stream.seekg(0, std::ios::beg);
|
||||
stream.read((char *)bytes.data(), size); // NOLINT
|
||||
stream.close();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import preliminary;
|
||||
import assets.shader;
|
||||
import logger;
|
||||
import bakers;
|
||||
import std;
|
||||
|
||||
auto main(int argc, char *argv[]) -> std::int32_t
|
||||
auto main(i32 argc, char *argv[]) -> i32
|
||||
try
|
||||
{
|
||||
if (argc != 2)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
export module assets.metadata;
|
||||
import std;
|
||||
|
||||
import preliminary;
|
||||
|
||||
export namespace lt::assets {
|
||||
|
||||
using Type_T = std::array<const char, 16>;
|
||||
|
||||
using Tag_T = std::uint8_t;
|
||||
using Tag_T = u8;
|
||||
|
||||
using Version = std::uint8_t;
|
||||
using Version = u8;
|
||||
|
||||
using Blob = std::vector<std::byte>;
|
||||
using Blob = std::vector<byte>;
|
||||
|
||||
constexpr auto current_version = Version { 1u };
|
||||
|
||||
enum class CompressionType : std::uint8_t
|
||||
enum class CompressionType : u8
|
||||
{
|
||||
none,
|
||||
lz4,
|
||||
|
|
@ -31,13 +32,13 @@ struct BlobMetadata
|
|||
{
|
||||
Tag_T tag;
|
||||
|
||||
std::size_t offset;
|
||||
size_t offset;
|
||||
|
||||
CompressionType compression_type;
|
||||
|
||||
std::size_t compressed_size;
|
||||
size_t compressed_size;
|
||||
|
||||
std::size_t uncompressed_size;
|
||||
size_t uncompressed_size;
|
||||
};
|
||||
|
||||
} // namespace lt::assets
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
export module assets.shader;
|
||||
|
||||
import preliminary;
|
||||
import assets.metadata;
|
||||
import logger;
|
||||
import debug.assertions;
|
||||
|
||||
import std;
|
||||
|
||||
export namespace lt::assets {
|
||||
|
||||
class ShaderAsset
|
||||
|
|
@ -17,7 +17,7 @@ public:
|
|||
code,
|
||||
};
|
||||
|
||||
enum class Type : std::uint8_t
|
||||
enum class Type : u8
|
||||
{
|
||||
vertex,
|
||||
fragment,
|
||||
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
ShaderAsset(const std::filesystem::path &path);
|
||||
|
||||
void unpack_to(BlobTag tag, std::span<std::byte> destination) const;
|
||||
void unpack_to(BlobTag tag, std::span<byte> destination) const;
|
||||
|
||||
[[nodiscard]] auto unpack(BlobTag tag) const -> Blob;
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path)
|
|||
};
|
||||
|
||||
m_stream.seekg(0, std::ifstream::end);
|
||||
const auto file_size = static_cast<std::size_t>(m_stream.tellg());
|
||||
const auto file_size = static_cast<size_t>(m_stream.tellg());
|
||||
debug::ensure(
|
||||
file_size > total_metadata_size,
|
||||
"Failed to open shader asset at: {}, file smaller than metadata: {} < {}",
|
||||
|
|
@ -193,7 +193,7 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path)
|
|||
stream.write(std::bit_cast<char *>(code_blob.data()), static_cast<long long>(code_blob.size()));
|
||||
}
|
||||
|
||||
void ShaderAsset::unpack_to(BlobTag tag, std::span<std::byte> destination) const
|
||||
void ShaderAsset::unpack_to(BlobTag tag, std::span<byte> destination) const
|
||||
{
|
||||
debug::ensure(
|
||||
tag == BlobTag::code,
|
||||
|
|
@ -206,7 +206,7 @@ void ShaderAsset::unpack_to(BlobTag tag, std::span<std::byte> destination) const
|
|||
"Failed to unpack shader blob {} to destination ({}) of size {} since it's smaller "
|
||||
"than the blobl's uncompressed size: {}",
|
||||
std::to_underlying(tag),
|
||||
std::bit_cast<std::size_t>(destination.data()),
|
||||
std::bit_cast<size_t>(destination.data()),
|
||||
destination.size(),
|
||||
m_code_blob_metadata.uncompressed_size
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import preliminary;
|
||||
import assets.metadata;
|
||||
import assets.shader;
|
||||
import logger;
|
||||
import logger;
|
||||
import test.test;
|
||||
import test.expects;
|
||||
import std;
|
||||
|
||||
using ::lt::assets::AssetMetadata;
|
||||
using ::lt::assets::BlobMetadata;
|
||||
|
|
@ -30,7 +30,7 @@ Suite raii = "shader_raii"_suite = [] {
|
|||
Case { "many won't freeze/throw" } = [] {
|
||||
for (auto idx : std::views::iota(0u, 1'000u))
|
||||
{
|
||||
std::ignore = idx;
|
||||
ignore = idx;
|
||||
auto shader_asset = ShaderAsset { "triangle.frag.asset" };
|
||||
}
|
||||
};
|
||||
|
|
@ -58,7 +58,7 @@ Suite packing = "shader_pack"_suite = [] {
|
|||
auto dummy_blob = lt::assets::Blob {};
|
||||
for (auto idx : std::views::iota(0u, 255u))
|
||||
{
|
||||
dummy_blob.emplace_back(static_cast<std::byte>(idx));
|
||||
dummy_blob.emplace_back(static_cast<byte>(idx));
|
||||
}
|
||||
|
||||
const auto expected_size = //
|
||||
|
|
@ -91,7 +91,7 @@ Suite packing = "shader_pack"_suite = [] {
|
|||
expect_true(stream.is_open());
|
||||
|
||||
stream.seekg(0u, std::ios::end);
|
||||
const auto file_size = static_cast<std::size_t>(stream.tellg());
|
||||
const auto file_size = static_cast<size_t>(stream.tellg());
|
||||
expect_eq(file_size, expected_size);
|
||||
stream.close();
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ Suite packing = "shader_pack"_suite = [] {
|
|||
|
||||
for (auto idx : std::views::iota(0u, 255u))
|
||||
{
|
||||
expect_eq(blob[idx], static_cast<std::byte>(idx));
|
||||
expect_eq(blob[idx], static_cast<byte>(idx));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
export module bitwise;
|
||||
import std;
|
||||
import preliminary;
|
||||
|
||||
namespace lt::bitwise {
|
||||
|
||||
/* bit-wise */
|
||||
export constexpr auto bit(std::uint32_t x) -> std::uint32_t
|
||||
export constexpr auto bit(u32 x) -> u32
|
||||
{
|
||||
return 1u << x;
|
||||
return u32 { 1u } << x;
|
||||
}
|
||||
|
||||
} // namespace lt::bitwise
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
export module camera.components;
|
||||
|
||||
import preliminary;
|
||||
import math.vec4;
|
||||
|
||||
namespace lt::camera::components {
|
||||
export namespace lt::camera::components {
|
||||
|
||||
export struct PerspectiveCamera
|
||||
struct PerspectiveCamera
|
||||
{
|
||||
float vertical_fov {};
|
||||
f32 vertical_fov {};
|
||||
|
||||
float near_plane {};
|
||||
f32 near_plane {};
|
||||
|
||||
float far_plane {};
|
||||
f32 far_plane {};
|
||||
|
||||
float aspect_ratio {};
|
||||
f32 aspect_ratio {};
|
||||
|
||||
math::vec4 background_color;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export module debug.instrumentor;
|
||||
|
||||
import std;
|
||||
import preliminary;
|
||||
import logger;
|
||||
|
||||
namespace lt::debug {
|
||||
|
|
@ -8,8 +8,8 @@ namespace lt::debug {
|
|||
struct ScopeProfileResult
|
||||
{
|
||||
std::string name;
|
||||
long long start, duration;
|
||||
std::uint32_t threadID;
|
||||
u64 start, duration;
|
||||
u32 threadID;
|
||||
};
|
||||
|
||||
class Instrumentor
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
export module ecs.entity;
|
||||
|
||||
import preliminary;
|
||||
import debug.assertions;
|
||||
import memory.reference;
|
||||
import ecs.registry;
|
||||
import std;
|
||||
|
||||
namespace lt::ecs {
|
||||
export namespace lt::ecs {
|
||||
|
||||
/** High-level entity convenience wrapper */
|
||||
export class Entity
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
Entity(memory::Ref<Registry> registry, EntityId identifier)
|
||||
|
|
@ -51,5 +52,4 @@ private:
|
|||
EntityId m_identifier;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lt::ecs
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
export module ecs.registry;
|
||||
|
||||
import preliminary;
|
||||
import debug.assertions;
|
||||
import ecs.sparse_set;
|
||||
import memory.scope;
|
||||
import std;
|
||||
|
||||
namespace lt::ecs {
|
||||
export namespace lt::ecs {
|
||||
|
||||
export using EntityId = std::uint32_t;
|
||||
using EntityId = u32;
|
||||
|
||||
export constexpr auto null_entity = std::numeric_limits<EntityId>::max();
|
||||
constexpr auto null_entity = std::numeric_limits<EntityId>::max();
|
||||
|
||||
/** A registry of components, the heart of an ECS architecture.
|
||||
*
|
||||
|
|
@ -23,7 +24,7 @@ export constexpr auto null_entity = std::numeric_limits<EntityId>::max();
|
|||
* @ref https://github.com/skypjack/entt
|
||||
* @ref https://github.com/SanderMertens/flecs
|
||||
*/
|
||||
export class Registry
|
||||
class Registry
|
||||
{
|
||||
public:
|
||||
using UnderlyingSparseSet_T = TypeErasedSparseSet<EntityId>;
|
||||
|
|
@ -190,25 +191,25 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] auto get_entity_count() const -> std::size_t
|
||||
[[nodiscard]] auto get_entity_count() const -> size_t
|
||||
{
|
||||
return static_cast<std::size_t>(m_entity_count);
|
||||
return static_cast<size_t>(m_entity_count);
|
||||
}
|
||||
|
||||
private:
|
||||
using TypeId = std::size_t;
|
||||
using TypeId = size_t;
|
||||
|
||||
static consteval auto hash_cstr(const char *str) -> TypeId
|
||||
{
|
||||
constexpr auto fnv_offset_basis = std::size_t { 14695981039346656037ull };
|
||||
constexpr auto fnv_prime = std::size_t { 1099511628211ull };
|
||||
constexpr auto fnv_offset_basis = size_t { 14695981039346656037ull };
|
||||
constexpr auto fnv_prime = size_t { 1099511628211ull };
|
||||
|
||||
auto hash = fnv_offset_basis;
|
||||
|
||||
for (const auto &ch : std::string_view { str })
|
||||
{
|
||||
hash *= fnv_prime;
|
||||
hash ^= static_cast<std::uint8_t>(ch);
|
||||
hash ^= static_cast<u8>(ch);
|
||||
}
|
||||
|
||||
return hash;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import preliminary;
|
||||
import ecs.registry;
|
||||
import test.test;
|
||||
import test.expects;
|
||||
import std;
|
||||
|
||||
using ::lt::ecs::EntityId;
|
||||
using ::lt::ecs::Registry;
|
||||
|
|
@ -15,7 +15,7 @@ using ::lt::test::operator""_suite;
|
|||
|
||||
struct Component
|
||||
{
|
||||
int m_int {};
|
||||
i32 m_int {};
|
||||
std::string m_string;
|
||||
|
||||
[[nodiscard]] friend auto operator==(const Component &lhs, const Component &rhs) -> bool
|
||||
|
|
@ -39,7 +39,7 @@ struct std::formatter<Component>
|
|||
|
||||
struct Component_B
|
||||
{
|
||||
float m_float {};
|
||||
f32 m_float {};
|
||||
|
||||
[[nodiscard]] friend auto operator==(const Component_B lhs, const Component_B &rhs) -> bool
|
||||
{
|
||||
|
|
@ -62,14 +62,14 @@ struct std::formatter<Component_B>
|
|||
|
||||
Suite raii = "raii"_suite = [] {
|
||||
Case { "happy path won't throw" } = [] {
|
||||
std::ignore = Registry {};
|
||||
ignore = Registry {};
|
||||
};
|
||||
|
||||
Case { "many won't freeze/throw" } = [] {
|
||||
for (auto idx : std::views::iota(0, 100'000))
|
||||
{
|
||||
std::ignore = idx;
|
||||
std::ignore = Registry {};
|
||||
ignore = idx;
|
||||
ignore = Registry {};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ Suite callbacks = "callbacks"_suite = [] {
|
|||
|
||||
for (auto idx : std::views::iota(0, 100'000))
|
||||
{
|
||||
std::ignore = idx;
|
||||
ignore = idx;
|
||||
registry.add<Component_B>(registry.create_entity(), {});
|
||||
}
|
||||
};
|
||||
|
|
@ -191,7 +191,7 @@ Suite callbacks = "callbacks"_suite = [] {
|
|||
expect_true(on_destruct_called.empty());
|
||||
for (auto idx : std::views::iota(0, 100'000))
|
||||
{
|
||||
std::ignore = idx;
|
||||
ignore = idx;
|
||||
|
||||
auto entity = all_entities.emplace_back(registry.create_entity());
|
||||
registry.add<Component>(entity, {});
|
||||
|
|
@ -242,7 +242,7 @@ Suite each = "each"_suite = [] {
|
|||
}
|
||||
auto &component = registry.add<Component_B>(
|
||||
entity,
|
||||
{ .m_float = static_cast<float>(idx) / 2.0f }
|
||||
{ .m_float = static_cast<f32>(idx) / 2.0f }
|
||||
);
|
||||
|
||||
component_map_b[entity] = component;
|
||||
|
|
@ -313,7 +313,7 @@ Suite views = "views"_suite = [] {
|
|||
}
|
||||
auto &component = registry.add<Component_B>(
|
||||
entity,
|
||||
{ .m_float = static_cast<float>(idx) / 2.0f }
|
||||
{ .m_float = static_cast<f32>(idx) / 2.0f }
|
||||
);
|
||||
|
||||
component_map_b[entity] = component;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
export module ecs.sparse_set;
|
||||
import debug.assertions;
|
||||
import std;
|
||||
|
||||
namespace lt::ecs {
|
||||
import preliminary;
|
||||
import debug.assertions;
|
||||
|
||||
export namespace lt::ecs {
|
||||
|
||||
/**
|
||||
* @ref https://programmingpraxis.com/2012/03/09/sparse-sets/
|
||||
*/
|
||||
export template<typename Identifier_T = std::uint32_t>
|
||||
template<typename Identifier_T = u32>
|
||||
class TypeErasedSparseSet
|
||||
{
|
||||
public:
|
||||
|
|
@ -26,17 +27,17 @@ public:
|
|||
virtual void remove(Identifier_T identifier) = 0;
|
||||
};
|
||||
|
||||
export template<typename Value_T, typename Identifier_T = std::uint32_t>
|
||||
template<typename Value_T, typename Identifier_T = u32>
|
||||
class SparseSet: public TypeErasedSparseSet<Identifier_T>
|
||||
{
|
||||
public:
|
||||
using Dense_T = std::pair<Identifier_T, Value_T>;
|
||||
|
||||
static constexpr auto max_capacity = std::size_t { 1'000'000 };
|
||||
static constexpr auto max_capacity = size_t { 1'000'000 };
|
||||
|
||||
static constexpr auto null_identifier = std::numeric_limits<Identifier_T>().max();
|
||||
|
||||
explicit SparseSet(std::size_t initial_capacity = 1)
|
||||
explicit SparseSet(size_t initial_capacity = 1)
|
||||
{
|
||||
debug::ensure(
|
||||
initial_capacity <= max_capacity,
|
||||
|
|
@ -53,10 +54,7 @@ public:
|
|||
{
|
||||
if (m_sparse.size() < identifier + 1)
|
||||
{
|
||||
auto new_capacity = std::max(
|
||||
static_cast<std::size_t>(identifier + 1),
|
||||
m_sparse.size() * 2
|
||||
);
|
||||
auto new_capacity = std::max(static_cast<size_t>(identifier + 1), m_sparse.size() * 2);
|
||||
new_capacity = std::min(new_capacity, max_capacity);
|
||||
|
||||
m_sparse.resize(new_capacity, null_identifier);
|
||||
|
|
@ -144,12 +142,12 @@ public:
|
|||
return std::forward<Self_T>(self).m_dense[std::forward<Self_T>(self).m_sparse[identifier]];
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_size() const noexcept -> std::size_t
|
||||
[[nodiscard]] auto get_size() const noexcept -> size_t
|
||||
{
|
||||
return m_alive_count;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_capacity() const noexcept -> std::size_t
|
||||
[[nodiscard]] auto get_capacity() const noexcept -> size_t
|
||||
{
|
||||
return m_sparse.capacity();
|
||||
}
|
||||
|
|
@ -164,9 +162,9 @@ private:
|
|||
|
||||
std::vector<Identifier_T> m_sparse;
|
||||
|
||||
std::size_t m_alive_count {};
|
||||
size_t m_alive_count {};
|
||||
|
||||
std::size_t m_dead_count {};
|
||||
size_t m_dead_count {};
|
||||
};
|
||||
|
||||
} // namespace lt::ecs
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import preliminary;
|
||||
import ecs.sparse_set;
|
||||
import test.test;
|
||||
import test.expects;
|
||||
import std;
|
||||
|
||||
using ::lt::test::Case;
|
||||
using ::lt::test::expect_eq;
|
||||
|
|
@ -12,18 +12,18 @@ using ::lt::test::expect_true;
|
|||
using ::lt::test::Suite;
|
||||
using ::lt::test::operator""_suite;
|
||||
|
||||
using Value_T = int;
|
||||
using Value_T = i32;
|
||||
using Set = lt::ecs::SparseSet<Value_T>;
|
||||
constexpr auto capacity = 100;
|
||||
|
||||
Suite raii = "raii"_suite = [] {
|
||||
Case { "happy path won't throw" } = [] {
|
||||
std::ignore = Set {};
|
||||
std::ignore = Set { Set::max_capacity };
|
||||
ignore = Set {};
|
||||
ignore = Set { Set::max_capacity };
|
||||
};
|
||||
|
||||
Case { "unhappy path throws" } = [] {
|
||||
expect_throw([] { std::ignore = Set { Set::max_capacity + 1 }; });
|
||||
expect_throw([] { ignore = Set { Set::max_capacity + 1 }; });
|
||||
};
|
||||
|
||||
Case { "post construct has correct state" } = [&] {
|
||||
|
|
@ -78,7 +78,7 @@ Suite element_raii = "element_raii"_suite = [] {
|
|||
|
||||
expect_eq(set.get_size(), 10'000 - (idx + 1));
|
||||
expect_false(set.contains(idx));
|
||||
expect_throw([&] { std::ignore = set.at(idx); });
|
||||
expect_throw([&] { ignore = set.at(idx); });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -141,12 +141,12 @@ Suite getters = "getters"_suite = [] {
|
|||
{
|
||||
expect_throw([&] {
|
||||
set.insert(idx, {});
|
||||
std::ignore = set.at(50);
|
||||
ignore = set.at(50);
|
||||
});
|
||||
}
|
||||
|
||||
set.insert(50, {});
|
||||
std::ignore = set.at(50); // should not throw
|
||||
ignore = set.at(50); // should not throw
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
13
modules/env/constants.cppm
vendored
13
modules/env/constants.cppm
vendored
|
|
@ -1,10 +1,10 @@
|
|||
export module env;
|
||||
|
||||
import std;
|
||||
import preliminary;
|
||||
|
||||
namespace lt {
|
||||
export namespace lt {
|
||||
|
||||
enum class Platform : std::uint8_t
|
||||
enum class Platform : u8
|
||||
{
|
||||
/** The GNU/Linux platform.
|
||||
* Tested on the following distros: arch-x86_64
|
||||
|
|
@ -26,7 +26,7 @@ enum class Platform : std::uint8_t
|
|||
};
|
||||
|
||||
/** The compiler that was used for compiling the project. */
|
||||
enum class Compiler : std::uint8_t
|
||||
enum class Compiler : u8
|
||||
{
|
||||
clang,
|
||||
gcc,
|
||||
|
|
@ -57,12 +57,13 @@ constexpr auto platform_name = "mac";
|
|||
|
||||
#endif
|
||||
|
||||
/** @TODO(Light): Handle other compilers... */
|
||||
#ifdef __clang__
|
||||
constexpr auto compiler = Compiler::clang;
|
||||
constexpr auto compiler_name = "clang";
|
||||
|
||||
/** @todo(Light): insert the full identifier, including version information and such */
|
||||
constexpr auto full_compiler_identifier = "clang";
|
||||
/** @TODO(Light): insert the full identifier, including version information and such */
|
||||
constexpr auto compiler_identifier = "clang";
|
||||
#endif
|
||||
|
||||
} // namespace constants
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
export module input.system:components;
|
||||
|
||||
import preliminary;
|
||||
import input.codes;
|
||||
import std;
|
||||
|
||||
namespace lt::input {
|
||||
export namespace lt::input {
|
||||
|
||||
export struct Trigger
|
||||
struct Trigger
|
||||
{
|
||||
Key mapped_keycode;
|
||||
};
|
||||
|
||||
export struct InputAction
|
||||
struct InputAction
|
||||
{
|
||||
enum class State : std::uint8_t
|
||||
enum class State : u8
|
||||
{
|
||||
inactive,
|
||||
active,
|
||||
|
|
@ -26,18 +27,18 @@ export struct InputAction
|
|||
Trigger trigger;
|
||||
};
|
||||
|
||||
export class InputComponent
|
||||
class InputComponent
|
||||
{
|
||||
public:
|
||||
InputComponent() = default;
|
||||
|
||||
auto add_action(InputAction action) -> std::size_t
|
||||
auto add_action(InputAction action) -> size_t
|
||||
{
|
||||
m_actions.emplace_back(std::move(action));
|
||||
return m_actions.size() - 1;
|
||||
}
|
||||
|
||||
auto get_action(std::size_t idx) -> const InputAction &
|
||||
auto get_action(size_t idx) -> const InputAction &
|
||||
{
|
||||
return m_actions[idx];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import surface.system;
|
|||
using namespace lt;
|
||||
using input::InputComponent;
|
||||
using input::System;
|
||||
using std::ignore;
|
||||
using test::Case;
|
||||
using test::expect_eq;
|
||||
using test::expect_false;
|
||||
|
|
@ -79,7 +78,7 @@ Suite raii = "raii"_suite = "raii"_suite = [] {
|
|||
auto fixture = Fixture {};
|
||||
for (auto idx : std::views::iota(0, 10'000))
|
||||
{
|
||||
std::ignore = idx;
|
||||
ignore = idx;
|
||||
ignore = System { fixture.registry() };
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,17 @@
|
|||
/**
|
||||
* @note: The reason this is a separate module, rather than being in the `Input` module is that
|
||||
* the input is received from the hardware through the `Surface` module, and it is further parsed
|
||||
* inside the `Input` module, USING the `Surface` module's events.
|
||||
*
|
||||
* Hence, both `Surface` and `Input` needs to agree to the same input codes, while `Input` depends
|
||||
* on `Surface`. The simplest solution is to keep the codes in a 3rd module and make both depend on
|
||||
* it.
|
||||
*/
|
||||
export module input.codes;
|
||||
import std;
|
||||
|
||||
export enum class Key: std::uint16_t {
|
||||
import preliminary;
|
||||
|
||||
export enum class Key: u16 {
|
||||
none = 0,
|
||||
|
||||
left_button,
|
||||
|
|
@ -153,6 +163,7 @@ export enum class Key: std::uint16_t {
|
|||
f11,
|
||||
f12,
|
||||
|
||||
/** Input was received but was none of the above. */
|
||||
unknown,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
export module logger;
|
||||
|
||||
import std;
|
||||
import preliminary;
|
||||
|
||||
namespace lt::log {
|
||||
|
||||
/** Severity of a log message. */
|
||||
enum class Level : std::uint8_t
|
||||
enum class Level : u8
|
||||
{
|
||||
/** Lowest and most vebose log level, for tracing execution paths and events */
|
||||
trace = 0,
|
||||
|
|
@ -31,9 +31,9 @@ enum class Level : std::uint8_t
|
|||
|
||||
namespace details {
|
||||
|
||||
inline auto thread_hash_id() noexcept -> std::uint64_t
|
||||
inline auto thread_hash_id() noexcept -> u64
|
||||
{
|
||||
return static_cast<std::uint64_t>(std::hash<std::thread::id> {}(std::this_thread::get_id()));
|
||||
return static_cast<u64>(std::hash<std::thread::id> {}(std::this_thread::get_id()));
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export module math.components;
|
||||
|
||||
import preliminary;
|
||||
import math.vec3;
|
||||
|
||||
namespace lt::math::components {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
export module math.mat4;
|
||||
|
||||
import preliminary;
|
||||
import math.vec2;
|
||||
import math.vec3;
|
||||
import math.vec4;
|
||||
import std;
|
||||
|
||||
namespace lt::math {
|
||||
|
||||
export template<typename T = float>
|
||||
export template<typename T = f32>
|
||||
struct mat4_impl
|
||||
{
|
||||
using Column_T = vec4_impl<T>;
|
||||
|
|
@ -54,12 +56,12 @@ struct mat4_impl
|
|||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator[](std::size_t idx) -> Column_T &
|
||||
[[nodiscard]] constexpr auto operator[](size_t idx) -> Column_T &
|
||||
{
|
||||
return values[idx];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator[](std::size_t idx) const -> const Column_T &
|
||||
[[nodiscard]] constexpr auto operator[](size_t idx) const -> const Column_T &
|
||||
{
|
||||
return values[idx];
|
||||
}
|
||||
|
|
@ -84,7 +86,7 @@ export template<typename T>
|
|||
}
|
||||
|
||||
export template<typename T>
|
||||
[[nodiscard]] auto rotate(float value, const vec3_impl<T> &xyz) -> mat4_impl<T>
|
||||
[[nodiscard]] auto rotate(f32 value, const vec3_impl<T> &xyz) -> mat4_impl<T>
|
||||
{
|
||||
return mat4_impl<T> {};
|
||||
}
|
||||
|
|
@ -101,10 +103,10 @@ export template<typename T>
|
|||
return mat4_impl<T> {};
|
||||
}
|
||||
|
||||
export using mat4 = mat4_impl<float>;
|
||||
export using mat4 = mat4_impl<f32>;
|
||||
|
||||
export using imat4 = mat4_impl<std::int32_t>;
|
||||
export using imat4 = mat4_impl<i32>;
|
||||
|
||||
export using umat4 = mat4_impl<std::uint32_t>;
|
||||
export using umat4 = mat4_impl<u32>;
|
||||
|
||||
} // namespace lt::math
|
||||
|
|
|
|||
|
|
@ -1,26 +1,27 @@
|
|||
export module math.trig;
|
||||
|
||||
import preliminary;
|
||||
|
||||
export namespace lt::math {
|
||||
|
||||
[[nodiscard]] constexpr auto radians(float degrees) -> float
|
||||
[[nodiscard]] constexpr auto radians(f32 degrees) -> f32
|
||||
{
|
||||
return degrees * 0.01745329251994329576923690768489f;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto radians(double degrees) -> double
|
||||
[[nodiscard]] constexpr auto radians(f64 degrees) -> f64
|
||||
{
|
||||
return degrees * 0.01745329251994329576923690768489;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto degrees(float radians) -> float
|
||||
[[nodiscard]] constexpr auto degrees(f32 radians) -> f32
|
||||
{
|
||||
return radians * 57.295779513082320876798154814105f;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto degrees(double radians) -> double
|
||||
[[nodiscard]] constexpr auto degrees(f64 radians) -> f64
|
||||
{
|
||||
return radians * 57.295779513082320876798154814105;
|
||||
}
|
||||
|
||||
|
||||
} // namespace lt::math
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
export module math.vec2;
|
||||
|
||||
import std;
|
||||
import preliminary;
|
||||
|
||||
namespace lt::math {
|
||||
|
||||
export template<typename T = float>
|
||||
export template<typename T = f32>
|
||||
struct vec2_impl
|
||||
{
|
||||
constexpr vec2_impl(): x(), y()
|
||||
|
|
@ -45,7 +45,7 @@ struct vec2_impl
|
|||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] auto operator*(float scalar) const -> vec2_impl
|
||||
[[nodiscard]] auto operator*(f32 scalar) const -> vec2_impl
|
||||
{
|
||||
return {
|
||||
x * scalar,
|
||||
|
|
@ -59,11 +59,11 @@ struct vec2_impl
|
|||
};
|
||||
|
||||
|
||||
export using vec2 = vec2_impl<float>;
|
||||
export using vec2 = vec2_impl<f32>;
|
||||
|
||||
export using ivec2 = vec2_impl<std::int32_t>;
|
||||
export using ivec2 = vec2_impl<i32>;
|
||||
|
||||
export using uvec2 = vec2_impl<std::uint32_t>;
|
||||
export using uvec2 = vec2_impl<u32>;
|
||||
|
||||
} // namespace lt::math
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
export module math.vec3;
|
||||
|
||||
import preliminary;
|
||||
import math.vec2;
|
||||
import std;
|
||||
|
||||
namespace lt::math {
|
||||
|
||||
export template<typename T = float>
|
||||
export template<typename T = f32>
|
||||
struct vec3_impl
|
||||
{
|
||||
constexpr vec3_impl(): x(), y(), z()
|
||||
|
|
@ -61,11 +61,11 @@ struct vec3_impl
|
|||
T z; // NOLINT
|
||||
};
|
||||
|
||||
export using vec3 = vec3_impl<float>;
|
||||
export using vec3 = vec3_impl<f32>;
|
||||
|
||||
export using ivec3 = vec3_impl<std::int32_t>;
|
||||
export using ivec3 = vec3_impl<i32>;
|
||||
|
||||
export using uvec3 = vec3_impl<std::uint32_t>;
|
||||
export using uvec3 = vec3_impl<u32>;
|
||||
|
||||
} // namespace lt::math
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
export module math.vec4;
|
||||
|
||||
import preliminary;
|
||||
import math.vec2;
|
||||
import debug.assertions;
|
||||
import math.vec3;
|
||||
import std;
|
||||
import debug.assertions;
|
||||
|
||||
namespace lt::math {
|
||||
|
||||
export template<typename T = float>
|
||||
export template<typename T = f32>
|
||||
struct vec4_impl
|
||||
{
|
||||
static constexpr auto num_elements = 4u;
|
||||
|
|
@ -43,14 +44,14 @@ struct vec4_impl
|
|||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator[](std::uint8_t idx) -> T &
|
||||
[[nodiscard]] constexpr auto operator[](u8 idx) -> T &
|
||||
{
|
||||
// TODO(Light): Use contract
|
||||
debug::ensure(idx <= num_elements, "vec4 out of bound: {}", idx);
|
||||
return ((T *)this)[idx];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator[](std::uint8_t idx) const -> const T &
|
||||
[[nodiscard]] constexpr auto operator[](u8 idx) const -> const T &
|
||||
{
|
||||
// TODO(Light): Use contract
|
||||
debug::ensure(idx < num_elements, "vec4 out of bound: {}", idx);
|
||||
|
|
@ -72,11 +73,11 @@ struct vec4_impl
|
|||
T w;
|
||||
};
|
||||
|
||||
export using vec4 = vec4_impl<float>;
|
||||
export using vec4 = vec4_impl<f32>;
|
||||
|
||||
export using ivec4 = vec4_impl<std::int32_t>;
|
||||
export using ivec4 = vec4_impl<i32>;
|
||||
|
||||
export using uvec4 = vec4_impl<std::uint32_t>;
|
||||
export using uvec4 = vec4_impl<u32>;
|
||||
|
||||
} // namespace lt::math
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ export module memory.null_on_move;
|
|||
|
||||
import logger;
|
||||
|
||||
import std;
|
||||
import preliminary;
|
||||
|
||||
namespace lt::memory {
|
||||
|
||||
|
|
@ -81,9 +81,9 @@ public:
|
|||
return m_value;
|
||||
}
|
||||
|
||||
operator std::uint64_t() const
|
||||
operator u64() const
|
||||
{
|
||||
return (std::uint64_t)m_value;
|
||||
return (u64)m_value;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get() -> Underlying_T &
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export module memory.reference;
|
||||
|
||||
import std;
|
||||
import preliminary;
|
||||
|
||||
namespace lt::memory {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export module memory.scope;
|
||||
|
||||
import std;
|
||||
import preliminary;
|
||||
|
||||
namespace lt::memory {
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ import mirror.system;
|
|||
import renderer.factory;
|
||||
|
||||
/** The ultimate entrypoint. */
|
||||
auto main(int argc, char *argv[]) -> std::int32_t
|
||||
auto main(i32 argc, char *argv[]) -> i32
|
||||
{
|
||||
try
|
||||
{
|
||||
std::ignore = argc;
|
||||
std::ignore = argv;
|
||||
ignore = argc;
|
||||
ignore = argv;
|
||||
|
||||
auto application = lt::memory::create_scope<lt::Mirror>();
|
||||
if (!application)
|
||||
|
|
|
|||
|
|
@ -1,227 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <app/layer.hpp>
|
||||
#include <imgui.h>
|
||||
#include <math/vec2.hpp>
|
||||
#include <memory/reference.hpp>
|
||||
#include <mirror/panels/asset_browser.hpp>
|
||||
#include <mirror/panels/properties.hpp>
|
||||
#include <mirror/panels/scene_hierarchy.hpp>
|
||||
#include <renderer/texture.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
class Scene;
|
||||
|
||||
class EditorLayer: public Layer
|
||||
{
|
||||
public:
|
||||
EditorLayer(const std::string &name);
|
||||
|
||||
~EditorLayer() override;
|
||||
|
||||
EditorLayer(EditorLayer &&) = delete;
|
||||
|
||||
EditorLayer(const EditorLayer &) = delete;
|
||||
|
||||
auto operator=(EditorLayer &&) const -> EditorLayer & = delete;
|
||||
|
||||
auto operator=(const EditorLayer &) const -> EditorLayer & = delete;
|
||||
|
||||
void on_update(float delta_time) override;
|
||||
|
||||
void on_render() override;
|
||||
|
||||
void on_user_interface_update() override;
|
||||
|
||||
private:
|
||||
std::string m_scene_dir;
|
||||
|
||||
math::vec2 m_direction;
|
||||
|
||||
float m_speed = 1000.0f;
|
||||
|
||||
memory::Ref<Scene> m_scene;
|
||||
|
||||
memory::Ref<SceneHierarchyPanel> m_sceneHierarchyPanel;
|
||||
|
||||
memory::Ref<PropertiesPanel> m_properties_panel;
|
||||
|
||||
memory::Ref<AssetBrowserPanel> m_content_browser_panel;
|
||||
|
||||
memory::Ref<Framebuffer> m_framebuffer;
|
||||
|
||||
Entity m_camera_entity;
|
||||
|
||||
ImVec2 m_available_content_region_prev;
|
||||
};
|
||||
|
||||
} // namespace lt
|
||||
|
||||
|
||||
#include <app/application.hpp>
|
||||
#include <asset_manager/asset_manager.hpp>
|
||||
#include <camera/component.hpp>
|
||||
#include <ecs/components.hpp>
|
||||
#include <ecs/registry.hpp>
|
||||
#include <ecs/serializer.hpp>
|
||||
#include <input/input.hpp>
|
||||
#include <input/key_codes.hpp>
|
||||
#include <math/vec4.hpp>
|
||||
#include <memory/reference.hpp>
|
||||
#include <mirror/layers/editor_layer.hpp>
|
||||
#include <renderer/framebuffer.hpp>
|
||||
#include <renderer/texture.hpp>
|
||||
#include <ui/ui.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
EditorLayer::EditorLayer(const std::string &name)
|
||||
: Layer(name)
|
||||
, m_scene_dir("")
|
||||
, m_direction { 0.0, 0.0 }
|
||||
{
|
||||
m_scene = memory::create_ref<Scene>();
|
||||
|
||||
m_properties_panel = memory::create_ref<PropertiesPanel>();
|
||||
m_sceneHierarchyPanel = memory::create_ref<SceneHierarchyPanel>(m_scene, m_properties_panel);
|
||||
m_content_browser_panel = memory::create_ref<AssetBrowserPanel>(m_scene);
|
||||
|
||||
m_framebuffer = Framebuffer::create(
|
||||
{
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.samples = 1,
|
||||
},
|
||||
GraphicsContext::get_shared_context()
|
||||
);
|
||||
|
||||
if (m_scene_dir.empty())
|
||||
{
|
||||
m_camera_entity = m_scene->create_entity("Camera");
|
||||
m_camera_entity.add_component<CameraComponent>(SceneCamera(), true);
|
||||
|
||||
AssetManager::load_texture("Awesomeface", "data/assets/textures/awesomeface.asset");
|
||||
|
||||
auto entity = Entity { m_scene->create_entity("Awesomeface", {}) };
|
||||
entity.add_component<SpriteRendererComponent>(
|
||||
AssetManager::get_texture("Awesomeface"),
|
||||
math::vec4 { 0.0f, 1.0f, 1.0f, 1.0f }
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto serializer = SceneSerializer { m_scene };
|
||||
ensure(serializer.deserialize(m_scene_dir), "Failed to de-serialize: {}", m_scene_dir);
|
||||
|
||||
// m_camera_entity = m_scene->GetEntityByTag("Game Camera");
|
||||
}
|
||||
}
|
||||
|
||||
EditorLayer::~EditorLayer()
|
||||
{
|
||||
if (!m_scene_dir.empty())
|
||||
{
|
||||
auto serializer = SceneSerializer { m_scene };
|
||||
serializer.serialize(m_scene_dir);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorLayer::on_update(float delta_time)
|
||||
{
|
||||
m_scene->on_update(delta_time);
|
||||
|
||||
if (Input::get_keyboard_key(Key::A))
|
||||
{
|
||||
m_direction.x = -1.0;
|
||||
}
|
||||
else if (Input::get_keyboard_key(Key::D))
|
||||
{
|
||||
m_direction.x = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_direction.x = 0.0;
|
||||
}
|
||||
|
||||
if (Input::get_keyboard_key(Key::S))
|
||||
{
|
||||
m_direction.y = -1.0;
|
||||
}
|
||||
else if (Input::get_keyboard_key(Key::W))
|
||||
{
|
||||
m_direction.y = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_direction.y = 0.0;
|
||||
}
|
||||
|
||||
auto &translation = m_camera_entity.get_component<TransformComponent>().translation;
|
||||
auto velocity = m_direction * m_speed * delta_time;
|
||||
translation = translation * math::vec3 { velocity.x, velocity.y, 0.0f };
|
||||
|
||||
if (Input::get_keyboard_key(Key::Escape))
|
||||
{
|
||||
Application::quit();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorLayer::on_render()
|
||||
{
|
||||
m_scene->on_render(m_framebuffer);
|
||||
}
|
||||
|
||||
void EditorLayer::on_user_interface_update()
|
||||
{
|
||||
UserInterface::dockspace_begin();
|
||||
ImGui::ShowDemoWindow();
|
||||
|
||||
if (ImGui::Begin("Game"))
|
||||
{
|
||||
Input::receive_game_events(ImGui::IsWindowFocused());
|
||||
auto available_region = ImGui::GetContentRegionAvail();
|
||||
|
||||
if (m_available_content_region_prev.x != available_region.x
|
||||
|| m_available_content_region_prev.y != available_region.y)
|
||||
{
|
||||
m_framebuffer->resize(
|
||||
math::uvec2 {
|
||||
static_cast<uint32_t>(available_region.x),
|
||||
static_cast<uint32_t>(available_region.y),
|
||||
}
|
||||
);
|
||||
auto &camera = m_camera_entity.get_component<CameraComponent>().camera;
|
||||
camera.set_viewport_size(
|
||||
static_cast<uint32_t>(available_region.x),
|
||||
static_cast<uint32_t>(available_region.y)
|
||||
);
|
||||
|
||||
m_available_content_region_prev = available_region;
|
||||
}
|
||||
|
||||
if (GraphicsContext::get_graphics_api() == GraphicsAPI::DirectX)
|
||||
{
|
||||
ImGui::Image(m_framebuffer->get_color_attachment(), available_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Image(
|
||||
m_framebuffer->get_color_attachment(),
|
||||
available_region,
|
||||
ImVec2(0, 1),
|
||||
ImVec2(1, 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
// Panels
|
||||
m_sceneHierarchyPanel->on_user_interface_update();
|
||||
m_properties_panel->on_user_interface_update();
|
||||
m_content_browser_panel->on_user_interface_update();
|
||||
|
||||
UserInterface::dockspace_end();
|
||||
}
|
||||
|
||||
} // namespace lt
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory/reference.hpp>
|
||||
#include <mirror/panels/panel.hpp>
|
||||
#include <renderer/texture.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
class Scene;
|
||||
|
||||
class AssetBrowserPanel: public Panel
|
||||
{
|
||||
public:
|
||||
AssetBrowserPanel(memory::Ref<Scene> active_scene);
|
||||
|
||||
void on_user_interface_update();
|
||||
|
||||
private:
|
||||
enum class AssetType
|
||||
{
|
||||
none = 0,
|
||||
scene,
|
||||
directory,
|
||||
text,
|
||||
image,
|
||||
};
|
||||
|
||||
std::filesystem::path m_current_directory;
|
||||
|
||||
const std::filesystem::path m_assets_path;
|
||||
|
||||
float m_file_size = 128.0f;
|
||||
|
||||
float m_file_padding = 8.0f;
|
||||
|
||||
memory::Ref<Scene> m_active_scene;
|
||||
|
||||
memory::Ref<Texture> m_directory_texture;
|
||||
|
||||
memory::Ref<Texture> m_scene_texture;
|
||||
|
||||
memory::Ref<Texture> m_image_texture;
|
||||
|
||||
memory::Ref<Texture> m_text_texture;
|
||||
};
|
||||
|
||||
} // namespace lt
|
||||
#include <asset_manager/asset_manager.hpp>
|
||||
#include <ecs/registry.hpp>
|
||||
#include <ecs/serializer.hpp>
|
||||
#include <imgui.h>
|
||||
#include <memory/reference.hpp>
|
||||
#include <mirror/panels/asset_browser.hpp>
|
||||
#include <renderer/texture.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
AssetBrowserPanel::AssetBrowserPanel(memory::Ref<Scene> active_scene)
|
||||
: m_current_directory("./data/assets")
|
||||
, m_assets_path("./data/assets")
|
||||
, m_active_scene(std::move(active_scene))
|
||||
{
|
||||
AssetManager::load_texture("_Assets_Directory", "data/engine/icons/asset/dir.asset");
|
||||
AssetManager::load_texture("_Assets_Scene", "data/engine/icons/asset/scene.asset");
|
||||
AssetManager::load_texture("_Assets_Image", "data/engine/icons/asset/img.asset");
|
||||
AssetManager::load_texture("_Assets_Text", "data/engine/icons/asset/txt.asset");
|
||||
|
||||
m_directory_texture = AssetManager::get_texture("_Assets_Directory");
|
||||
m_scene_texture = AssetManager::get_texture("_Assets_Scene");
|
||||
m_image_texture = AssetManager::get_texture("_Assets_Image");
|
||||
m_text_texture = AssetManager::get_texture("_Assets_Text");
|
||||
}
|
||||
|
||||
void AssetBrowserPanel::on_user_interface_update()
|
||||
{
|
||||
ImGui::Begin("Content Browser");
|
||||
|
||||
// Parent directory button
|
||||
if (m_current_directory != std::filesystem::path("data/assets"))
|
||||
{
|
||||
if (ImGui::Button(" <-- "))
|
||||
{
|
||||
m_current_directory = m_current_directory.parent_path();
|
||||
}
|
||||
}
|
||||
|
||||
const auto available_region = ImGui::GetContentRegionAvail();
|
||||
const auto cell_size = m_file_size + m_file_padding;
|
||||
const auto column_count = std::clamp(
|
||||
static_cast<uint32_t>(std::floor(available_region.x / cell_size)),
|
||||
1u,
|
||||
64u
|
||||
);
|
||||
|
||||
if (ImGui::BeginTable("ContentBrowser", static_cast<int>(column_count)))
|
||||
{
|
||||
m_directory_texture->bind(0u);
|
||||
for (const auto &directory_entry : std::filesystem::directory_iterator(m_current_directory))
|
||||
{
|
||||
const auto &path = directory_entry.path();
|
||||
auto extension = directory_entry.path().extension().string();
|
||||
|
||||
auto asset_type = AssetType {};
|
||||
|
||||
if (extension.empty())
|
||||
{
|
||||
asset_type = AssetType::directory;
|
||||
}
|
||||
else if (extension == ".txt" || extension == ".glsl")
|
||||
{
|
||||
asset_type = AssetType::text;
|
||||
}
|
||||
else if (extension == ".png")
|
||||
{
|
||||
asset_type = AssetType::image;
|
||||
}
|
||||
else if (extension == ".scene")
|
||||
{
|
||||
asset_type = AssetType::scene;
|
||||
}
|
||||
else
|
||||
{
|
||||
asset_type = AssetType::none;
|
||||
}
|
||||
|
||||
// Extension not supported
|
||||
if (asset_type == AssetType::none)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Button
|
||||
const auto path_str = path.string();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushID(path_str.c_str());
|
||||
switch (asset_type)
|
||||
{
|
||||
// Directory
|
||||
case AssetType::directory:
|
||||
if (ImGui::ImageButton(
|
||||
path_str.c_str(),
|
||||
m_directory_texture->get_texture(),
|
||||
ImVec2(m_file_size, m_file_size)
|
||||
))
|
||||
{
|
||||
m_current_directory /= path.filename();
|
||||
}
|
||||
break;
|
||||
|
||||
// Scene
|
||||
case AssetType::scene:
|
||||
if (ImGui::ImageButton(
|
||||
path_str.c_str(),
|
||||
m_scene_texture->get_texture(),
|
||||
ImVec2(m_file_size, m_file_size)
|
||||
))
|
||||
{
|
||||
auto serializer = SceneSerializer { m_active_scene };
|
||||
log::info("Attempting to deserialize: {}", path.string());
|
||||
serializer.deserialize(path.string());
|
||||
}
|
||||
break;
|
||||
|
||||
// Image
|
||||
case AssetType::image:
|
||||
if (ImGui::ImageButton(
|
||||
path_str.c_str(),
|
||||
m_image_texture->get_texture(),
|
||||
ImVec2(m_file_size, m_file_size)
|
||||
))
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
// Text
|
||||
case AssetType::text:
|
||||
if (ImGui::ImageButton(
|
||||
path_str.c_str(),
|
||||
m_text_texture->get_texture(),
|
||||
ImVec2(m_file_size, m_file_size)
|
||||
))
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default: break;
|
||||
}
|
||||
// Label
|
||||
ImGui::TextUnformatted(std::format("{}", path.filename().string()).c_str());
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
} // namespace lt
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
namespace lt {
|
||||
|
||||
class Panel
|
||||
{
|
||||
public:
|
||||
Panel() = default;
|
||||
|
||||
virtual ~Panel() = default;
|
||||
};
|
||||
|
||||
} // namespace lt
|
||||
|
|
@ -1,345 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <ecs/entity.hpp>
|
||||
#include <math/vec3.hpp>
|
||||
#include <mirror/panels/panel.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
class PropertiesPanel: public Panel
|
||||
{
|
||||
public:
|
||||
PropertiesPanel() = default;
|
||||
|
||||
void on_user_interface_update();
|
||||
|
||||
void set_entity_context(const Entity &entity);
|
||||
|
||||
private:
|
||||
void draw_vec3_control(
|
||||
const std::string &label,
|
||||
math::vec3 &values,
|
||||
float reset_value = 0.0f,
|
||||
float column_width = 100.0f
|
||||
);
|
||||
|
||||
template<typename ComponentType, typename UIFunction>
|
||||
void draw_component(const std::string &name, Entity entity, UIFunction function);
|
||||
|
||||
Entity m_entity_context;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lt
|
||||
#include <asset_manager/asset_manager.hpp>
|
||||
#include <camera/component.hpp>
|
||||
#include <ecs/components.hpp>
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <math/trig.hpp>
|
||||
#include <mirror/panels/properties.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
void PropertiesPanel::on_user_interface_update()
|
||||
{
|
||||
ImGui::Begin("Properties");
|
||||
|
||||
if (m_entity_context.is_valid())
|
||||
{
|
||||
if (m_entity_context.has_component<TagComponent>())
|
||||
{
|
||||
auto &tagComponent = m_entity_context.get_component<TagComponent>();
|
||||
|
||||
auto buffer = std::array<char, 256> {};
|
||||
memset(buffer.data(), 0, buffer.size());
|
||||
strncpy(buffer.data(), tagComponent.tag.c_str(), buffer.size());
|
||||
|
||||
if (ImGui::InputText("##Tag", buffer.data(), buffer.size()))
|
||||
{
|
||||
tagComponent.tag = buffer.data();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
if (ImGui::Button("Add component"))
|
||||
{
|
||||
ImGui::OpenPopup("Components");
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("Components"))
|
||||
{
|
||||
if (ImGui::Selectable(
|
||||
"SpriteRenderer",
|
||||
false,
|
||||
m_entity_context.has_component<SpriteRendererComponent>() ?
|
||||
ImGuiSelectableFlags_Disabled :
|
||||
ImGuiSelectableFlags {}
|
||||
))
|
||||
{
|
||||
m_entity_context.add_component<SpriteRendererComponent>(
|
||||
lt::AssetManager::get_texture("awesomeface")
|
||||
);
|
||||
}
|
||||
|
||||
if (ImGui::Selectable(
|
||||
"Camera",
|
||||
false,
|
||||
m_entity_context.has_component<CameraComponent>() ?
|
||||
ImGuiSelectableFlags_Disabled :
|
||||
ImGuiSelectableFlags {}
|
||||
))
|
||||
{
|
||||
m_entity_context.add_component<CameraComponent>();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
draw_component<TransformComponent>(
|
||||
"Transform Component",
|
||||
m_entity_context,
|
||||
[&](auto &transformComponent) {
|
||||
draw_vec3_control("Translation", transformComponent.translation);
|
||||
}
|
||||
);
|
||||
|
||||
draw_component<SpriteRendererComponent>(
|
||||
"SpriteRenderer Component",
|
||||
m_entity_context,
|
||||
[&](auto &spriteRendererComponent) {
|
||||
ImGui::ColorEdit4("Color", &spriteRendererComponent.tint[0]);
|
||||
}
|
||||
);
|
||||
|
||||
draw_component<CameraComponent>(
|
||||
"Camera Component",
|
||||
m_entity_context,
|
||||
[&](auto &cameraComponent) {
|
||||
auto &camera = cameraComponent.camera;
|
||||
|
||||
auto projection_type = camera.get_projection_type();
|
||||
auto projection_types_str = std::array<const char *, 2> {
|
||||
"Orthographic",
|
||||
"Perspective",
|
||||
};
|
||||
|
||||
if (ImGui::BeginCombo("ProjectionType", projection_types_str[(int)projection_type]))
|
||||
{
|
||||
for (auto idx = 0; idx < 2; idx++)
|
||||
{
|
||||
const auto is_selected = static_cast<int>(projection_type) == idx;
|
||||
if (ImGui::Selectable(projection_types_str[idx], is_selected))
|
||||
{
|
||||
projection_type = static_cast<SceneCamera::ProjectionType>(idx);
|
||||
camera.set_projection_type(projection_type);
|
||||
}
|
||||
|
||||
if (is_selected)
|
||||
{
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (projection_type == SceneCamera::ProjectionType::Orthographic)
|
||||
{
|
||||
auto ortho_size = float {};
|
||||
auto near_plane = float {};
|
||||
auto far_plane = float {};
|
||||
|
||||
ortho_size = camera.get_orthographic_size();
|
||||
near_plane = camera.get_orthographic_near_plane();
|
||||
far_plane = camera.get_orthographic_far_plane();
|
||||
|
||||
if (ImGui::DragFloat("Orthographic Size", &ortho_size))
|
||||
{
|
||||
camera.set_orthographic_size(ortho_size);
|
||||
}
|
||||
|
||||
if (ImGui::DragFloat("Near Plane", &near_plane))
|
||||
{
|
||||
camera.set_orthographic_near_plane(near_plane);
|
||||
}
|
||||
|
||||
if (ImGui::DragFloat("Far Plane", &far_plane))
|
||||
{
|
||||
camera.set_orthographic_far_plane(far_plane);
|
||||
}
|
||||
}
|
||||
|
||||
else // perspective
|
||||
{
|
||||
auto vertical_fov = float {};
|
||||
auto near_plane = float {};
|
||||
auto far_plane = float {};
|
||||
|
||||
vertical_fov = math::degrees(camera.get_perspective_vertical_fov());
|
||||
near_plane = camera.get_perspective_near_plane();
|
||||
far_plane = camera.get_perspective_far_plane();
|
||||
|
||||
if (ImGui::DragFloat("Vertical FOV", &vertical_fov))
|
||||
{
|
||||
camera.set_perspective_vertical_fov(math::radians(vertical_fov));
|
||||
}
|
||||
|
||||
if (ImGui::DragFloat("Near Plane", &near_plane))
|
||||
{
|
||||
camera.set_perspective_near_plane(near_plane);
|
||||
}
|
||||
|
||||
if (ImGui::DragFloat("Far Plane", &far_plane))
|
||||
{
|
||||
camera.set_perspective_far_plane(far_plane);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void PropertiesPanel::set_entity_context(const Entity &entity)
|
||||
{
|
||||
m_entity_context = entity;
|
||||
}
|
||||
|
||||
void PropertiesPanel::draw_vec3_control(
|
||||
const std::string &label,
|
||||
math::vec3 &values,
|
||||
float reset_value,
|
||||
float column_width
|
||||
)
|
||||
{
|
||||
auto &io = ImGui::GetIO();
|
||||
|
||||
auto *bold_font = io.Fonts->Fonts[0];
|
||||
|
||||
ImGui::Columns(2);
|
||||
ImGui::SetColumnWidth(0, column_width);
|
||||
ImGui::TextUnformatted(label.c_str());
|
||||
ImGui::NextColumn();
|
||||
|
||||
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2 { 0, 0 });
|
||||
|
||||
auto line_height = GImGui->Font->LegacySize + GImGui->Style.FramePadding.y * 2.0f;
|
||||
auto button_size = ImVec2 { line_height + 3.0f, line_height };
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.1f, 0.15f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.9f, 0.2f, 0.2f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.8f, 0.1f, 0.15f, 1.0f));
|
||||
ImGui::PushFont(bold_font);
|
||||
if (ImGui::Button("X", button_size))
|
||||
{
|
||||
values.x = reset_value;
|
||||
}
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::DragFloat("##X", &values.x, 0.1f);
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.7f, 0.2f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.3f, 0.8f, 0.3f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.2f, 0.7f, 0.2f, 1.0f));
|
||||
ImGui::PushFont(bold_font);
|
||||
if (ImGui::Button("Y", button_size))
|
||||
{
|
||||
values.y = reset_value;
|
||||
}
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::DragFloat("##Y", &values.y, 0.1f);
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::SameLine();
|
||||
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.25f, 0.8f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.2f, 0.35f, 0.9f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.1f, 0.25f, 0.8f, 1.0f));
|
||||
ImGui::PushFont(bold_font);
|
||||
if (ImGui::Button("Z", button_size))
|
||||
{
|
||||
values.z = reset_value;
|
||||
}
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::DragFloat("##Z", &values.z, 0.1f);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::Columns(1);
|
||||
}
|
||||
|
||||
|
||||
template<typename ComponentType, typename UIFunction>
|
||||
void PropertiesPanel::draw_component(
|
||||
const std::string &name,
|
||||
Entity entity,
|
||||
UIFunction user_interface_function
|
||||
)
|
||||
{
|
||||
if (!entity.has_component<ComponentType>())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto &component = entity.get_component<ComponentType>();
|
||||
|
||||
auto available_region = ImGui::GetContentRegionAvail();
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
auto flags = ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanAvailWidth
|
||||
| ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_AllowItemOverlap
|
||||
| ImGuiTreeNodeFlags_FramePadding;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 4, 4 });
|
||||
auto lineHeight = GImGui->Font->LegacySize + GImGui->Style.FramePadding.y * 2.0f;
|
||||
ImGui::Separator();
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
if (ImGui::TreeNodeEx((void *)typeid(ComponentType).hash_code(), flags, name.c_str()))
|
||||
{
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::SameLine(available_region.x - lineHeight * .5f);
|
||||
if (ImGui::Button("+", { lineHeight, lineHeight }))
|
||||
{
|
||||
ImGui::OpenPopup("ComponentSettings");
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("ComponentSettings"))
|
||||
{
|
||||
if (ImGui::Selectable("Remove component"))
|
||||
{
|
||||
entity.remove_component<ComponentType>();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
user_interface_function(component);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace lt
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <ecs/entity.hpp>
|
||||
#include <ecs/registry.hpp>
|
||||
#include <memory/reference.hpp>
|
||||
#include <mirror/panels/panel.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
class PropertiesPanel;
|
||||
|
||||
class SceneHierarchyPanel: public Panel
|
||||
{
|
||||
public:
|
||||
SceneHierarchyPanel();
|
||||
|
||||
SceneHierarchyPanel(
|
||||
memory::Ref<Scene> context,
|
||||
memory::Ref<PropertiesPanel> properties_panel = nullptr
|
||||
);
|
||||
|
||||
void on_user_interface_update();
|
||||
|
||||
void set_context(
|
||||
memory::Ref<Scene> context,
|
||||
memory::Ref<PropertiesPanel> properties_panel = nullptr
|
||||
);
|
||||
|
||||
private:
|
||||
void draw_node(Entity entity, const std::string &label);
|
||||
|
||||
memory::Ref<Scene> m_context;
|
||||
|
||||
memory::Ref<PropertiesPanel> m_properties_panel_context;
|
||||
|
||||
Entity m_selection_context;
|
||||
};
|
||||
|
||||
} // namespace lt
|
||||
#include <ecs/components.hpp>
|
||||
#include <imgui.h>
|
||||
#include <memory/reference.hpp>
|
||||
#include <mirror/panels/properties.hpp>
|
||||
#include <mirror/panels/scene_hierarchy.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
SceneHierarchyPanel::SceneHierarchyPanel(): m_context(nullptr), m_properties_panel_context(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SceneHierarchyPanel::SceneHierarchyPanel(
|
||||
memory::Ref<Scene> context,
|
||||
memory::Ref<PropertiesPanel> properties_panel
|
||||
)
|
||||
: m_context(std::move(context))
|
||||
, m_properties_panel_context(std::move(properties_panel))
|
||||
{
|
||||
}
|
||||
|
||||
void SceneHierarchyPanel::on_user_interface_update()
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
ImGui::Begin("Hierarchy");
|
||||
|
||||
for (auto entityID : m_context->m_registry.view<TagComponent>())
|
||||
{
|
||||
auto entity = Entity {
|
||||
static_cast<entt::entity>(entityID),
|
||||
m_context.get(),
|
||||
};
|
||||
|
||||
const auto &tag = entity.get_component<TagComponent>();
|
||||
draw_node(entity, tag);
|
||||
};
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void SceneHierarchyPanel::set_context(
|
||||
memory::Ref<Scene> context,
|
||||
memory::Ref<PropertiesPanel> properties_panel
|
||||
)
|
||||
{
|
||||
if (properties_panel)
|
||||
{
|
||||
m_properties_panel_context = std::move(properties_panel);
|
||||
}
|
||||
|
||||
m_context = std::move(context);
|
||||
}
|
||||
|
||||
void SceneHierarchyPanel::draw_node(Entity entity, const std::string &label)
|
||||
{
|
||||
auto flags = ImGuiTreeNodeFlags {
|
||||
// NOLINTNEXTLINE
|
||||
(m_selection_context == entity ? ImGuiTreeNodeFlags_Selected : ImGuiTreeNodeFlags {})
|
||||
| ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanFullWidth
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
const auto expanded = ImGui::TreeNodeEx(
|
||||
std::bit_cast<void *>(static_cast<uint64_t>(entity)),
|
||||
flags,
|
||||
"%s",
|
||||
label.c_str()
|
||||
);
|
||||
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
m_selection_context = entity;
|
||||
m_properties_panel_context->set_entity_context(entity);
|
||||
}
|
||||
|
||||
if (expanded)
|
||||
{
|
||||
ImGui::TextUnformatted("TEST_OPENED_TREE!");
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace lt
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
export module mirror.system;
|
||||
|
||||
import preliminary;
|
||||
import math.vec3;
|
||||
import camera.components;
|
||||
import surface.requests;
|
||||
|
|
@ -22,7 +24,6 @@ import app;
|
|||
import app.system;
|
||||
import ecs.entity;
|
||||
import ecs.registry;
|
||||
import std;
|
||||
|
||||
namespace lt {
|
||||
|
||||
|
|
@ -33,9 +34,9 @@ void renderer_callback(
|
|||
std::any &user_data
|
||||
)
|
||||
{
|
||||
std::ignore = message_severity;
|
||||
std::ignore = message_type;
|
||||
std::ignore = user_data;
|
||||
ignore = message_severity;
|
||||
ignore = message_type;
|
||||
ignore = user_data;
|
||||
|
||||
log::trace("< Renderer > ==> {}", std::string { data.message });
|
||||
}
|
||||
|
|
@ -45,8 +46,8 @@ class MirrorSystem: public lt::app::ISystem
|
|||
public:
|
||||
MirrorSystem(
|
||||
memory::Ref<ecs::Registry> registry,
|
||||
std::size_t quit_action_key,
|
||||
std::array<std::size_t, 4ul> debug_action_keys
|
||||
size_t quit_action_key,
|
||||
std::array<size_t, 4ul> debug_action_keys
|
||||
)
|
||||
: m_registry(std::move(registry))
|
||||
, m_quit_action_key(quit_action_key)
|
||||
|
|
@ -84,7 +85,7 @@ public:
|
|||
for (auto &[id, camera] :
|
||||
m_registry->view<lt::camera::components::PerspectiveCamera>())
|
||||
{
|
||||
camera.vertical_fov += (static_cast<float>(tick.delta_time.count()) * 40.0f);
|
||||
camera.vertical_fov += (static_cast<f32>(tick.delta_time.count()) * 40.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,9 +129,9 @@ public:
|
|||
private:
|
||||
memory::Ref<ecs::Registry> m_registry;
|
||||
|
||||
std::size_t m_quit_action_key;
|
||||
size_t m_quit_action_key;
|
||||
|
||||
std::array<std::size_t, 4ul> m_debug_action_keys {};
|
||||
std::array<size_t, 4ul> m_debug_action_keys {};
|
||||
|
||||
app::TickResult m_last_tick_result {};
|
||||
};
|
||||
|
|
@ -183,7 +184,7 @@ public:
|
|||
}
|
||||
);
|
||||
|
||||
auto debug_action_keys = std::array<std::size_t, 4ul> {};
|
||||
auto debug_action_keys = std::array<size_t, 4ul> {};
|
||||
debug_action_keys[0] = input.add_action(
|
||||
input::InputAction {
|
||||
.name = "debug_1",
|
||||
|
|
|
|||
22
modules/preliminary/fundumental_types.cppm
Normal file
22
modules/preliminary/fundumental_types.cppm
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export module preliminary.fundumental_types;
|
||||
|
||||
import std;
|
||||
|
||||
export using byte = ::std::byte;
|
||||
|
||||
export using u8 = ::std::uint8_t;
|
||||
export using u16 = ::std::uint16_t;
|
||||
export using u32 = ::std::uint32_t;
|
||||
export using u64 = ::std::uint64_t;
|
||||
|
||||
export using i8 = ::std::int8_t;
|
||||
export using i16 = ::std::int16_t;
|
||||
export using i32 = ::std::int32_t;
|
||||
export using i64 = ::std::int64_t;
|
||||
|
||||
export using f32 = float;
|
||||
export using f64 = double;
|
||||
|
||||
export using size_t = ::std::size_t;
|
||||
|
||||
export using ::std::ignore;
|
||||
4
modules/preliminary/module.cppm
Normal file
4
modules/preliminary/module.cppm
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export module preliminary;
|
||||
export import preliminary.fundumental_types;
|
||||
// std should always be available...
|
||||
export import std;
|
||||
|
|
@ -3,25 +3,22 @@ import renderer.test_utils;
|
|||
|
||||
using enum ::lt::renderer::IDebugger::MessageSeverity;
|
||||
using enum ::lt::renderer::IBuffer::Usage;
|
||||
using ::std::this_thread::sleep_for;
|
||||
|
||||
// TODO(Light): finish these (and many other) tests...
|
||||
Suite raii = "buffer_raii"_suite = [] {
|
||||
Case { "happy path won't throw" } = [] {
|
||||
auto fixture = FixtureDeviceSwapchain {};
|
||||
};
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
sleep_for(std::chrono::milliseconds { 500u });
|
||||
|
||||
Case { "unhappy path throws" } = [] {
|
||||
auto fixture = FixtureDeviceSwapchain {};
|
||||
};
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
|
||||
Case { "tapping" } = [] {
|
||||
auto fixture = FixtureDeviceSwapchain {};
|
||||
};
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
sleep_for(std::chrono::milliseconds { 500u });
|
||||
|
||||
Case { "mapping" } = [] {
|
||||
auto fixture = FixtureDeviceSwapchain {};
|
||||
};
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
sleep_for(std::chrono::milliseconds { 500u });
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,18 +1,9 @@
|
|||
import renderer.frontend;
|
||||
import renderer.test_utils;
|
||||
|
||||
void noop_callback(
|
||||
lt::renderer::IDebugger::MessageSeverity message_severity,
|
||||
lt::renderer::IDebugger::MessageType message_type,
|
||||
const lt::renderer::IDebugger::MessageData &data,
|
||||
std::any &user_data
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
Suite raii = "debugger_raii"_suite = [] {
|
||||
Case { "happy path won't throw" } = [] {
|
||||
std::ignore = lt::renderer::create_debugger(
|
||||
ignore = lt::renderer::create_debugger(
|
||||
lt::renderer::Api::vulkan,
|
||||
lt::renderer::get_instance(lt::renderer::Api::vulkan),
|
||||
lt::renderer::IDebugger::CreateInfo {
|
||||
|
|
@ -25,7 +16,7 @@ Suite raii = "debugger_raii"_suite = [] {
|
|||
|
||||
Case { "unhappy path throws" } = [] {
|
||||
expect_throw([] {
|
||||
std::ignore = lt::renderer::create_debugger(
|
||||
ignore = lt::renderer::create_debugger(
|
||||
lt::renderer::Api::vulkan,
|
||||
lt::renderer::get_instance(lt::renderer::Api::vulkan),
|
||||
lt::renderer::IDebugger::CreateInfo {
|
||||
|
|
@ -37,7 +28,7 @@ Suite raii = "debugger_raii"_suite = [] {
|
|||
});
|
||||
|
||||
expect_throw([] {
|
||||
std::ignore = lt::renderer::create_debugger(
|
||||
ignore = lt::renderer::create_debugger(
|
||||
lt::renderer::Api::vulkan,
|
||||
lt::renderer::get_instance(lt::renderer::Api::vulkan),
|
||||
lt::renderer::IDebugger::CreateInfo {
|
||||
|
|
@ -49,7 +40,7 @@ Suite raii = "debugger_raii"_suite = [] {
|
|||
});
|
||||
|
||||
expect_throw([] {
|
||||
std::ignore = lt::renderer::create_debugger(
|
||||
ignore = lt::renderer::create_debugger(
|
||||
lt::renderer::Api::vulkan,
|
||||
lt::renderer::get_instance(lt::renderer::Api::vulkan),
|
||||
lt::renderer::IDebugger::CreateInfo {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import renderer.test_utils;
|
|||
Suite raii = "device_raii"_suite = [] {
|
||||
Case { "happy path won't throw" } = [] {
|
||||
auto fixture = Fixture_SurfaceGpu {};
|
||||
std::ignore = lt::renderer::create_device(constants::api, fixture.gpu(), fixture.surface());
|
||||
ignore = lt::renderer::create_device(constants::api, fixture.gpu(), fixture.surface());
|
||||
};
|
||||
|
||||
Case { "unhappy path throws" } = [] {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import renderer.test_utils;
|
|||
Suite raii = "pass_raii"_suite = [] {
|
||||
Case { "happy path won't throw" } = [] {
|
||||
auto fixture = FixtureDeviceSwapchain {};
|
||||
std::ignore = lt::renderer::create_pass(
|
||||
ignore = lt::renderer::create_pass(
|
||||
constants::api,
|
||||
fixture.device(),
|
||||
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
|
||||
|
|
@ -20,7 +20,7 @@ Suite raii = "pass_raii"_suite = [] {
|
|||
Case { "unhappy path throws" } = [] {
|
||||
auto fixture = FixtureDeviceSwapchain {};
|
||||
expect_throw([&] {
|
||||
std::ignore = lt::renderer::create_pass(
|
||||
ignore = lt::renderer::create_pass(
|
||||
constants::api,
|
||||
nullptr,
|
||||
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
|
||||
|
|
@ -29,7 +29,7 @@ Suite raii = "pass_raii"_suite = [] {
|
|||
});
|
||||
|
||||
expect_throw([&] {
|
||||
std::ignore = lt::renderer::create_pass(
|
||||
ignore = lt::renderer::create_pass(
|
||||
lt::renderer::Api::none,
|
||||
fixture.device(),
|
||||
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
|
||||
|
|
@ -38,7 +38,7 @@ Suite raii = "pass_raii"_suite = [] {
|
|||
});
|
||||
|
||||
expect_throw([&] {
|
||||
std::ignore = lt::renderer::create_pass(
|
||||
ignore = lt::renderer::create_pass(
|
||||
lt::renderer::Api::direct_x,
|
||||
fixture.device(),
|
||||
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
|
||||
|
|
@ -47,7 +47,7 @@ Suite raii = "pass_raii"_suite = [] {
|
|||
});
|
||||
|
||||
expect_throw([&] {
|
||||
std::ignore = lt::renderer::create_pass(
|
||||
ignore = lt::renderer::create_pass(
|
||||
lt::renderer::Api::metal,
|
||||
fixture.device(),
|
||||
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Suite raii = "surface"_suite = [] {
|
|||
auto system = lt::surface::System(registry);
|
||||
|
||||
expect_throw([&] {
|
||||
std::ignore = lt::renderer::create_surface(
|
||||
ignore = lt::renderer::create_surface(
|
||||
constants::api,
|
||||
lt::renderer::get_instance(constants::api),
|
||||
entity
|
||||
|
|
@ -38,11 +38,11 @@ Suite raii = "surface"_suite = [] {
|
|||
);
|
||||
|
||||
expect_throw([&] {
|
||||
std::ignore = lt::renderer::create_surface(constants::api, nullptr, entity);
|
||||
ignore = lt::renderer::create_surface(constants::api, nullptr, entity);
|
||||
});
|
||||
|
||||
expect_throw([&] {
|
||||
std::ignore = lt::renderer::create_surface(
|
||||
ignore = lt::renderer::create_surface(
|
||||
lt::renderer::Api::none,
|
||||
lt::renderer::get_instance(constants::api),
|
||||
entity
|
||||
|
|
@ -50,7 +50,7 @@ Suite raii = "surface"_suite = [] {
|
|||
});
|
||||
|
||||
expect_throw([&] {
|
||||
std::ignore = lt::renderer::create_surface(
|
||||
ignore = lt::renderer::create_surface(
|
||||
lt::renderer::Api::direct_x,
|
||||
lt::renderer::get_instance(constants::api),
|
||||
entity
|
||||
|
|
@ -58,7 +58,7 @@ Suite raii = "surface"_suite = [] {
|
|||
});
|
||||
|
||||
expect_throw([&] {
|
||||
std::ignore = lt::renderer::create_surface(
|
||||
ignore = lt::renderer::create_surface(
|
||||
lt::renderer::Api::metal,
|
||||
lt::renderer::get_instance(constants::api),
|
||||
entity
|
||||
|
|
@ -66,7 +66,7 @@ Suite raii = "surface"_suite = [] {
|
|||
});
|
||||
|
||||
// Ensure base creation info is non-throwing
|
||||
std::ignore = lt::renderer::create_surface(
|
||||
ignore = lt::renderer::create_surface(
|
||||
constants::api,
|
||||
lt::renderer::get_instance(constants::api),
|
||||
entity
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import preliminary;
|
||||
import time;
|
||||
import renderer.frontend;
|
||||
import renderer.test_utils;
|
||||
|
|
@ -17,95 +18,64 @@ struct RendererContext
|
|||
};
|
||||
|
||||
Suite raii = "system_raii"_suite = [] {
|
||||
Case { "sandbox" } = [] {
|
||||
Case { "happy path has no errors" } = [] {
|
||||
auto fixture = Fixture_RendererSystem {};
|
||||
auto &surface_system = fixture.surface_system();
|
||||
auto &renderer_system = fixture.renderer_system();
|
||||
|
||||
auto timer = lt::time::Timer {};
|
||||
lt::log::trace("Ticking for 3 seconds...");
|
||||
|
||||
while (timer.elapsed_time() < std::chrono::seconds { 3 })
|
||||
{
|
||||
surface_system.tick({});
|
||||
renderer_system.tick({});
|
||||
}
|
||||
|
||||
lt::log::trace("Three seconds passed, quitting...");
|
||||
expect_false(fixture.has_any_messages_of(lt::renderer::IDebugger::MessageSeverity::error));
|
||||
expect_false(
|
||||
fixture.has_any_messages_of(lt::renderer::IDebugger::MessageSeverity::warning)
|
||||
);
|
||||
};
|
||||
|
||||
// Case { "happy path won't throw" } = [] {
|
||||
// ignore = Fixture_RendererSystem {};
|
||||
//
|
||||
//
|
||||
// auto timer = lt::time::Timer {};
|
||||
// lt::log::trace("Ticking for 3 seconds...");
|
||||
// while (timer.elapsed_time() < std::chrono::seconds { 3 })
|
||||
// {
|
||||
// system.tick({});
|
||||
// }
|
||||
//
|
||||
// lt::log::trace("Three seconds passed, quitting...");
|
||||
// };
|
||||
//
|
||||
// Case { "happy path has no errors" } = [] {
|
||||
// auto fixture = Fixture_RendererSystem {};
|
||||
// expect_false(fixture.has_any_messages_of(lt::renderer::IDebugger::MessageSeverity::error));
|
||||
// expect_false(
|
||||
// fixture.has_any_messages_of(lt::renderer::IDebugger::MessageSeverity::warning)
|
||||
// );
|
||||
// };
|
||||
//
|
||||
// Case { "unhappy path throws" } = [] {
|
||||
// auto fixture = Fixture_SurfaceSystem {};
|
||||
// auto empty_entity = lt::ecs::Entity { fixture.registry(),
|
||||
// fixture.registry()->create_entity() };
|
||||
// auto info = fixture.renderer_system_create_info();
|
||||
//
|
||||
// expect_throw([=] mutable {
|
||||
// info.registry = nullptr;
|
||||
// ignore = lt::renderer::System { info };
|
||||
// });
|
||||
//
|
||||
// expect_throw([=] mutable {
|
||||
// info.surface_entity = lt::ecs::Entity({}, {});
|
||||
// ignore = lt::renderer::System { info };
|
||||
// });
|
||||
//
|
||||
// expect_throw([=] mutable {
|
||||
// info.config.target_api = lt::renderer::Api::none;
|
||||
// ignore = lt::renderer::System { info };
|
||||
// });
|
||||
//
|
||||
// // unsupported Apis
|
||||
// expect_throw([=] mutable {
|
||||
// info.config.target_api = lt::renderer::Api::direct_x;
|
||||
// ignore = lt::renderer::System { info };
|
||||
// });
|
||||
//
|
||||
// expect_throw([=] mutable {
|
||||
// info.config.target_api = lt::renderer::Api::metal;
|
||||
// ignore = lt::renderer::System { info };
|
||||
// });
|
||||
//
|
||||
// expect_throw([=] mutable {
|
||||
// constexpr auto limit = lt::renderer::System::frames_in_flight_upper_limit;
|
||||
// info.config.max_frames_in_flight = limit + 1u;
|
||||
// ignore = lt::renderer::System { info };
|
||||
// });
|
||||
//
|
||||
// expect_throw([=] mutable {
|
||||
// constexpr auto limit = lt::renderer::System::frames_in_flight_lower_limit;
|
||||
// info.config.max_frames_in_flight = limit - 1u;
|
||||
// ignore = lt::renderer::System { info };
|
||||
// });
|
||||
//
|
||||
// expect_throw([=] mutable {
|
||||
// info.debug_callback_info = lt::renderer::IDebugger::CreateInfo {};
|
||||
// ignore = lt::renderer::System { info };
|
||||
// });
|
||||
//
|
||||
// // Make sure the base info is not at fault for unhappiness.
|
||||
// ignore = lt::renderer::System { info };
|
||||
// };
|
||||
Case { "unhappy path throws" } = [] {
|
||||
auto fixture = Fixture_SurfaceSystem {};
|
||||
auto empty_entity = lt::ecs::Entity { fixture.registry(),
|
||||
fixture.registry()->create_entity() };
|
||||
auto info = fixture.renderer_system_create_info();
|
||||
|
||||
expect_throw([=] mutable {
|
||||
info.registry = nullptr;
|
||||
ignore = lt::renderer::System { info };
|
||||
});
|
||||
|
||||
expect_throw([=] mutable {
|
||||
info.surface_entity = lt::ecs::Entity({}, {});
|
||||
ignore = lt::renderer::System { info };
|
||||
});
|
||||
|
||||
expect_throw([=] mutable {
|
||||
info.config.target_api = lt::renderer::Api::none;
|
||||
ignore = lt::renderer::System { info };
|
||||
});
|
||||
|
||||
// unsupported Apis
|
||||
expect_throw([=] mutable {
|
||||
info.config.target_api = lt::renderer::Api::direct_x;
|
||||
ignore = lt::renderer::System { info };
|
||||
});
|
||||
|
||||
expect_throw([=] mutable {
|
||||
info.config.target_api = lt::renderer::Api::metal;
|
||||
ignore = lt::renderer::System { info };
|
||||
});
|
||||
|
||||
expect_throw([=] mutable {
|
||||
constexpr auto limit = lt::renderer::System::frames_in_flight_upper_limit;
|
||||
info.config.max_frames_in_flight = limit + 1u;
|
||||
ignore = lt::renderer::System { info };
|
||||
});
|
||||
|
||||
expect_throw([=] mutable {
|
||||
constexpr auto limit = lt::renderer::System::frames_in_flight_lower_limit;
|
||||
info.config.max_frames_in_flight = limit - 1u;
|
||||
ignore = lt::renderer::System { info };
|
||||
});
|
||||
|
||||
expect_throw([=] mutable {
|
||||
info.debug_callback_info = lt::renderer::IDebugger::CreateInfo {};
|
||||
ignore = lt::renderer::System { info };
|
||||
});
|
||||
|
||||
// Make sure the base info is not at fault for unhappiness.
|
||||
ignore = lt::renderer::System { info };
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export module renderer.test_utils;
|
||||
|
||||
export import preliminary;
|
||||
export import logger;
|
||||
export import surface.system;
|
||||
export import ecs.registry;
|
||||
|
|
@ -13,7 +14,6 @@ export import math.vec2;
|
|||
export import math.vec3;
|
||||
export import math.vec4;
|
||||
export import math.mat4;
|
||||
export import std;
|
||||
|
||||
export using ::lt::test::Case;
|
||||
export using ::lt::test::expect_eq;
|
||||
|
|
@ -23,18 +23,17 @@ export using ::lt::test::expect_throw;
|
|||
export using ::lt::test::operator""_suite;
|
||||
export using ::lt::test::expect_true;
|
||||
export using ::lt::test::Suite;
|
||||
export using ::std::ignore;
|
||||
|
||||
export namespace constants {
|
||||
|
||||
constexpr auto api = lt::renderer::Api::vulkan;
|
||||
constexpr auto resolution = lt::math::uvec2 { 800u, 600u };
|
||||
constexpr auto frames_in_flight = std::uint32_t { 3u };
|
||||
constexpr auto frames_in_flight = u32 { 3u };
|
||||
|
||||
} // namespace constants
|
||||
|
||||
|
||||
void noop_messenger_callback(
|
||||
export void noop_callback(
|
||||
lt::renderer::IDebugger::MessageSeverity,
|
||||
lt::renderer::IDebugger::MessageType,
|
||||
const lt::renderer::IDebugger::MessageData &,
|
||||
|
|
@ -69,7 +68,7 @@ public:
|
|||
.debug_callback_info = {
|
||||
.severities = lt::renderer::IDebugger::MessageSeverity::all,
|
||||
.types= lt::renderer::IDebugger::MessageType::all,
|
||||
.callback = noop_messenger_callback,
|
||||
.callback = noop_callback,
|
||||
.user_data = {},
|
||||
}
|
||||
} ;
|
||||
|
|
@ -157,7 +156,7 @@ public:
|
|||
}
|
||||
|
||||
[[nodiscard]] auto has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity severity) const
|
||||
-> std::uint32_t
|
||||
-> u32
|
||||
{
|
||||
return m_user_data->m_severity_counter.contains(severity);
|
||||
}
|
||||
|
|
@ -173,8 +172,8 @@ private:
|
|||
// I know this makes the tests too verbose...
|
||||
// but makes it easier to figure out what the problem is when things fail on ci
|
||||
lt::log::trace("vulkan: {}", std::string { data.message });
|
||||
std::ignore = data;
|
||||
std::ignore = type;
|
||||
ignore = data;
|
||||
ignore = type;
|
||||
|
||||
auto *fixture = std::any_cast<UserData *>(user_data);
|
||||
fixture->m_has_any_messages = true;
|
||||
|
|
@ -183,8 +182,7 @@ private:
|
|||
|
||||
struct UserData
|
||||
{
|
||||
std::unordered_map<lt::renderer::IDebugger::MessageSeverity, std::uint32_t>
|
||||
m_severity_counter;
|
||||
std::unordered_map<lt::renderer::IDebugger::MessageSeverity, u32> m_severity_counter;
|
||||
|
||||
bool m_has_any_messages {};
|
||||
};
|
||||
|
|
@ -227,7 +225,7 @@ public:
|
|||
}
|
||||
|
||||
[[nodiscard]] auto has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity severity) const
|
||||
-> std::uint32_t
|
||||
-> u32
|
||||
{
|
||||
return m_user_data->m_severity_counter.contains(severity);
|
||||
}
|
||||
|
|
@ -244,8 +242,8 @@ private:
|
|||
// but makes it easier to figure out what the problem is when things fail on ci
|
||||
lt::log::trace("vulkan: {}", std::string { data.message });
|
||||
|
||||
std::ignore = data;
|
||||
std::ignore = type;
|
||||
ignore = data;
|
||||
ignore = type;
|
||||
|
||||
auto *fixture = std::any_cast<UserData *>(user_data);
|
||||
fixture->m_has_any_messages = true;
|
||||
|
|
@ -254,8 +252,7 @@ private:
|
|||
|
||||
struct UserData
|
||||
{
|
||||
std::unordered_map<lt::renderer::IDebugger::MessageSeverity, std::uint32_t>
|
||||
m_severity_counter;
|
||||
std::unordered_map<lt::renderer::IDebugger::MessageSeverity, u32> m_severity_counter;
|
||||
|
||||
bool m_has_any_messages {};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
export module renderer.components;
|
||||
|
||||
import preliminary;
|
||||
import assets.shader;
|
||||
import math.vec3;
|
||||
import memory.reference;
|
||||
import std;
|
||||
|
||||
export namespace lt::renderer::components {
|
||||
|
||||
enum class VertexFormat : std::uint8_t
|
||||
enum class VertexFormat : u8
|
||||
{
|
||||
r32_g32_b32_sfloat,
|
||||
|
||||
r32_g32_sfloat,
|
||||
};
|
||||
|
||||
enum class VertexInputRate : std::uint8_t
|
||||
enum class VertexInputRate : u8
|
||||
{
|
||||
per_vertex,
|
||||
|
||||
|
|
@ -22,20 +23,20 @@ enum class VertexInputRate : std::uint8_t
|
|||
|
||||
struct VertexInputAttributeDescriptipn
|
||||
{
|
||||
std::uint32_t location;
|
||||
u32 location;
|
||||
|
||||
std::uint32_t binding;
|
||||
u32 binding;
|
||||
|
||||
std::uint32_t offset;
|
||||
u32 offset;
|
||||
|
||||
VertexFormat format;
|
||||
};
|
||||
|
||||
struct VertexInputBindingDescription
|
||||
{
|
||||
std::uint32_t binding;
|
||||
u32 binding;
|
||||
|
||||
std::uint32_t stride;
|
||||
u32 stride;
|
||||
};
|
||||
|
||||
/** Requires a math::components::Transform component on the same entity to be functional. */
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@ export module renderer.data;
|
|||
|
||||
import math.mat4;
|
||||
|
||||
export namespace lt::renderer {
|
||||
|
||||
namespace lt::renderer {
|
||||
|
||||
export struct FrameConstants
|
||||
struct FrameConstants
|
||||
{
|
||||
math::mat4 view_projection;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ export import renderer.vk.surface;
|
|||
export import memory.scope;
|
||||
export import debug.assertions;
|
||||
export import ecs.entity;
|
||||
export import std;
|
||||
|
||||
import preliminary;
|
||||
|
||||
export namespace lt::renderer {
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ export namespace lt::renderer {
|
|||
IGpu *gpu,
|
||||
IDevice *device,
|
||||
ISwapchain *swapchain,
|
||||
std::uint32_t max_frames_in_flight
|
||||
u32 max_frames_in_flight
|
||||
) -> memory::Scope<IRenderer>;
|
||||
|
||||
[[nodiscard]] auto create_buffer(
|
||||
|
|
@ -188,7 +189,7 @@ namespace lt::renderer {
|
|||
IGpu *gpu,
|
||||
IDevice *device,
|
||||
ISwapchain *swapchain,
|
||||
std::uint32_t max_frames_in_flight
|
||||
u32 max_frames_in_flight
|
||||
) -> memory::Scope<IRenderer>
|
||||
{
|
||||
debug::ensure(gpu, "Failed to create renderer::IRenderer: null gpu");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export module renderer.frontend;
|
||||
|
||||
import preliminary;
|
||||
import renderer.data;
|
||||
import renderer.components;
|
||||
import bitwise;
|
||||
|
|
@ -7,11 +9,10 @@ import assets.shader;
|
|||
import ecs.entity;
|
||||
import math.vec2;
|
||||
import memory.scope;
|
||||
import std;
|
||||
|
||||
export namespace lt::renderer {
|
||||
|
||||
enum class Api : std::uint8_t
|
||||
enum class Api : u8
|
||||
{
|
||||
none = 0u,
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ public:
|
|||
class IBuffer
|
||||
{
|
||||
public:
|
||||
enum class Usage : std::uint8_t
|
||||
enum class Usage : u8
|
||||
{
|
||||
vertex,
|
||||
|
||||
|
|
@ -80,27 +81,27 @@ public:
|
|||
{
|
||||
Usage usage;
|
||||
|
||||
std::size_t size;
|
||||
size_t size;
|
||||
|
||||
std::string debug_name;
|
||||
};
|
||||
|
||||
struct CopyInfo
|
||||
{
|
||||
std::size_t offset;
|
||||
size_t offset;
|
||||
|
||||
std::size_t size;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
IBuffer() = default;
|
||||
|
||||
virtual ~IBuffer() = default;
|
||||
|
||||
[[nodiscard]] virtual auto map() -> std::span<std::byte> = 0;
|
||||
[[nodiscard]] virtual auto map() -> std::span<byte> = 0;
|
||||
|
||||
virtual void unmap() = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_size() const -> std::size_t = 0;
|
||||
[[nodiscard]] virtual auto get_size() const -> size_t = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
@ -120,7 +121,7 @@ public:
|
|||
|
||||
static constexpr auto frames_in_flight_lower_limit = 1u;
|
||||
|
||||
enum class Result : std::uint8_t
|
||||
enum class Result : u8
|
||||
{
|
||||
success = 0,
|
||||
invalid_swapchain,
|
||||
|
|
@ -131,7 +132,7 @@ public:
|
|||
|
||||
virtual ~IRenderer() = default;
|
||||
|
||||
virtual auto frame(std::uint32_t frame_idx, std::function<void()> submit_scene) -> Result = 0;
|
||||
virtual auto frame(u32 frame_idx, std::function<void()> submit_scene) -> Result = 0;
|
||||
|
||||
virtual void replace_swapchain(class ISwapchain *swapchain) = 0;
|
||||
|
||||
|
|
@ -146,7 +147,7 @@ public:
|
|||
class IDebugger
|
||||
{
|
||||
public:
|
||||
enum class MessageSeverity : std::uint8_t
|
||||
enum class MessageSeverity : u8
|
||||
{
|
||||
none = 0u,
|
||||
|
||||
|
|
@ -158,7 +159,7 @@ public:
|
|||
all = verbose | info | warning | error,
|
||||
};
|
||||
|
||||
enum class MessageType : std::uint8_t
|
||||
enum class MessageType : u8
|
||||
{
|
||||
none = 0u,
|
||||
general = bitwise::bit(0u),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export module renderer.system;
|
||||
|
||||
import preliminary;
|
||||
import logger;
|
||||
import debug.assertions;
|
||||
import math.mat4;
|
||||
|
|
@ -16,9 +18,8 @@ import renderer.components;
|
|||
import math.components;
|
||||
import math.algebra;
|
||||
import math.trig;
|
||||
import std;
|
||||
|
||||
namespace lt::renderer {
|
||||
export namespace lt::renderer {
|
||||
|
||||
/** The main rendering engine.
|
||||
*
|
||||
|
|
@ -27,9 +28,11 @@ namespace lt::renderer {
|
|||
* - Connecting the context to the physical devices (select gpu, create surface, logical device)
|
||||
* - Rendering the scene represented in registry via lt::renderer::components.
|
||||
*/
|
||||
export class System: public app::ISystem
|
||||
class System: public app::ISystem
|
||||
{
|
||||
public:
|
||||
// TODO(Light): this is some horrible design... fix it :(
|
||||
|
||||
/** config.max_frames_in_flight should not be higher than this value. */
|
||||
static constexpr auto frames_in_flight_upper_limit = 5u;
|
||||
|
||||
|
|
@ -40,7 +43,7 @@ public:
|
|||
{
|
||||
Api target_api;
|
||||
|
||||
std::uint32_t max_frames_in_flight;
|
||||
u32 max_frames_in_flight;
|
||||
};
|
||||
|
||||
struct CreateInfo
|
||||
|
|
@ -106,9 +109,9 @@ private:
|
|||
|
||||
app::TickResult m_last_tick_result {};
|
||||
|
||||
std::uint32_t m_frame_idx {};
|
||||
u32 m_frame_idx {};
|
||||
|
||||
std::uint32_t m_max_frames_in_flight {};
|
||||
u32 m_max_frames_in_flight {};
|
||||
};
|
||||
|
||||
} // namespace lt::renderer
|
||||
|
|
@ -162,7 +165,7 @@ void System::on_unregister()
|
|||
|
||||
void System::tick(app::TickInfo tick)
|
||||
{
|
||||
std::ignore = tick;
|
||||
ignore = tick;
|
||||
|
||||
handle_surface_resized_events();
|
||||
auto frame_result = m_renderer->frame(m_frame_idx, [this] { submit_scene(); });
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@ struct wl_surface;
|
|||
#endif
|
||||
|
||||
export module renderer.vk.api_wrapper;
|
||||
import preliminary;
|
||||
import memory.null_on_move;
|
||||
import math.vec3;
|
||||
import math.vec2;
|
||||
import debug.assertions;
|
||||
import std;
|
||||
import logger;
|
||||
|
||||
template<class... Ts>
|
||||
|
|
@ -490,57 +490,57 @@ enum class Format : std::underlying_type_t<VkFormat>
|
|||
r16_sscaled = VK_FORMAT_R16_SSCALED,
|
||||
r16_uint = VK_FORMAT_R16_UINT,
|
||||
r16_sint = VK_FORMAT_R16_SINT,
|
||||
r16_sfloat = VK_FORMAT_R16_SFLOAT,
|
||||
r16_sf32 = VK_FORMAT_R16_SFLOAT,
|
||||
r16g16_unorm = VK_FORMAT_R16G16_UNORM,
|
||||
r16g16_snorm = VK_FORMAT_R16G16_SNORM,
|
||||
r16g16_uscaled = VK_FORMAT_R16G16_USCALED,
|
||||
r16g16_sscaled = VK_FORMAT_R16G16_SSCALED,
|
||||
r16g16_uint = VK_FORMAT_R16G16_UINT,
|
||||
r16g16_sint = VK_FORMAT_R16G16_SINT,
|
||||
r16g16_sfloat = VK_FORMAT_R16G16_SFLOAT,
|
||||
r16g16_sf32 = VK_FORMAT_R16G16_SFLOAT,
|
||||
r16g16b16_unorm = VK_FORMAT_R16G16B16_UNORM,
|
||||
r16g16b16_snorm = VK_FORMAT_R16G16B16_SNORM,
|
||||
r16g16b16_uscaled = VK_FORMAT_R16G16B16_USCALED,
|
||||
r16g16b16_sscaled = VK_FORMAT_R16G16B16_SSCALED,
|
||||
r16g16b16_uint = VK_FORMAT_R16G16B16_UINT,
|
||||
r16g16b16_sint = VK_FORMAT_R16G16B16_SINT,
|
||||
r16g16b16_sfloat = VK_FORMAT_R16G16B16_SFLOAT,
|
||||
r16g16b16_sf32 = VK_FORMAT_R16G16B16_SFLOAT,
|
||||
r16g16b16a16_unorm = VK_FORMAT_R16G16B16A16_UNORM,
|
||||
r16g16b16a16_snorm = VK_FORMAT_R16G16B16A16_SNORM,
|
||||
r16g16b16a16_uscaled = VK_FORMAT_R16G16B16A16_USCALED,
|
||||
r16g16b16a16_sscaled = VK_FORMAT_R16G16B16A16_SSCALED,
|
||||
r16g16b16a16_uint = VK_FORMAT_R16G16B16A16_UINT,
|
||||
r16g16b16a16_sint = VK_FORMAT_R16G16B16A16_SINT,
|
||||
r16g16b16a16_sfloat = VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
r16g16b16a16_sf32 = VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
r32_uint = VK_FORMAT_R32_UINT,
|
||||
r32_sint = VK_FORMAT_R32_SINT,
|
||||
r32_sfloat = VK_FORMAT_R32_SFLOAT,
|
||||
r32_sf32 = VK_FORMAT_R32_SFLOAT,
|
||||
r32g32_uint = VK_FORMAT_R32G32_UINT,
|
||||
r32g32_sint = VK_FORMAT_R32G32_SINT,
|
||||
r32g32_sfloat = VK_FORMAT_R32G32_SFLOAT,
|
||||
r32g32_sf32 = VK_FORMAT_R32G32_SFLOAT,
|
||||
r32g32b32_uint = VK_FORMAT_R32G32B32_UINT,
|
||||
r32g32b32_sint = VK_FORMAT_R32G32B32_SINT,
|
||||
r32g32b32_sfloat = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
r32g32b32_sf32 = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
r32g32b32a32_uint = VK_FORMAT_R32G32B32A32_UINT,
|
||||
r32g32b32a32_sint = VK_FORMAT_R32G32B32A32_SINT,
|
||||
r32g32b32a32_sfloat = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
r32g32b32a32_sf32 = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
r64_uint = VK_FORMAT_R64_UINT,
|
||||
r64_sint = VK_FORMAT_R64_SINT,
|
||||
r64_sfloat = VK_FORMAT_R64_SFLOAT,
|
||||
r64_sf32 = VK_FORMAT_R64_SFLOAT,
|
||||
r64g64_uint = VK_FORMAT_R64G64_UINT,
|
||||
r64g64_sint = VK_FORMAT_R64G64_SINT,
|
||||
r64g64_sfloat = VK_FORMAT_R64G64_SFLOAT,
|
||||
r64g64_sf32 = VK_FORMAT_R64G64_SFLOAT,
|
||||
r64g64b64_uint = VK_FORMAT_R64G64B64_UINT,
|
||||
r64g64b64_sint = VK_FORMAT_R64G64B64_SINT,
|
||||
r64g64b64_sfloat = VK_FORMAT_R64G64B64_SFLOAT,
|
||||
r64g64b64_sf32 = VK_FORMAT_R64G64B64_SFLOAT,
|
||||
r64g64b64a64_uint = VK_FORMAT_R64G64B64A64_UINT,
|
||||
r64g64b64a64_sint = VK_FORMAT_R64G64B64A64_SINT,
|
||||
r64g64b64a64_sfloat = VK_FORMAT_R64G64B64A64_SFLOAT,
|
||||
r64g64b64a64_sf32 = VK_FORMAT_R64G64B64A64_SFLOAT,
|
||||
b10g11r11_ufloat_pack32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32,
|
||||
e5b9g9r9_ufloat_pack32 = VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
|
||||
d16_unorm = VK_FORMAT_D16_UNORM,
|
||||
x8_d24_unorm_pack32 = VK_FORMAT_X8_D24_UNORM_PACK32,
|
||||
d32_sfloat = VK_FORMAT_D32_SFLOAT,
|
||||
d32_sf32 = VK_FORMAT_D32_SFLOAT,
|
||||
s8_uint = VK_FORMAT_S8_UINT,
|
||||
d16_unorm_s8_uint = VK_FORMAT_D16_UNORM_S8_UINT,
|
||||
d24_unorm_s8_uint = VK_FORMAT_D24_UNORM_S8_UINT,
|
||||
|
|
@ -696,9 +696,9 @@ struct Viewport
|
|||
|
||||
math::vec2 extent;
|
||||
|
||||
float min_depth {};
|
||||
f32 min_depth {};
|
||||
|
||||
float max_depth {};
|
||||
f32 max_depth {};
|
||||
};
|
||||
|
||||
struct Rect2d
|
||||
|
|
@ -724,7 +724,7 @@ public:
|
|||
struct Setting
|
||||
{
|
||||
std::string name;
|
||||
std::variant<std::vector<const char *>, std::uint32_t, bool> values;
|
||||
std::variant<std::vector<const char *>, u32, bool> values;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
|
|
@ -806,9 +806,9 @@ public:
|
|||
|
||||
struct Capabilities
|
||||
{
|
||||
std::uint32_t min_image_count;
|
||||
u32 min_image_count;
|
||||
|
||||
std::uint32_t max_image_count;
|
||||
u32 max_image_count;
|
||||
|
||||
math::uvec2 current_extent;
|
||||
|
||||
|
|
@ -816,7 +816,7 @@ public:
|
|||
|
||||
math::uvec2 max_image_extent;
|
||||
|
||||
std::uint32_t max_image_array_layers;
|
||||
u32 max_image_array_layers;
|
||||
|
||||
std::underlying_type_t<Transform> supported_transforms;
|
||||
|
||||
|
|
@ -974,112 +974,112 @@ public:
|
|||
|
||||
struct Limits
|
||||
{
|
||||
std::uint32_t max_image_dimension_1d;
|
||||
std::uint32_t max_image_dimension_2d;
|
||||
std::uint32_t max_image_dimension_3d;
|
||||
std::uint32_t max_image_dimension_cube;
|
||||
std::uint32_t max_image_array_layers;
|
||||
std::uint32_t max_texel_buffer_elements;
|
||||
std::uint32_t max_uniform_buffer_range;
|
||||
std::uint32_t max_storage_buffer_range;
|
||||
std::uint32_t max_push_constants_size;
|
||||
std::uint32_t max_memory_allocation_count;
|
||||
std::uint32_t max_sampler_allocation_count;
|
||||
std::size_t buffer_image_granularity;
|
||||
std::size_t sparse_address_space_size;
|
||||
std::uint32_t max_bound_descriptor_sets;
|
||||
std::uint32_t max_per_stage_descriptor_samplers;
|
||||
std::uint32_t max_per_stage_descriptor_uniform_buffers;
|
||||
std::uint32_t max_per_stage_descriptor_storage_buffers;
|
||||
std::uint32_t max_per_stage_descriptor_sampled_images;
|
||||
std::uint32_t max_per_stage_descriptor_storage_images;
|
||||
std::uint32_t max_per_stage_descriptor_input_attachments;
|
||||
std::uint32_t max_per_stage_resources;
|
||||
std::uint32_t max_descriptor_set_samplers;
|
||||
std::uint32_t max_descriptor_set_uniform_buffers;
|
||||
std::uint32_t max_descriptor_set_uniform_buffers_dynamic;
|
||||
std::uint32_t max_descriptor_set_storage_buffers;
|
||||
std::uint32_t max_descriptor_set_storage_buffers_dynamic;
|
||||
std::uint32_t max_descriptor_set_sampled_images;
|
||||
std::uint32_t max_descriptor_set_storage_images;
|
||||
std::uint32_t max_descriptor_set_input_attachments;
|
||||
std::uint32_t max_vertex_input_attributes;
|
||||
std::uint32_t max_vertex_input_bindings;
|
||||
std::uint32_t max_vertex_input_attribute_offset;
|
||||
std::uint32_t max_vertex_input_binding_stride;
|
||||
std::uint32_t max_vertex_output_components;
|
||||
std::uint32_t max_tessellation_generation_level;
|
||||
std::uint32_t max_tessellation_patch_size;
|
||||
std::uint32_t max_tessellation_control_per_vertex_input_components;
|
||||
std::uint32_t max_tessellation_control_per_vertex_output_components;
|
||||
std::uint32_t max_tessellation_control_per_patch_output_components;
|
||||
std::uint32_t max_tessellation_control_total_output_components;
|
||||
std::uint32_t max_tessellation_evaluation_input_components;
|
||||
std::uint32_t max_tessellation_evaluation_output_components;
|
||||
std::uint32_t max_geometry_shader_invocations;
|
||||
std::uint32_t max_geometry_input_components;
|
||||
std::uint32_t max_geometry_output_components;
|
||||
std::uint32_t max_geometry_output_vertices;
|
||||
std::uint32_t max_geometry_total_output_components;
|
||||
std::uint32_t max_fragment_input_components;
|
||||
std::uint32_t max_fragment_output_attachments;
|
||||
std::uint32_t max_fragment_dual_src_attachments;
|
||||
std::uint32_t max_fragment_combined_output_resources;
|
||||
std::uint32_t max_compute_shared_memory_size;
|
||||
std::array<std::uint32_t, 3> max_compute_work_group_count;
|
||||
std::uint32_t max_compute_work_group_invocations;
|
||||
std::array<std::uint32_t, 3> max_compute_work_group_size;
|
||||
std::uint32_t sub_pixel_precision_bits;
|
||||
std::uint32_t sub_texel_precision_bits;
|
||||
std::uint32_t mipmap_precision_bits;
|
||||
std::uint32_t max_draw_indexed_index_value;
|
||||
std::uint32_t max_draw_indirect_count;
|
||||
float max_sampler_lod_bias;
|
||||
float max_sampler_anisotropy;
|
||||
std::uint32_t max_viewports;
|
||||
std::array<std::uint32_t, 2> max_viewport_dimensions;
|
||||
std::array<float, 2> viewport_bounds_range;
|
||||
std::uint32_t viewport_sub_pixel_bits;
|
||||
std::size_t min_memory_map_alignment;
|
||||
u32 max_image_dimension_1d;
|
||||
u32 max_image_dimension_2d;
|
||||
u32 max_image_dimension_3d;
|
||||
u32 max_image_dimension_cube;
|
||||
u32 max_image_array_layers;
|
||||
u32 max_texel_buffer_elements;
|
||||
u32 max_uniform_buffer_range;
|
||||
u32 max_storage_buffer_range;
|
||||
u32 max_push_constants_size;
|
||||
u32 max_memory_allocation_count;
|
||||
u32 max_sampler_allocation_count;
|
||||
size_t buffer_image_granularity;
|
||||
size_t sparse_address_space_size;
|
||||
u32 max_bound_descriptor_sets;
|
||||
u32 max_per_stage_descriptor_samplers;
|
||||
u32 max_per_stage_descriptor_uniform_buffers;
|
||||
u32 max_per_stage_descriptor_storage_buffers;
|
||||
u32 max_per_stage_descriptor_sampled_images;
|
||||
u32 max_per_stage_descriptor_storage_images;
|
||||
u32 max_per_stage_descriptor_input_attachments;
|
||||
u32 max_per_stage_resources;
|
||||
u32 max_descriptor_set_samplers;
|
||||
u32 max_descriptor_set_uniform_buffers;
|
||||
u32 max_descriptor_set_uniform_buffers_dynamic;
|
||||
u32 max_descriptor_set_storage_buffers;
|
||||
u32 max_descriptor_set_storage_buffers_dynamic;
|
||||
u32 max_descriptor_set_sampled_images;
|
||||
u32 max_descriptor_set_storage_images;
|
||||
u32 max_descriptor_set_input_attachments;
|
||||
u32 max_vertex_input_attributes;
|
||||
u32 max_vertex_input_bindings;
|
||||
u32 max_vertex_input_attribute_offset;
|
||||
u32 max_vertex_input_binding_stride;
|
||||
u32 max_vertex_output_components;
|
||||
u32 max_tessellation_generation_level;
|
||||
u32 max_tessellation_patch_size;
|
||||
u32 max_tessellation_control_per_vertex_input_components;
|
||||
u32 max_tessellation_control_per_vertex_output_components;
|
||||
u32 max_tessellation_control_per_patch_output_components;
|
||||
u32 max_tessellation_control_total_output_components;
|
||||
u32 max_tessellation_evaluation_input_components;
|
||||
u32 max_tessellation_evaluation_output_components;
|
||||
u32 max_geometry_shader_invocations;
|
||||
u32 max_geometry_input_components;
|
||||
u32 max_geometry_output_components;
|
||||
u32 max_geometry_output_vertices;
|
||||
u32 max_geometry_total_output_components;
|
||||
u32 max_fragment_input_components;
|
||||
u32 max_fragment_output_attachments;
|
||||
u32 max_fragment_dual_src_attachments;
|
||||
u32 max_fragment_combined_output_resources;
|
||||
u32 max_compute_shared_memory_size;
|
||||
std::array<u32, 3> max_compute_work_group_count;
|
||||
u32 max_compute_work_group_invocations;
|
||||
std::array<u32, 3> max_compute_work_group_size;
|
||||
u32 sub_pixel_precision_bits;
|
||||
u32 sub_texel_precision_bits;
|
||||
u32 mipmap_precision_bits;
|
||||
u32 max_draw_indexed_index_value;
|
||||
u32 max_draw_indirect_count;
|
||||
f32 max_sampler_lod_bias;
|
||||
f32 max_sampler_anisotropy;
|
||||
u32 max_viewports;
|
||||
std::array<u32, 2> max_viewport_dimensions;
|
||||
std::array<f32, 2> viewport_bounds_range;
|
||||
u32 viewport_sub_pixel_bits;
|
||||
size_t min_memory_map_alignment;
|
||||
VkDeviceSize min_texel_buffer_offset_alignment;
|
||||
VkDeviceSize min_uniform_buffer_offset_alignment;
|
||||
VkDeviceSize min_storage_buffer_offset_alignment;
|
||||
std::int32_t min_texel_offset;
|
||||
std::uint32_t max_texel_offset;
|
||||
std::int32_t min_texel_gather_offset;
|
||||
std::uint32_t max_texel_gather_offset;
|
||||
float min_interpolation_offset;
|
||||
float max_interpolation_offset;
|
||||
std::uint32_t sub_pixel_interpolation_offset_bits;
|
||||
std::uint32_t max_framebuffer_width;
|
||||
std::uint32_t max_framebuffer_height;
|
||||
std::uint32_t max_framebuffer_layers;
|
||||
i32 min_texel_offset;
|
||||
u32 max_texel_offset;
|
||||
i32 min_texel_gather_offset;
|
||||
u32 max_texel_gather_offset;
|
||||
f32 min_interpolation_offset;
|
||||
f32 max_interpolation_offset;
|
||||
u32 sub_pixel_interpolation_offset_bits;
|
||||
u32 max_framebuffer_width;
|
||||
u32 max_framebuffer_height;
|
||||
u32 max_framebuffer_layers;
|
||||
VkSampleCountFlags framebuffer_color_sample_counts;
|
||||
VkSampleCountFlags framebuffer_depth_sample_counts;
|
||||
VkSampleCountFlags framebuffer_stencil_sample_counts;
|
||||
VkSampleCountFlags framebuffer_no_attachments_sample_counts;
|
||||
std::uint32_t max_color_attachments;
|
||||
u32 max_color_attachments;
|
||||
VkSampleCountFlags sampled_image_color_sample_counts;
|
||||
VkSampleCountFlags sampled_image_integer_sample_counts;
|
||||
VkSampleCountFlags sampled_image_depth_sample_counts;
|
||||
VkSampleCountFlags sampled_image_stencil_sample_counts;
|
||||
VkSampleCountFlags storage_image_sample_counts;
|
||||
std::uint32_t max_sample_mask_words;
|
||||
u32 max_sample_mask_words;
|
||||
Bool32 timestamp_compute_and_graphics;
|
||||
float timestamp_period;
|
||||
std::uint32_t max_clip_distances;
|
||||
std::uint32_t max_cull_distances;
|
||||
std::uint32_t max_combined_clip_and_cull_distances;
|
||||
std::uint32_t discrete_queue_priorities;
|
||||
std::array<float, 2> point_size_range;
|
||||
std::array<float, 2> line_width_range;
|
||||
float point_size_granularity;
|
||||
float line_width_granularity;
|
||||
f32 timestamp_period;
|
||||
u32 max_clip_distances;
|
||||
u32 max_cull_distances;
|
||||
u32 max_combined_clip_and_cull_distances;
|
||||
u32 discrete_queue_priorities;
|
||||
std::array<f32, 2> point_size_range;
|
||||
std::array<f32, 2> line_width_range;
|
||||
f32 point_size_granularity;
|
||||
f32 line_width_granularity;
|
||||
Bool32 strict_lines;
|
||||
Bool32 standard_sample_locations;
|
||||
std::size_t optimal_buffer_copy_offset_alignment;
|
||||
std::size_t optimal_buffer_copy_row_pitch_alignment;
|
||||
std::size_t non_coherent_atom_size;
|
||||
size_t optimal_buffer_copy_offset_alignment;
|
||||
size_t optimal_buffer_copy_row_pitch_alignment;
|
||||
size_t non_coherent_atom_size;
|
||||
};
|
||||
|
||||
struct SparseProperties
|
||||
|
|
@ -1093,13 +1093,13 @@ public:
|
|||
|
||||
struct Properties
|
||||
{
|
||||
std::uint32_t api_version;
|
||||
std::uint32_t driver_version;
|
||||
std::uint32_t vendor_id;
|
||||
std::uint32_t device_id;
|
||||
u32 api_version;
|
||||
u32 driver_version;
|
||||
u32 vendor_id;
|
||||
u32 device_id;
|
||||
Type device_type;
|
||||
std::array<char, constants::max_physical_device_name> device_name;
|
||||
std::array<std::uint8_t, constants::uuid_size> pipeline_cache_uuid;
|
||||
std::array<u8, constants::uuid_size> pipeline_cache_uuid;
|
||||
Limits limits;
|
||||
SparseProperties sparse_properties;
|
||||
};
|
||||
|
|
@ -1107,12 +1107,12 @@ public:
|
|||
struct MemoryType
|
||||
{
|
||||
MemoryPropertyFlags::T property_flags;
|
||||
std::uint32_t heap_idx;
|
||||
u32 heap_idx;
|
||||
};
|
||||
|
||||
struct MemoryHeap
|
||||
{
|
||||
std::size_t size;
|
||||
size_t size;
|
||||
MemoryHeapFlags::T flags;
|
||||
};
|
||||
|
||||
|
|
@ -1125,8 +1125,8 @@ public:
|
|||
struct QueueFamilyProperties
|
||||
{
|
||||
QueueFlags::T queue_flags {};
|
||||
std::uint32_t queue_count {};
|
||||
std::uint32_t timestamp_valid_bits {};
|
||||
u32 queue_count {};
|
||||
u32 timestamp_valid_bits {};
|
||||
math::uvec3 min_image_transfer_granularity;
|
||||
};
|
||||
|
||||
|
|
@ -1163,7 +1163,7 @@ public:
|
|||
|
||||
[[nodiscard]] auto queue_family_supports_surface(
|
||||
const Surface &surface,
|
||||
std::uint32_t queue_family_idx
|
||||
u32 queue_family_idx
|
||||
) const -> bool;
|
||||
|
||||
[[nodiscard]] auto get_surface_capabilities(Surface &surface) const -> Surface::Capabilities;
|
||||
|
|
@ -1201,7 +1201,7 @@ public:
|
|||
|
||||
struct CreateInfo
|
||||
{
|
||||
std::set<std::uint32_t> queue_indices;
|
||||
std::set<u32> queue_indices;
|
||||
|
||||
std::vector<std::string> extensions;
|
||||
|
||||
|
|
@ -1258,7 +1258,7 @@ public:
|
|||
void bind_memory(VkBuffer buffer, VkDeviceMemory memory, size_t offset = 0u) const;
|
||||
|
||||
[[nodiscard]] auto map_memory(VkDeviceMemory memory, size_t size, size_t offset) const
|
||||
-> std::span<std::byte>;
|
||||
-> std::span<byte>;
|
||||
|
||||
void unmap_memory(VkDeviceMemory memory);
|
||||
|
||||
|
|
@ -1498,14 +1498,14 @@ public:
|
|||
|
||||
struct MemoryRequirements
|
||||
{
|
||||
std::size_t size;
|
||||
std::size_t alignment;
|
||||
std::uint32_t memory_type_bits;
|
||||
size_t size;
|
||||
size_t alignment;
|
||||
u32 memory_type_bits;
|
||||
};
|
||||
|
||||
struct CreateInfo
|
||||
{
|
||||
std::size_t size;
|
||||
size_t size;
|
||||
|
||||
UsageFlags usage;
|
||||
|
||||
|
|
@ -1640,10 +1640,10 @@ public:
|
|||
struct Range
|
||||
{
|
||||
Image::AspectFlags aspect_flags;
|
||||
std::uint32_t base_mip_level;
|
||||
std::uint32_t level_count;
|
||||
std::uint32_t base_array_layer;
|
||||
std::uint32_t layer_count;
|
||||
u32 base_mip_level;
|
||||
u32 level_count;
|
||||
u32 base_array_layer;
|
||||
u32 layer_count;
|
||||
};
|
||||
|
||||
static constexpr auto full_color_range = Range {
|
||||
|
|
@ -1764,7 +1764,7 @@ public:
|
|||
|
||||
struct CreateInfo
|
||||
{
|
||||
std::vector<std::byte> code;
|
||||
std::vector<byte> code;
|
||||
|
||||
std::string_view name;
|
||||
};
|
||||
|
|
@ -1874,9 +1874,9 @@ public:
|
|||
|
||||
Flags flags;
|
||||
|
||||
std::uint32_t idx;
|
||||
u32 idx;
|
||||
|
||||
std::uint32_t count;
|
||||
u32 count;
|
||||
|
||||
DescriptorSet::Type type;
|
||||
|
||||
|
|
@ -1945,14 +1945,14 @@ public:
|
|||
{
|
||||
DescriptorSet::Type type;
|
||||
|
||||
std::uint32_t count;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct CreateInfo
|
||||
{
|
||||
std::vector<Size> sizes;
|
||||
|
||||
std::uint32_t max_sets;
|
||||
u32 max_sets;
|
||||
|
||||
std::string_view name;
|
||||
};
|
||||
|
|
@ -2009,9 +2009,9 @@ public:
|
|||
|
||||
struct ViewportState
|
||||
{
|
||||
std::uint32_t viewport_count;
|
||||
u32 viewport_count;
|
||||
|
||||
std::uint32_t scissor_count;
|
||||
u32 scissor_count;
|
||||
};
|
||||
|
||||
struct RasterizationState
|
||||
|
|
@ -2028,13 +2028,13 @@ public:
|
|||
|
||||
bool depth_bias_enabled;
|
||||
|
||||
float depth_bias_constant_factor;
|
||||
f32 depth_bias_constant_factor;
|
||||
|
||||
float depth_bias_clamp;
|
||||
f32 depth_bias_clamp;
|
||||
|
||||
float depth_bias_slope_factor;
|
||||
f32 depth_bias_slope_factor;
|
||||
|
||||
float line_width;
|
||||
f32 line_width;
|
||||
};
|
||||
|
||||
struct MultisamplingState
|
||||
|
|
@ -2043,7 +2043,7 @@ public:
|
|||
|
||||
bool sample_shading_enabled;
|
||||
|
||||
float min_sample_shading;
|
||||
f32 min_sample_shading;
|
||||
|
||||
bool alpha_to_coverage_enabled;
|
||||
|
||||
|
|
@ -2134,8 +2134,8 @@ public:
|
|||
struct PushConstantRange
|
||||
{
|
||||
ShaderStageFlags::T shader_stages;
|
||||
std::uint32_t offset;
|
||||
std::uint32_t size;
|
||||
u32 offset;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct CreateInfo
|
||||
|
|
@ -2189,11 +2189,11 @@ public:
|
|||
|
||||
Buffer *dst_buffer;
|
||||
|
||||
std::size_t src_offset;
|
||||
size_t src_offset;
|
||||
|
||||
std::size_t dst_offset;
|
||||
size_t dst_offset;
|
||||
|
||||
std::size_t size;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct PushConstantsInfo
|
||||
|
|
@ -2202,9 +2202,9 @@ public:
|
|||
|
||||
vk::ShaderStageFlags::T shader_stages;
|
||||
|
||||
std::uint32_t offset;
|
||||
u32 offset;
|
||||
|
||||
std::uint32_t size;
|
||||
u32 size;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
|
@ -2298,11 +2298,11 @@ public:
|
|||
|
||||
StoreOperation store_operation;
|
||||
|
||||
std::array<float, 4> color_clear_values;
|
||||
std::array<f32, 4> color_clear_values;
|
||||
|
||||
float depth_clear_value;
|
||||
f32 depth_clear_value;
|
||||
|
||||
std::uint32_t stencil_clear_value;
|
||||
u32 stencil_clear_value;
|
||||
|
||||
Flags resolve_mode_flags;
|
||||
};
|
||||
|
|
@ -2316,13 +2316,13 @@ public:
|
|||
|
||||
struct DrawInfo
|
||||
{
|
||||
std::uint32_t vertex_count;
|
||||
u32 vertex_count;
|
||||
|
||||
std::uint32_t instance_count;
|
||||
u32 instance_count;
|
||||
|
||||
std::uint32_t first_vertex;
|
||||
u32 first_vertex;
|
||||
|
||||
std::uint32_t first_instance;
|
||||
u32 first_instance;
|
||||
};
|
||||
|
||||
CommandBuffer() = default;
|
||||
|
|
@ -2462,7 +2462,7 @@ public:
|
|||
|
||||
math::uvec2 extent;
|
||||
|
||||
std::uint32_t min_image_count;
|
||||
u32 min_image_count;
|
||||
|
||||
std::vector<uint32_t> queue_family_indices;
|
||||
|
||||
|
|
@ -2491,8 +2491,7 @@ public:
|
|||
|
||||
[[nodiscard]] auto get_images() -> std::vector<Image>;
|
||||
|
||||
[[nodiscard]] auto acquire_image(Semaphore &semaphore, std::uint64_t timeout = 100'000'000)
|
||||
-> std::uint32_t;
|
||||
[[nodiscard]] auto acquire_image(Semaphore &semaphore, u64 timeout = 100'000'000) -> u32;
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto get_vk_handle() -> VkSwapchainKHR
|
||||
|
|
@ -2590,9 +2589,9 @@ public:
|
|||
|
||||
struct AllocateInfo
|
||||
{
|
||||
std::size_t size;
|
||||
size_t size;
|
||||
|
||||
std::uint32_t memory_type_idx;
|
||||
u32 memory_type_idx;
|
||||
|
||||
std::string_view name;
|
||||
};
|
||||
|
|
@ -2609,7 +2608,7 @@ public:
|
|||
|
||||
auto operator=(const Memory &) -> Memory & = delete;
|
||||
|
||||
[[nodiscard]] auto map(std::size_t size, std::size_t offset) -> std::span<std::byte>;
|
||||
[[nodiscard]] auto map(size_t size, size_t offset) -> std::span<byte>;
|
||||
|
||||
void unmap();
|
||||
|
||||
|
|
@ -2755,11 +2754,9 @@ constexpr auto to_string(VkResult result) noexcept -> std::string_view
|
|||
case VK_PIPELINE_BINARY_MISSING_KHR: return "VK_PIPELINE_BINARY_MISSING_KHR";
|
||||
case VK_ERROR_NOT_ENOUGH_SPACE_KHR: return "VK_ERROR_NOT_ENOUGH_SPACE_KHR";
|
||||
case VK_RESULT_MAX_ENUM: return "VK_RESULT_MAX_ENUM";
|
||||
default: return"<unknown>";
|
||||
default: return "<unknown>";
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
void vkc(VkResult result)
|
||||
|
|
@ -3114,13 +3111,13 @@ Instance::Instance(CreateInfo info)
|
|||
{
|
||||
const auto layer_setting_type_visitor = overloads {
|
||||
[](const std::vector<const char *> &) { return VK_LAYER_SETTING_TYPE_STRING_EXT; },
|
||||
[](std::uint32_t) { return VK_LAYER_SETTING_TYPE_UINT32_EXT; },
|
||||
[](u32) { return VK_LAYER_SETTING_TYPE_UINT32_EXT; },
|
||||
[](bool) { return VK_LAYER_SETTING_TYPE_BOOL32_EXT; },
|
||||
};
|
||||
|
||||
const auto layer_setting_value_visitor = overloads {
|
||||
[](std::vector<const char *> values) { return std::bit_cast<void *>(values.data()); },
|
||||
[](std::uint32_t value) { return std::bit_cast<void *>(&value); },
|
||||
[](u32 value) { return std::bit_cast<void *>(&value); },
|
||||
[](bool value) { return std::bit_cast<void *>(&value); },
|
||||
};
|
||||
|
||||
|
|
@ -3403,7 +3400,7 @@ Surface::~Surface()
|
|||
|
||||
std::memcpy(
|
||||
properties.pipeline_cache_uuid.data(),
|
||||
static_cast<std::uint8_t *>(vk_properties.pipelineCacheUUID),
|
||||
static_cast<u8 *>(vk_properties.pipelineCacheUUID),
|
||||
constants::uuid_size
|
||||
);
|
||||
|
||||
|
|
@ -3559,7 +3556,7 @@ Surface::~Surface()
|
|||
|
||||
[[nodiscard]] auto Gpu::get_queue_family_properties() const -> std::vector<QueueFamilyProperties>
|
||||
{
|
||||
auto count = std::uint32_t {};
|
||||
auto count = u32 {};
|
||||
|
||||
api::get_physical_device_queue_family_properties(m_physical_device, &count, {});
|
||||
|
||||
|
|
@ -3591,7 +3588,7 @@ Surface::~Surface()
|
|||
|
||||
[[nodiscard]] auto Gpu::queue_family_supports_surface(
|
||||
const Surface &surface,
|
||||
std::uint32_t queue_family_idx
|
||||
u32 queue_family_idx
|
||||
) const -> bool
|
||||
{
|
||||
auto supported = VkBool32 { false };
|
||||
|
|
@ -3949,11 +3946,11 @@ void Device::bind_memory(VkBuffer buffer, VkDeviceMemory memory, size_t offset /
|
|||
}
|
||||
|
||||
[[nodiscard]] auto Device::map_memory(VkDeviceMemory memory, size_t size, size_t offset) const
|
||||
-> std::span<std::byte>
|
||||
-> std::span<byte>
|
||||
{
|
||||
void *data = {};
|
||||
vkc(api::map_memory(m_device, memory, offset, size, {}, &data));
|
||||
return { std::bit_cast<std::byte *>(data), size };
|
||||
return { std::bit_cast<byte *>(data), size };
|
||||
}
|
||||
|
||||
void Device::unmap_memory(VkDeviceMemory memory)
|
||||
|
|
@ -4276,7 +4273,7 @@ Image::Image(Device &device, CreateInfo info): m_device(device.get_vk_handle()),
|
|||
{
|
||||
// WIP(Light): use image create info's info
|
||||
|
||||
std::ignore = info;
|
||||
ignore = info;
|
||||
auto vk_info = VkImageCreateInfo {};
|
||||
vkc(api::create_image(m_device, &vk_info, nullptr, &m_image));
|
||||
}
|
||||
|
|
@ -4341,7 +4338,7 @@ CommandBuffer::CommandBuffer(VkCommandBuffer buffer): m_buffer(buffer)
|
|||
void CommandBuffer::begin(BeginInfo info /* = {} */)
|
||||
{
|
||||
// WIP(Light): Use info
|
||||
std::ignore = info;
|
||||
ignore = info;
|
||||
|
||||
auto vk_info = VkCommandBufferBeginInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
|
|
@ -4449,7 +4446,7 @@ void CommandBuffer::begin_rendering(RenderingInfo info)
|
|||
.extent = {info.area_extent.x, info.area_extent.y},
|
||||
},
|
||||
.layerCount = 1u,
|
||||
.colorAttachmentCount = static_cast<std::uint32_t>(vk_color_attachments.size()),
|
||||
.colorAttachmentCount = static_cast<u32>(vk_color_attachments.size()),
|
||||
.pColorAttachments= vk_color_attachments.data(),
|
||||
};
|
||||
|
||||
|
|
@ -4587,7 +4584,7 @@ Swapchain::Swapchain(Device &device, Surface &surface, CreateInfo info)
|
|||
.imageArrayLayers = 1u,
|
||||
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = static_cast<std::uint32_t>(info.queue_family_indices.size()),
|
||||
.queueFamilyIndexCount = static_cast<u32>(info.queue_family_indices.size()),
|
||||
.pQueueFamilyIndices = info.queue_family_indices.data(),
|
||||
.preTransform = static_cast<VkSurfaceTransformFlagBitsKHR>(info.pre_transform),
|
||||
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
||||
|
|
@ -4629,10 +4626,9 @@ Swapchain::~Swapchain()
|
|||
return images;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Swapchain::acquire_image(Semaphore &semaphore, std::uint64_t timeout)
|
||||
-> std::uint32_t
|
||||
[[nodiscard]] auto Swapchain::acquire_image(Semaphore &semaphore, u64 timeout) -> u32
|
||||
{
|
||||
auto idx = std::uint32_t {};
|
||||
auto idx = u32 {};
|
||||
vkc(api::acquire_next_image_khr(
|
||||
m_device,
|
||||
m_swapchain,
|
||||
|
|
@ -4706,11 +4702,11 @@ Memory::~Memory()
|
|||
api::free_memory(m_device, m_memory, nullptr);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Memory::map(std::size_t size, std::size_t offset) -> std::span<std::byte>
|
||||
[[nodiscard]] auto Memory::map(size_t size, size_t offset) -> std::span<byte>
|
||||
{
|
||||
void *data = {};
|
||||
vkc(api::map_memory(m_device, m_memory, offset, size, {}, &data));
|
||||
return { std::bit_cast<std::byte *>(data), size };
|
||||
return { std::bit_cast<byte *>(data), size };
|
||||
}
|
||||
|
||||
void Memory::unmap()
|
||||
|
|
@ -4725,7 +4721,7 @@ ShaderModule::ShaderModule(Device &device, CreateInfo info): m_device(device.get
|
|||
.pNext = {},
|
||||
.flags = {},
|
||||
.codeSize = info.code.size(),
|
||||
.pCode = std::bit_cast<std::uint32_t *>(info.code.data()),
|
||||
.pCode = std::bit_cast<u32 *>(info.code.data()),
|
||||
};
|
||||
vkc(api::create_shader_module(m_device, &vk_info, nullptr, &m_shader_module));
|
||||
|
||||
|
|
@ -4770,7 +4766,7 @@ DescriptorSetLayout::DescriptorSetLayout(Device &device, CreateInfo info)
|
|||
auto vk_binding_flags_info = VkDescriptorSetLayoutBindingFlagsCreateInfoEXT {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||
.pNext = {},
|
||||
.bindingCount = static_cast<std::uint32_t>(vk_binding_flag_values.size()),
|
||||
.bindingCount = static_cast<u32>(vk_binding_flag_values.size()),
|
||||
.pBindingFlags = vk_binding_flag_values.data(),
|
||||
};
|
||||
|
||||
|
|
@ -4778,7 +4774,7 @@ DescriptorSetLayout::DescriptorSetLayout(Device &device, CreateInfo info)
|
|||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.pNext = &vk_binding_flags_info,
|
||||
.flags = info.flags,
|
||||
.bindingCount = static_cast<std::uint32_t>(vk_bindings.size()),
|
||||
.bindingCount = static_cast<u32>(vk_bindings.size()),
|
||||
.pBindings = vk_bindings.data(),
|
||||
};
|
||||
vkc(api::create_descriptor_set_layout(m_device, &vk_info, nullptr, &m_descriptor_set_layout));
|
||||
|
|
@ -4817,7 +4813,7 @@ DescriptorPool::DescriptorPool(Device &device, CreateInfo info): m_device(device
|
|||
.pNext = {},
|
||||
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
|
||||
.maxSets = info.max_sets,
|
||||
.poolSizeCount = static_cast<std::uint32_t>(vk_sizes.size()),
|
||||
.poolSizeCount = static_cast<u32>(vk_sizes.size()),
|
||||
.pPoolSizes = vk_sizes.data(),
|
||||
};
|
||||
|
||||
|
|
@ -4946,7 +4942,7 @@ Pipeline::Pipeline(Device &device, PipelineLayout &layout, CreateInfo info)
|
|||
// WIP(Light): use color attachments
|
||||
for (auto &color_attachment : info.attachment_state.color_attachments)
|
||||
{
|
||||
std::ignore = color_attachment;
|
||||
ignore = color_attachment;
|
||||
}
|
||||
|
||||
auto rendering_info = VkPipelineRenderingCreateInfoKHR {
|
||||
|
|
@ -5025,9 +5021,9 @@ PipelineLayout::PipelineLayout(Device &device, CreateInfo info): m_device(device
|
|||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.pNext = {},
|
||||
.flags = {},
|
||||
.setLayoutCount = static_cast<std::uint32_t>(vk_set_layouts.size()),
|
||||
.setLayoutCount = static_cast<u32>(vk_set_layouts.size()),
|
||||
.pSetLayouts = vk_set_layouts.data(),
|
||||
.pushConstantRangeCount = static_cast<std::uint32_t>(vk_push_constant_ranges.size()),
|
||||
.pushConstantRangeCount = static_cast<u32>(vk_push_constant_ranges.size()),
|
||||
.pPushConstantRanges = vk_push_constant_ranges.data()
|
||||
};
|
||||
vkc(api::create_pipeline_layout(m_device, &vk_info, nullptr, &m_pipeline_layout));
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
export module renderer.vk.buffer;
|
||||
|
||||
import preliminary;
|
||||
import renderer.vk.device;
|
||||
import renderer.vk.gpu;
|
||||
import renderer.vk.api_wrapper;
|
||||
import renderer.frontend;
|
||||
import std;
|
||||
|
||||
namespace lt::renderer::vkb {
|
||||
export namespace lt::renderer::vkb {
|
||||
|
||||
export class Buffer: public IBuffer
|
||||
class Buffer: public IBuffer
|
||||
{
|
||||
public:
|
||||
Buffer(class IDevice *device, class IGpu *gpu, const CreateInfo &info);
|
||||
|
|
@ -16,7 +17,7 @@ public:
|
|||
|
||||
void unmap() override;
|
||||
|
||||
[[nodiscard]] auto get_size() const -> std::size_t override
|
||||
[[nodiscard]] auto get_size() const -> size_t override
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
|
@ -34,12 +35,11 @@ private:
|
|||
[[nodiscard]] auto to_native_memory_properties(Usage usage) const -> vk::Memory::PropertyFlags;
|
||||
|
||||
|
||||
[[nodiscard]] auto has_correct_memory_type_bit(std::uint32_t type_bits, std::uint32_t type_idx)
|
||||
const -> bool;
|
||||
[[nodiscard]] auto has_correct_memory_type_bit(u32 type_bits, u32 type_idx) const -> bool;
|
||||
|
||||
[[nodiscard]] auto has_required_memory_properties(
|
||||
std::uint32_t required_properties,
|
||||
std::uint32_t property_flags
|
||||
u32 required_properties,
|
||||
u32 property_flags
|
||||
) const -> bool;
|
||||
|
||||
Device *m_device {};
|
||||
|
|
@ -51,14 +51,13 @@ private:
|
|||
vk::Memory m_memory;
|
||||
|
||||
// TODO(Light): should this reflect the allocation size instead?
|
||||
std::size_t m_size {};
|
||||
size_t m_size {};
|
||||
};
|
||||
|
||||
} // namespace lt::renderer::vkb
|
||||
|
||||
module :private;
|
||||
using namespace ::lt::renderer;
|
||||
using namespace ::lt::renderer::vkb;
|
||||
namespace lt::renderer::vkb {
|
||||
|
||||
Buffer::Buffer(IDevice *device, IGpu *gpu, const CreateInfo &info)
|
||||
: m_device(static_cast<Device *>(device))
|
||||
|
|
@ -145,18 +144,17 @@ void Buffer::unmap() /* override */
|
|||
std::unreachable();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Buffer::has_correct_memory_type_bit(
|
||||
std::uint32_t type_bits,
|
||||
std::uint32_t type_idx
|
||||
) const -> bool
|
||||
[[nodiscard]] auto Buffer::has_correct_memory_type_bit(u32 type_bits, u32 type_idx) const -> bool
|
||||
{
|
||||
return type_bits & (1 << type_idx);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Buffer::has_required_memory_properties(
|
||||
std::uint32_t required_properties,
|
||||
std::uint32_t property_flags
|
||||
u32 required_properties,
|
||||
u32 property_flags
|
||||
) const -> bool
|
||||
{
|
||||
return (property_flags & required_properties) == required_properties;
|
||||
}
|
||||
|
||||
} // namespace lt::renderer::vkb
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
export module renderer.vk.debugger;
|
||||
|
||||
import preliminary;
|
||||
import renderer.vk.instance;
|
||||
import renderer.frontend;
|
||||
import renderer.vk.api_wrapper;
|
||||
import memory.null_on_move;
|
||||
import debug.assertions;
|
||||
import logger;
|
||||
import std;
|
||||
|
||||
namespace lt::renderer::vkb {
|
||||
export namespace lt::renderer::vkb {
|
||||
|
||||
export class Debugger: public IDebugger
|
||||
class Debugger: public IDebugger
|
||||
{
|
||||
public:
|
||||
Debugger(IInstance *instance, CreateInfo info);
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
namespace lt::renderer::vk {
|
||||
|
||||
class Descriptors
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace lt::renderer::vk
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
export module renderer.vk.device;
|
||||
|
||||
import preliminary;
|
||||
import memory.null_on_move;
|
||||
import logger;
|
||||
import debug.assertions;
|
||||
|
|
@ -7,11 +9,10 @@ import renderer.frontend;
|
|||
import renderer.vk.api_wrapper;
|
||||
import renderer.vk.gpu;
|
||||
import renderer.vk.surface;
|
||||
import std;
|
||||
|
||||
namespace lt::renderer::vkb {
|
||||
export namespace lt::renderer::vkb {
|
||||
|
||||
export class Device: public IDevice
|
||||
class Device: public IDevice
|
||||
{
|
||||
public:
|
||||
Device(IGpu *gpu, ISurface *surface);
|
||||
|
|
@ -21,7 +22,7 @@ public:
|
|||
return m_device;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_family_indices() const -> std::vector<std::uint32_t>
|
||||
[[nodiscard]] auto get_family_indices() const -> std::vector<u32>
|
||||
{
|
||||
return { m_graphics_queue_family_index, m_present_queue_family_index };
|
||||
}
|
||||
|
|
@ -43,7 +44,7 @@ private:
|
|||
|
||||
void initialize_queue_indices();
|
||||
|
||||
[[nodiscard]] auto find_suitable_queue_family() const -> std::uint32_t;
|
||||
[[nodiscard]] auto find_suitable_queue_family() const -> u32;
|
||||
|
||||
vkb::Gpu *m_gpu {};
|
||||
|
||||
|
|
@ -55,9 +56,9 @@ private:
|
|||
|
||||
vk::Queue m_present_queue {};
|
||||
|
||||
std::uint32_t m_graphics_queue_family_index = vk::constants::queue_family_ignored;
|
||||
u32 m_graphics_queue_family_index = vk::constants::queue_family_ignored;
|
||||
|
||||
std::uint32_t m_present_queue_family_index = vk::constants::queue_family_ignored;
|
||||
u32 m_present_queue_family_index = vk::constants::queue_family_ignored;
|
||||
};
|
||||
|
||||
} // namespace lt::renderer::vkb
|
||||
|
|
@ -124,7 +125,7 @@ void Device::initialize_logical_device()
|
|||
void Device::initialize_queue_indices()
|
||||
{
|
||||
auto properties = m_gpu->vk().get_queue_family_properties();
|
||||
for (auto idx = std::uint32_t { 0u }; const auto &property : properties)
|
||||
for (auto idx = u32 { 0u }; const auto &property : properties)
|
||||
{
|
||||
if (property.queue_flags & vk::QueueFlags::graphics_bit)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,52 +1,20 @@
|
|||
export module renderer.vk.gpu;
|
||||
|
||||
import preliminary;
|
||||
import renderer.vk.api_wrapper;
|
||||
import logger;
|
||||
import debug.assertions;
|
||||
import renderer.frontend;
|
||||
import renderer.vk.instance;
|
||||
import memory.null_on_move;
|
||||
import std;
|
||||
|
||||
namespace lt::renderer::vkb {
|
||||
export namespace lt::renderer::vkb {
|
||||
|
||||
export class Gpu: public IGpu
|
||||
class Gpu: public IGpu
|
||||
{
|
||||
public:
|
||||
Gpu(IInstance *instance);
|
||||
|
||||
// [[nodiscard]] auto queue_family_supports_presentation(
|
||||
// VkSurfaceKHR surface,
|
||||
// uint32_t queue_family_idx
|
||||
// ) -> bool;
|
||||
//
|
||||
// [[nodiscard]] auto get_surface_capabilities(VkSurfaceKHR surface) const
|
||||
// -> VkSurfaceCapabilitiesKHR;
|
||||
//
|
||||
// [[nodiscard]] auto get_surface_formats(VkSurfaceKHR surface) const
|
||||
// -> std::vector<VkSurfaceFormatKHR>;
|
||||
//
|
||||
// [[nodiscard]] auto get_properties() const -> VkPhysicalDeviceProperties
|
||||
// {
|
||||
// return m_properties;
|
||||
// }
|
||||
//
|
||||
// [[nodiscard]] auto get_descriptor_indexing_features() const
|
||||
// -> VkPhysicalDeviceDescriptorIndexingFeatures
|
||||
// {
|
||||
// return m_descriptor_indexing_features;
|
||||
// }
|
||||
//
|
||||
// [[nodiscard]] auto get_memory_properties() const -> VkPhysicalDeviceMemoryProperties
|
||||
// {
|
||||
// return m_memory_properties;
|
||||
// }
|
||||
//
|
||||
// [[nodiscard]] auto get_queue_family_properties() const ->
|
||||
// std::vector<VkQueueFamilyProperties>
|
||||
// {
|
||||
// return m_queue_family_properties;
|
||||
// }
|
||||
|
||||
[[nodiscard]] auto vk() -> vk::Gpu &;
|
||||
|
||||
private:
|
||||
|
|
@ -54,8 +22,6 @@ private:
|
|||
|
||||
vk::Gpu::Properties m_properties {};
|
||||
|
||||
// VkPhysicalDeviceDescriptorIndexingFeatures m_descriptor_indexing_features;
|
||||
|
||||
vk::Gpu::MemoryProperties m_memory_properties {};
|
||||
|
||||
std::vector<vk::Gpu::QueueFamilyProperties> m_queue_family_properties;
|
||||
|
|
@ -111,42 +77,4 @@ Gpu::Gpu(IInstance *instance)
|
|||
return m_gpu;
|
||||
}
|
||||
|
||||
// [[nodiscard]] auto Gpu::queue_family_supports_presentation(
|
||||
// VkSurfaceKHR surface,
|
||||
// uint32_t queue_family_idx
|
||||
// ) -> bool
|
||||
// {
|
||||
// auto supported = VkBool32 { false };
|
||||
// vkc(vk_get_physical_device_surface_support(m_gpu, queue_family_idx, surface, &supported));
|
||||
//
|
||||
// return supported;
|
||||
// }
|
||||
//
|
||||
// [[nodiscard]] auto Gpu::get_surface_capabilities(VkSurfaceKHR surface) const
|
||||
// -> VkSurfaceCapabilitiesKHR
|
||||
// {
|
||||
// auto capabilities = VkSurfaceCapabilitiesKHR {};
|
||||
// vkc(vk_get_physical_device_surface_capabilities(m_gpu, surface, &capabilities));
|
||||
// return capabilities;
|
||||
// }
|
||||
//
|
||||
// [[nodiscard]] auto Gpu::get_surface_formats(VkSurfaceKHR surface) const
|
||||
// -> std::vector<VkSurfaceFormatKHR>
|
||||
// {
|
||||
// auto count = uint32_t { 0u };
|
||||
// vkc(vk_get_physical_device_surface_formats(m_gpu, surface, &count, nullptr));
|
||||
//
|
||||
// auto formats = std::vector<VkSurfaceFormatKHR>(count);
|
||||
// vkc(vk_get_physical_device_surface_formats(m_gpu, surface, &count, formats.data()));
|
||||
//
|
||||
// return formats;
|
||||
// }
|
||||
|
||||
// [[nodiscard]] auto Gpu::create_device(VkDeviceCreateInfo info) const -> VkDevice
|
||||
// {
|
||||
// auto *device = VkDevice {};
|
||||
// vkc(vk_create_device(m_gpu, &info, nullptr, &device));
|
||||
// return device;
|
||||
// }
|
||||
|
||||
} // namespace lt::renderer::vkb
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
export module renderer.vk.instance;
|
||||
|
||||
import preliminary;
|
||||
import debug.assertions;
|
||||
import renderer.frontend;
|
||||
import renderer.vk.api_wrapper;
|
||||
import std;
|
||||
|
||||
namespace lt::renderer::vkb {
|
||||
export namespace lt::renderer::vkb {
|
||||
|
||||
/**
|
||||
* Responsible for dynamically loading Vulkan library/functions.
|
||||
|
|
@ -15,7 +16,7 @@ namespace lt::renderer::vkb {
|
|||
* https://www.xfree86.org/4.7.0/DRI11.html
|
||||
* https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/1894
|
||||
*/
|
||||
export class Instance: public IInstance
|
||||
class Instance: public IInstance
|
||||
{
|
||||
public:
|
||||
static auto get() -> IInstance *
|
||||
|
|
@ -28,20 +29,6 @@ public:
|
|||
return m_instance;
|
||||
}
|
||||
|
||||
// /* create functions */
|
||||
// [[nodiscard]] auto create_xlib_surface(VkXlibSurfaceCreateInfoKHR info) const ->
|
||||
// VkSurfaceKHR;
|
||||
//
|
||||
// [[nodiscard]] auto create_messenger(VkDebugUtilsMessengerCreateInfoEXT info) const
|
||||
// -> VkDebugUtilsMessengerEXT;
|
||||
//
|
||||
// /* destroy functions */
|
||||
// void destroy_surface(VkSurfaceKHR surface) const;
|
||||
//
|
||||
// void destroy_messenger(VkDebugUtilsMessengerEXT messenger) const;
|
||||
//
|
||||
// [[nodiscard]] auto enumerate_gpus() const -> std::vector<VkPhysicalDevice>;
|
||||
|
||||
private:
|
||||
static auto instance() -> IInstance &
|
||||
{
|
||||
|
|
@ -81,7 +68,7 @@ Instance::Instance()
|
|||
Setting { .name = "enable_message_limit", .values = true },
|
||||
Setting {
|
||||
.name = "duplicate_message_limit",
|
||||
.values = std::numeric_limits<std::uint32_t>::max(),
|
||||
.values = std::numeric_limits<u32>::max(),
|
||||
},
|
||||
Setting {
|
||||
.name = "report_flags",
|
||||
|
|
@ -89,7 +76,6 @@ Instance::Instance()
|
|||
},
|
||||
};
|
||||
|
||||
|
||||
using Layer = vk::Instance::Layer;
|
||||
m_instance = vk::Instance(
|
||||
vk::Instance::CreateInfo {
|
||||
|
|
@ -110,41 +96,4 @@ Instance::Instance()
|
|||
m_instance.load_functions();
|
||||
}
|
||||
|
||||
// auto Instance::enumerate_gpus() const -> std::vector<VkPhysicalDevice>
|
||||
// {
|
||||
// auto count = 0u;
|
||||
// vkc(vk_enumerate_physical_devices(m_instance, &count, nullptr));
|
||||
// debug::ensure(count != 0u, "Failed to find any gpus with Vulkan support");
|
||||
//
|
||||
// auto gpus = std::vector<VkPhysicalDevice>(count);
|
||||
// vkc(vk_enumerate_physical_devices(m_instance, &count, gpus.data()));
|
||||
// return gpus;
|
||||
// }
|
||||
//
|
||||
// auto Instance::create_xlib_surface(VkXlibSurfaceCreateInfoKHR info) const -> VkSurfaceKHR
|
||||
// {
|
||||
// auto *value = VkSurfaceKHR {};
|
||||
// vk_create_xlib_surface_khr(m_instance, &info, m_allocator, &value);
|
||||
//
|
||||
// return value;
|
||||
// }
|
||||
//
|
||||
// [[nodiscard]] auto Instance::create_messenger(VkDebugUtilsMessengerCreateInfoEXT info) const
|
||||
// -> VkDebugUtilsMessengerEXT
|
||||
// {
|
||||
// auto *messenger = VkDebugUtilsMessengerEXT {};
|
||||
// vkc(vk_create_debug_messenger(m_instance, &info, m_allocator, &messenger));
|
||||
// return messenger;
|
||||
// }
|
||||
//
|
||||
// void Instance::destroy_surface(VkSurfaceKHR surface) const
|
||||
// {
|
||||
// vk_destroy_surface_khr(m_instance, surface, m_allocator);
|
||||
// }
|
||||
//
|
||||
// void Instance::destroy_messenger(VkDebugUtilsMessengerEXT messenger) const
|
||||
// {
|
||||
// vk_destroy_debug_messenger(m_instance, messenger, m_allocator);
|
||||
// }
|
||||
|
||||
} // namespace lt::renderer::vkb
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export module renderer.vk.pass;
|
||||
|
||||
import preliminary;
|
||||
import renderer.data;
|
||||
import renderer.vk.api_wrapper;
|
||||
import renderer.vk.device;
|
||||
|
|
@ -7,11 +9,10 @@ import assets.shader;
|
|||
import assets.metadata;
|
||||
import memory.null_on_move;
|
||||
import renderer.frontend;
|
||||
import std;
|
||||
|
||||
namespace lt::renderer::vkb {
|
||||
export namespace lt::renderer::vkb {
|
||||
|
||||
export class Pass: public IPass
|
||||
class Pass: public IPass
|
||||
{
|
||||
public:
|
||||
Pass(
|
||||
|
|
@ -51,10 +52,8 @@ private:
|
|||
|
||||
} // namespace lt::renderer::vkb
|
||||
|
||||
|
||||
module :private;
|
||||
using namespace ::lt::renderer::vkb;
|
||||
using namespace ::lt::renderer;
|
||||
namespace lt::renderer::vkb {
|
||||
|
||||
using enum vk::DescriptorSetLayout::Binding::FlagBits;
|
||||
|
||||
|
|
@ -80,36 +79,6 @@ Pass::Pass(
|
|||
.push_constant_ranges = { { vk::ShaderStageFlags::vertex_bit, 0u, sizeof(FrameConstants) } }
|
||||
}))
|
||||
{
|
||||
// auto pool_size = VkDescriptorPoolSize {
|
||||
// .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
// .descriptorCount = descriptor_count,
|
||||
// };
|
||||
//
|
||||
// m_descriptor_pool = m_device->create_desscriptor_pool(
|
||||
// {
|
||||
// .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
// .poolSizeCount = 1u,
|
||||
// .pPoolSizes = &pool_size,
|
||||
// }
|
||||
// );
|
||||
//
|
||||
// auto descriptor_set_variable_descriptor_count_info
|
||||
// = VkDescriptorSetVariableDescriptorCountAllocateInfo {
|
||||
// .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
|
||||
// .descriptorSetCount = 1u,
|
||||
// .pDescriptorCounts = &descriptor_count,
|
||||
// };
|
||||
//
|
||||
// m_vertices_descriptor_set = m_device->allocate_descriptor_set(
|
||||
// VkDescriptorSetAllocateInfo {
|
||||
// .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
// .pNext = &descriptor_set_variable_descriptor_count_info,
|
||||
// .descriptorPool = m_descriptor_pool,
|
||||
// .descriptorSetCount = 1u,
|
||||
// .pSetLayouts = &m_vertices_descriptor_set_layout,
|
||||
// }
|
||||
// );
|
||||
|
||||
auto shaders = std::vector<std::pair<vk::ShaderModule, vk::ShaderStageFlags::T>> {};
|
||||
shaders.emplace_back(
|
||||
vk::ShaderModule(
|
||||
|
|
@ -152,3 +121,5 @@ Pass::Pass(
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace lt::renderer::vkb
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export module renderer.vk.renderer;
|
||||
|
||||
import preliminary;
|
||||
import logger;
|
||||
import assets.shader;
|
||||
import debug.assertions;
|
||||
|
|
@ -14,19 +16,17 @@ import renderer.vk.buffer;
|
|||
import renderer.vk.pass;
|
||||
import renderer.data;
|
||||
import renderer.frontend;
|
||||
import std;
|
||||
|
||||
namespace lt::renderer::vkb {
|
||||
export namespace lt::renderer::vkb {
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
export class Renderer: public IRenderer
|
||||
class Renderer: public IRenderer
|
||||
{
|
||||
public:
|
||||
Renderer(
|
||||
class IGpu *gpu,
|
||||
class IDevice *device,
|
||||
class ISwapchain *swapchain,
|
||||
std::uint32_t max_frames_in_flight
|
||||
u32 max_frames_in_flight
|
||||
);
|
||||
|
||||
~Renderer() override
|
||||
|
|
@ -42,8 +42,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] auto frame(std::uint32_t frame_idx, std::function<void()> submit_scene)
|
||||
-> Result override;
|
||||
[[nodiscard]] auto frame(u32 frame_idx, std::function<void()> submit_scene) -> Result override;
|
||||
|
||||
void replace_swapchain(ISwapchain *swapchain) override;
|
||||
|
||||
|
|
@ -58,11 +57,11 @@ public:
|
|||
) override;
|
||||
|
||||
private:
|
||||
void record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx);
|
||||
void record_cmd(vk::CommandBuffer &cmd, u32 image_idx);
|
||||
|
||||
void map_buffers(std::uint32_t frame_idx);
|
||||
void map_buffers(u32 frame_idx);
|
||||
|
||||
std::uint32_t m_max_frames_in_flight {};
|
||||
u32 m_max_frames_in_flight {};
|
||||
|
||||
Device *m_device {};
|
||||
|
||||
|
|
@ -88,13 +87,13 @@ private:
|
|||
|
||||
Buffer m_staging_buffer;
|
||||
|
||||
std::size_t m_staging_offset;
|
||||
size_t m_staging_offset;
|
||||
|
||||
std::span<std::byte> m_staging_map;
|
||||
std::span<byte> m_staging_map;
|
||||
|
||||
std::span<components::Sprite::Vertex> m_sprite_vertex_map;
|
||||
|
||||
std::size_t m_current_sprite_idx;
|
||||
size_t m_current_sprite_idx;
|
||||
|
||||
vk::DescriptorPool m_global_set_pool;
|
||||
|
||||
|
|
@ -106,12 +105,7 @@ private:
|
|||
module :private;
|
||||
namespace lt::renderer::vkb {
|
||||
|
||||
Renderer::Renderer(
|
||||
IGpu *gpu,
|
||||
IDevice *device,
|
||||
ISwapchain *swapchain,
|
||||
std::uint32_t max_frames_in_flight
|
||||
)
|
||||
Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, u32 max_frames_in_flight)
|
||||
: m_device(static_cast<Device *>(device))
|
||||
, m_swapchain(static_cast<Swapchain *>(swapchain))
|
||||
, m_resolution(m_swapchain->get_resolution())
|
||||
|
|
@ -175,8 +169,7 @@ Renderer::Renderer(
|
|||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] auto Renderer::frame(std::uint32_t frame_idx, std::function<void()> submit_scene)
|
||||
-> Result
|
||||
[[nodiscard]] auto Renderer::frame(u32 frame_idx, std::function<void()> submit_scene) -> Result
|
||||
{
|
||||
debug::ensure(
|
||||
frame_idx < m_max_frames_in_flight,
|
||||
|
|
@ -196,7 +189,7 @@ Renderer::Renderer(
|
|||
map_buffers(frame_idx);
|
||||
|
||||
// WIP(Light): submit the scene!
|
||||
std::ignore = submit_scene;
|
||||
ignore = submit_scene;
|
||||
// submit_scene();
|
||||
record_cmd(cmd, image_idx);
|
||||
|
||||
|
|
@ -229,7 +222,7 @@ void Renderer::replace_swapchain(ISwapchain *swapchain)
|
|||
m_resolution = m_swapchain->get_resolution();
|
||||
}
|
||||
|
||||
void Renderer::map_buffers(std::uint32_t frame_idx)
|
||||
void Renderer::map_buffers(u32 frame_idx)
|
||||
{
|
||||
using components::Sprite;
|
||||
|
||||
|
|
@ -246,7 +239,7 @@ void Renderer::map_buffers(std::uint32_t frame_idx)
|
|||
);
|
||||
}
|
||||
|
||||
void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
|
||||
void Renderer::record_cmd(vk::CommandBuffer &cmd, u32 image_idx)
|
||||
{
|
||||
m_staging_map = {};
|
||||
m_sprite_vertex_map = {};
|
||||
|
|
@ -318,7 +311,7 @@ void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
|
|||
// cmd.set_viewport(
|
||||
// {
|
||||
// .origin = {},
|
||||
// .extent = { static_cast<float>(m_resolution.x), static_cast<float>(m_resolution.y) },
|
||||
// .extent = { static_cast<f32>(m_resolution.x), static_cast<f32>(m_resolution.y) },
|
||||
// .min_depth = 0.0f,
|
||||
// .max_depth = 1.0f,
|
||||
// }
|
||||
|
|
@ -326,7 +319,7 @@ void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
|
|||
// cmd.set_scissor({ .offset = {}, .extent = m_resolution });
|
||||
// cmd.draw(
|
||||
// {
|
||||
// .vertex_count = static_cast<std::uint32_t>(m_current_sprite_idx),
|
||||
// .vertex_count = static_cast<u32>(m_current_sprite_idx),
|
||||
// .instance_count = 1u,
|
||||
// .first_vertex = 0u,
|
||||
// .first_instance = 0u,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export module renderer.vk.surface;
|
||||
|
||||
import preliminary;
|
||||
import debug.assertions;
|
||||
import ecs.entity;
|
||||
import ecs.registry;
|
||||
|
|
@ -9,9 +11,9 @@ import renderer.frontend;
|
|||
import renderer.vk.instance;
|
||||
import renderer.vk.api_wrapper;
|
||||
|
||||
namespace lt::renderer::vkb {
|
||||
export namespace lt::renderer::vkb {
|
||||
|
||||
export class Surface: public ISurface
|
||||
class Surface: public ISurface
|
||||
{
|
||||
public:
|
||||
Surface(IInstance *instance, const ecs::Entity &surface_entity);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export module renderer.vk.swapchain;
|
||||
|
||||
import preliminary;
|
||||
import renderer.vk.api_wrapper;
|
||||
import renderer.vk.surface;
|
||||
import renderer.vk.device;
|
||||
|
|
@ -8,11 +10,10 @@ import renderer.frontend;
|
|||
import math.vec2;
|
||||
import memory.null_on_move;
|
||||
import logger;
|
||||
import std;
|
||||
|
||||
namespace lt::renderer::vkb {
|
||||
export namespace lt::renderer::vkb {
|
||||
|
||||
export class Swapchain: public ISwapchain
|
||||
class Swapchain: public ISwapchain
|
||||
{
|
||||
public:
|
||||
Swapchain(ISurface *surface, IGpu *gpu, IDevice *device);
|
||||
|
|
@ -32,17 +33,17 @@ public:
|
|||
return m_format;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_image_count() const -> std::size_t
|
||||
[[nodiscard]] auto get_image_count() const -> size_t
|
||||
{
|
||||
return m_images.size();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_image_view(std::uint32_t idx) -> vk::ImageView &
|
||||
[[nodiscard]] auto get_image_view(u32 idx) -> vk::ImageView &
|
||||
{
|
||||
return m_image_views[idx];
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_image(std::uint32_t idx) -> vk::Image &
|
||||
[[nodiscard]] auto get_image(u32 idx) -> vk::Image &
|
||||
{
|
||||
return m_images[idx];
|
||||
}
|
||||
|
|
@ -50,8 +51,8 @@ public:
|
|||
private:
|
||||
[[nodiscard]] auto get_optimal_image_count(
|
||||
vk::Surface::Capabilities capabilities,
|
||||
std::uint32_t desired_image_count
|
||||
) const -> std::uint32_t;
|
||||
u32 desired_image_count
|
||||
) const -> u32;
|
||||
|
||||
Gpu *m_gpu;
|
||||
|
||||
|
|
@ -72,7 +73,6 @@ private:
|
|||
|
||||
} // namespace lt::renderer::vkb
|
||||
|
||||
|
||||
module :private;
|
||||
namespace lt::renderer::vkb {
|
||||
|
||||
|
|
@ -85,11 +85,11 @@ Swapchain::Swapchain(ISurface *surface, IGpu *gpu, IDevice *device)
|
|||
const auto formats = m_gpu->vk().get_surface_formats(m_surface->vk());
|
||||
|
||||
// TODO(Light): parameterize
|
||||
constexpr auto desired_image_count = std::uint32_t { 3u };
|
||||
constexpr auto desired_image_count = u32 { 3u };
|
||||
const auto surface_format = formats.front();
|
||||
m_format = surface_format.format;
|
||||
|
||||
if (capabilities.current_extent.x == std::numeric_limits<std::uint32_t>::max())
|
||||
if (capabilities.current_extent.x == std::numeric_limits<u32>::max())
|
||||
{
|
||||
log::info(
|
||||
"Vulkan surface capabilities current extent is uint32 max... This indicates that the "
|
||||
|
|
@ -155,8 +155,8 @@ Swapchain::Swapchain(ISurface *surface, IGpu *gpu, IDevice *device)
|
|||
|
||||
[[nodiscard]] auto Swapchain::get_optimal_image_count(
|
||||
vk::Surface::Capabilities capabilities,
|
||||
std::uint32_t desired_image_count
|
||||
) const -> std::uint32_t
|
||||
u32 desired_image_count
|
||||
) const -> u32
|
||||
{
|
||||
const auto min_image_count = capabilities.min_image_count;
|
||||
const auto max_image_count = capabilities.max_image_count;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import preliminary;
|
||||
import test.test;
|
||||
import time;
|
||||
import test.expects;
|
||||
|
|
@ -10,7 +11,6 @@ import memory.reference;
|
|||
import logger;
|
||||
import math.vec2;
|
||||
import app.system;
|
||||
import std;
|
||||
|
||||
constexpr auto title = "TestWindow";
|
||||
constexpr auto width = 800u;
|
||||
|
|
@ -18,7 +18,8 @@ constexpr auto height = 600u;
|
|||
constexpr auto vsync = true;
|
||||
constexpr auto visible = false;
|
||||
|
||||
int main()
|
||||
auto main() -> int32_t
|
||||
try
|
||||
{
|
||||
auto registry = lt::memory::create_ref<lt::ecs::Registry>();
|
||||
auto system = lt::surface::System { registry };
|
||||
|
|
@ -43,3 +44,12 @@ int main()
|
|||
}
|
||||
lt::log::trace("Three seconds passed, quitting...");
|
||||
}
|
||||
catch (const std::exception &exp)
|
||||
{
|
||||
lt::log::critical("Aborting due to uncaught std::exception:");
|
||||
lt::log::critical("\twhat: {}", exp.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
lt::log::critical("Aborting due to uncaught non std::exception!");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,18 +7,19 @@ struct wl_surface;
|
|||
#endif
|
||||
|
||||
export module surface.system:components;
|
||||
import std;
|
||||
|
||||
import preliminary;
|
||||
import math.vec2;
|
||||
import surface.events;
|
||||
import surface.requests;
|
||||
|
||||
namespace lt::surface {
|
||||
export namespace lt::surface {
|
||||
|
||||
/** Represents a platform's surface (eg. a Window).
|
||||
*
|
||||
* @note This is a "system component"
|
||||
*/
|
||||
export class SurfaceComponent
|
||||
class SurfaceComponent
|
||||
{
|
||||
public:
|
||||
friend class System;
|
||||
|
|
@ -59,6 +60,8 @@ public:
|
|||
|
||||
static constexpr auto max_title_length = 256;
|
||||
|
||||
// TODO(Light): add `center_to_screen` flag
|
||||
// TODO(Light): add `screen_mode` flag (windowed/full_screen/windowed_full_screen)
|
||||
struct CreateInfo
|
||||
{
|
||||
std::string_view title;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
export module surface.events;
|
||||
|
||||
import preliminary;
|
||||
import input.codes;
|
||||
import math.vec2;
|
||||
import std;
|
||||
|
||||
export namespace lt::surface {
|
||||
|
||||
|
|
@ -92,7 +93,7 @@ private:
|
|||
class MouseMovedEvent
|
||||
{
|
||||
public:
|
||||
MouseMovedEvent(float x, float y): m_position(x, y)
|
||||
MouseMovedEvent(f32 x, f32 y): m_position(x, y)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -101,12 +102,12 @@ public:
|
|||
return m_position;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_x() const -> float
|
||||
[[nodiscard]] auto get_x() const -> f32
|
||||
{
|
||||
return m_position.x;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_y() const -> float
|
||||
[[nodiscard]] auto get_y() const -> f32
|
||||
{
|
||||
return m_position.y;
|
||||
}
|
||||
|
|
@ -123,11 +124,11 @@ private:
|
|||
class WheelScrolledEvent
|
||||
{
|
||||
public:
|
||||
WheelScrolledEvent(float offset): m_offset(offset)
|
||||
WheelScrolledEvent(f32 offset): m_offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_offset() const -> float
|
||||
[[nodiscard]] auto get_offset() const -> f32
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
|
@ -140,7 +141,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
float m_offset;
|
||||
f32 m_offset;
|
||||
};
|
||||
|
||||
class ButtonPressedEvent
|
||||
|
|
@ -197,7 +198,7 @@ public:
|
|||
class MovedEvent
|
||||
{
|
||||
public:
|
||||
MovedEvent(std::int32_t x, std::int32_t y): m_position(x, y)
|
||||
MovedEvent(i32 x, i32 y): m_position(x, y)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +219,7 @@ private:
|
|||
class ResizedEvent
|
||||
{
|
||||
public:
|
||||
ResizedEvent(std::uint32_t width, std::uint32_t height): m_size(width, height)
|
||||
ResizedEvent(u32 width, u32 height): m_size(width, height)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
export module surface.requests;
|
||||
|
||||
import preliminary;
|
||||
import math.vec2;
|
||||
import std;
|
||||
|
||||
export namespace lt::surface {
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ module;
|
|||
|
||||
export module surface.system;
|
||||
export import :components;
|
||||
|
||||
import preliminary;
|
||||
import debug.assertions;
|
||||
import app.system;
|
||||
import ecs.registry;
|
||||
|
|
@ -19,7 +21,7 @@ import surface.requests;
|
|||
import memory.reference;
|
||||
import memory.null_on_move;
|
||||
import logger;
|
||||
import std;
|
||||
import preliminary;
|
||||
import surface.constants;
|
||||
import debug.assertions;
|
||||
import memory.reference;
|
||||
|
|
@ -29,7 +31,6 @@ import logger;
|
|||
import ecs.registry;
|
||||
import ecs.entity;
|
||||
import time;
|
||||
import std;
|
||||
|
||||
export namespace lt::surface {
|
||||
|
||||
|
|
@ -66,28 +67,24 @@ private:
|
|||
static void wayland_registry_listener(
|
||||
void *data,
|
||||
wl_registry *registry,
|
||||
std::uint32_t name,
|
||||
u32 name,
|
||||
const char *interface,
|
||||
std::uint32_t version
|
||||
u32 version
|
||||
);
|
||||
|
||||
static void wayland_seat_capabilities_listener(
|
||||
void *data,
|
||||
wl_seat *seat,
|
||||
std::uint32_t capabilities
|
||||
);
|
||||
static void wayland_seat_capabilities_listener(void *data, wl_seat *seat, u32 capabilities);
|
||||
|
||||
static void wayland_pointer_leave_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t serial,
|
||||
u32 serial,
|
||||
wl_surface *surface
|
||||
);
|
||||
|
||||
static void wayland_pointer_enter_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t serial,
|
||||
u32 serial,
|
||||
wl_surface *surface,
|
||||
wl_fixed_t surface_x,
|
||||
wl_fixed_t surface_y
|
||||
|
|
@ -96,7 +93,7 @@ private:
|
|||
static void wayland_pointer_motion_listener(
|
||||
void *data,
|
||||
wl_pointer *listener,
|
||||
std::uint32_t time,
|
||||
u32 time,
|
||||
wl_fixed_t surface_x,
|
||||
wl_fixed_t surface_y
|
||||
);
|
||||
|
|
@ -104,38 +101,38 @@ private:
|
|||
static void wayland_pointer_button_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t serial,
|
||||
std::uint32_t time,
|
||||
std::uint32_t button,
|
||||
std::uint32_t state
|
||||
u32 serial,
|
||||
u32 time,
|
||||
u32 button,
|
||||
u32 state
|
||||
);
|
||||
|
||||
static void wayland_pointer_axis_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t time,
|
||||
std::uint32_t axis,
|
||||
u32 time,
|
||||
u32 axis,
|
||||
wl_fixed_t value
|
||||
);
|
||||
|
||||
static void wayland_pointer_axis_source_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t axis_source
|
||||
u32 axis_source
|
||||
);
|
||||
|
||||
static void wayland_pointer_axis_stop_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t time,
|
||||
std::uint32_t axis_source
|
||||
u32 time,
|
||||
u32 axis_source
|
||||
);
|
||||
|
||||
static void wayland_pointer_axis_discrete_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t axis,
|
||||
std::int32_t discrete
|
||||
u32 axis,
|
||||
i32 discrete
|
||||
);
|
||||
|
||||
static void wayland_pointer_frame_listener(void *data, wl_pointer *pointer);
|
||||
|
|
@ -199,18 +196,18 @@ namespace lt::surface {
|
|||
|
||||
#if defined(LIGHT_PLATFORM_LINUX)
|
||||
|
||||
void handle_shell_ping(void *data, xdg_wm_base *shell, std::uint32_t serial)
|
||||
void handle_shell_ping(void *data, xdg_wm_base *shell, u32 serial)
|
||||
{
|
||||
std::ignore = data;
|
||||
ignore = data;
|
||||
xdg_wm_base_pong(shell, serial);
|
||||
}
|
||||
const auto shell_listener = xdg_wm_base_listener {
|
||||
.ping = &handle_shell_ping,
|
||||
};
|
||||
|
||||
void handle_shell_surface_configure(void *data, xdg_surface *shell_surface, std::uint32_t serial)
|
||||
void handle_shell_surface_configure(void *data, xdg_surface *shell_surface, u32 serial)
|
||||
{
|
||||
std::ignore = data;
|
||||
ignore = data;
|
||||
|
||||
xdg_surface_ack_configure(shell_surface, serial);
|
||||
}
|
||||
|
|
@ -221,8 +218,8 @@ const auto shell_surface_listener = xdg_surface_listener {
|
|||
void handle_toplevel_configure(
|
||||
void *data,
|
||||
xdg_toplevel *toplevel,
|
||||
std::int32_t width,
|
||||
std::int32_t height,
|
||||
i32 width,
|
||||
i32 height,
|
||||
wl_array *states
|
||||
)
|
||||
{
|
||||
|
|
@ -240,7 +237,7 @@ const auto toplevel_listener = xdg_toplevel_listener {
|
|||
void wayland_pointer_leave_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t serial,
|
||||
u32 serial,
|
||||
wl_surface *surface
|
||||
)
|
||||
{
|
||||
|
|
@ -250,10 +247,10 @@ void wayland_pointer_leave_listener(
|
|||
/* static */ void System::wayland_seat_capabilities_listener(
|
||||
void *data,
|
||||
wl_seat *seat,
|
||||
std::uint32_t capabilities
|
||||
u32 capabilities
|
||||
)
|
||||
{
|
||||
std::ignore = seat;
|
||||
ignore = seat;
|
||||
|
||||
auto *system = std::bit_cast<System *>(data);
|
||||
const auto have_pointer = capabilities & WL_SEAT_CAPABILITY_POINTER;
|
||||
|
|
@ -262,27 +259,21 @@ void wayland_pointer_leave_listener(
|
|||
{
|
||||
system->m_wl_pointer = wl_seat_get_pointer(system->m_wl_seat);
|
||||
wl_pointer_add_listener(system->m_wl_pointer, &system->m_wl_pointer_listener, system);
|
||||
log::info(
|
||||
"Added Wayland pointer (0x{:x})",
|
||||
std::bit_cast<std::size_t>(system->m_wl_pointer)
|
||||
);
|
||||
log::info("Added Wayland pointer (0x{:x})", std::bit_cast<size_t>(system->m_wl_pointer));
|
||||
}
|
||||
else if (!have_pointer && system->m_wl_pointer)
|
||||
{
|
||||
wl_pointer_release(system->m_wl_pointer);
|
||||
system->m_wl_pointer = nullptr;
|
||||
|
||||
log::info(
|
||||
"Released Wayland pointer (0x{:x})",
|
||||
std::bit_cast<std::size_t>(system->m_wl_pointer)
|
||||
);
|
||||
log::info("Released Wayland pointer (0x{:x})", std::bit_cast<size_t>(system->m_wl_pointer));
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void System::wayland_pointer_leave_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t serial,
|
||||
u32 serial,
|
||||
wl_surface *surface
|
||||
)
|
||||
{
|
||||
|
|
@ -292,7 +283,7 @@ void wayland_pointer_leave_listener(
|
|||
/* static */ void System::wayland_pointer_enter_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t serial,
|
||||
u32 serial,
|
||||
wl_surface *surface,
|
||||
wl_fixed_t surface_x,
|
||||
wl_fixed_t surface_y
|
||||
|
|
@ -304,7 +295,7 @@ void wayland_pointer_leave_listener(
|
|||
/* static */ void System::wayland_pointer_motion_listener(
|
||||
void *data,
|
||||
wl_pointer *listener,
|
||||
std::uint32_t time,
|
||||
u32 time,
|
||||
wl_fixed_t surface_x,
|
||||
wl_fixed_t surface_y
|
||||
)
|
||||
|
|
@ -315,10 +306,10 @@ void wayland_pointer_leave_listener(
|
|||
/* static */ void System::wayland_pointer_button_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t serial,
|
||||
std::uint32_t time,
|
||||
std::uint32_t button,
|
||||
std::uint32_t state
|
||||
u32 serial,
|
||||
u32 time,
|
||||
u32 button,
|
||||
u32 state
|
||||
)
|
||||
{
|
||||
}
|
||||
|
|
@ -326,8 +317,8 @@ void wayland_pointer_leave_listener(
|
|||
/* static */ void System::wayland_pointer_axis_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t time,
|
||||
std::uint32_t axis,
|
||||
u32 time,
|
||||
u32 axis,
|
||||
wl_fixed_t value
|
||||
)
|
||||
{
|
||||
|
|
@ -336,7 +327,7 @@ void wayland_pointer_leave_listener(
|
|||
/* static */ void System::wayland_pointer_axis_source_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t axis_source
|
||||
u32 axis_source
|
||||
)
|
||||
{
|
||||
}
|
||||
|
|
@ -344,8 +335,8 @@ void wayland_pointer_leave_listener(
|
|||
/* static */ void System::wayland_pointer_axis_stop_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t time,
|
||||
std::uint32_t axis_source
|
||||
u32 time,
|
||||
u32 axis_source
|
||||
)
|
||||
{
|
||||
}
|
||||
|
|
@ -353,8 +344,8 @@ void wayland_pointer_leave_listener(
|
|||
/* static */ void System::wayland_pointer_axis_discrete_listener(
|
||||
void *data,
|
||||
wl_pointer *pointer,
|
||||
std::uint32_t axis,
|
||||
std::int32_t discrete
|
||||
u32 axis,
|
||||
i32 discrete
|
||||
)
|
||||
{
|
||||
}
|
||||
|
|
@ -366,23 +357,23 @@ void wayland_pointer_leave_listener(
|
|||
|
||||
void seat_name_listener(void *data, wl_seat *seat, const char *name)
|
||||
{
|
||||
std::ignore = data;
|
||||
ignore = data;
|
||||
|
||||
log::info("Wayland seat:");
|
||||
log::info("\tname: {}", name);
|
||||
log::info("\taddr: 0x{:x}", std::bit_cast<std::size_t>(seat));
|
||||
log::info("\taddr: 0x{:x}", std::bit_cast<size_t>(seat));
|
||||
}
|
||||
|
||||
void System::wayland_registry_listener(
|
||||
void *data,
|
||||
wl_registry *registry,
|
||||
std::uint32_t name,
|
||||
u32 name,
|
||||
const char *interface,
|
||||
std::uint32_t version
|
||||
u32 version
|
||||
)
|
||||
|
||||
{
|
||||
std::ignore = version;
|
||||
ignore = version;
|
||||
|
||||
auto *system = std::bit_cast<System *>(data);
|
||||
|
||||
|
|
@ -413,7 +404,7 @@ void System::wayland_registry_listener(
|
|||
}
|
||||
}
|
||||
|
||||
void registry_handle_global_remove(void *data, wl_registry *registry, std::uint32_t name)
|
||||
void registry_handle_global_remove(void *data, wl_registry *registry, u32 name)
|
||||
{
|
||||
log::trace("Registry global remove:");
|
||||
log::trace("\tname: {}", name);
|
||||
|
|
@ -723,15 +714,15 @@ try
|
|||
{
|
||||
// WIP(Light): use ignored local variables...
|
||||
auto &component = m_registry->add<SurfaceComponent>(entity, info);
|
||||
std::ignore = component;
|
||||
ignore = component;
|
||||
|
||||
auto &surface = m_registry->get<SurfaceComponent>(entity);
|
||||
ensure_component_sanity(surface);
|
||||
|
||||
const auto &resolution = surface.get_resolution();
|
||||
const auto &position = surface.get_position();
|
||||
std::ignore = resolution;
|
||||
std::ignore = position;
|
||||
ignore = resolution;
|
||||
ignore = position;
|
||||
|
||||
surface.m_native_data.window = CreateWindowEx(
|
||||
0,
|
||||
|
|
@ -765,7 +756,7 @@ try
|
|||
// auto root_window = XDefaultRootWindow(display);
|
||||
//
|
||||
// auto border_width = 0;
|
||||
// auto depth = std::int32_t { CopyFromParent };
|
||||
// auto depth = i32 { CopyFromParent };
|
||||
// auto window_class = CopyFromParent;
|
||||
// auto *visual = (Visual *)CopyFromParent;
|
||||
//
|
||||
|
|
@ -831,7 +822,7 @@ try
|
|||
catch (const std::exception &exp)
|
||||
{
|
||||
log::error("Exception thrown when on_constructing surface component");
|
||||
log::error("\tentity: {}", std::uint32_t { entity });
|
||||
log::error("\tentity: {}", u32 { entity });
|
||||
log::error("\twhat: {}", exp.what());
|
||||
m_registry->remove<SurfaceComponent>(entity);
|
||||
}
|
||||
|
|
@ -864,12 +855,12 @@ void System::handle_events(SurfaceComponent &surface)
|
|||
case WM_SETFOCUS: log::debug("Window setfocus"); break;
|
||||
case WM_KILLFOCUS: log::debug("Window killfocus"); break;
|
||||
case WM_ACTIVATE:
|
||||
log::debug("Window activate: {}", static_cast<std::size_t>(LOWORD(wParam)));
|
||||
log::debug("Window activate: {}", static_cast<size_t>(LOWORD(wParam)));
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
const auto delta = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
|
||||
log::debug("wheel delta: {}", static_cast<std::int64_t>(delta));
|
||||
log::debug("wheel delta: {}", static_cast<i64>(delta));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -928,14 +919,14 @@ void System::handle_events(SurfaceComponent &surface)
|
|||
// case KeyPress:
|
||||
// {
|
||||
// queue.emplace_back<KeyPressedEvent>(
|
||||
// static_cast<std::uint32_t>(XLookupKeysym(&event.xkey, 0))
|
||||
// static_cast<u32>(XLookupKeysym(&event.xkey, 0))
|
||||
// );
|
||||
// break;
|
||||
// }
|
||||
// case KeyRelease:
|
||||
// {
|
||||
// queue.emplace_back<KeyReleasedEvent>(
|
||||
// static_cast<std::uint32_t>(XLookupKeysym(&event.xkey, 0))
|
||||
// static_cast<u32>(XLookupKeysym(&event.xkey, 0))
|
||||
// );
|
||||
// break;
|
||||
// }
|
||||
|
|
@ -971,8 +962,8 @@ void System::handle_events(SurfaceComponent &surface)
|
|||
// case MotionNotify:
|
||||
// {
|
||||
// queue.emplace_back<MouseMovedEvent>(MouseMovedEvent {
|
||||
// static_cast<float>(event.xmotion.x),
|
||||
// static_cast<float>(event.xmotion.y),
|
||||
// static_cast<f32>(event.xmotion.x),
|
||||
// static_cast<f32>(event.xmotion.y),
|
||||
// });
|
||||
// break;
|
||||
// }
|
||||
|
|
@ -986,8 +977,8 @@ void System::handle_events(SurfaceComponent &surface)
|
|||
// surface.m_resolution.x = new_width;
|
||||
// surface.m_resolution.y = new_height;
|
||||
// queue.emplace_back<ResizedEvent>(ResizedEvent {
|
||||
// static_cast<std::uint32_t>(new_width),
|
||||
// static_cast<std::uint32_t>(new_height),
|
||||
// static_cast<u32>(new_width),
|
||||
// static_cast<u32>(new_height),
|
||||
// });
|
||||
// }
|
||||
//
|
||||
|
|
@ -1026,13 +1017,15 @@ void System::handle_requests(SurfaceComponent &surface)
|
|||
{
|
||||
std::visit(visitor, request);
|
||||
}
|
||||
|
||||
surface.m_requests.clear();
|
||||
}
|
||||
|
||||
void System::modify_title(SurfaceComponent &surface, const ModifyTitleRequest &request)
|
||||
{
|
||||
// WIP(Light):
|
||||
std::ignore = surface;
|
||||
std::ignore = request;
|
||||
ignore = surface;
|
||||
ignore = request;
|
||||
|
||||
surface.m_title = request.title;
|
||||
|
||||
|
|
@ -1043,8 +1036,8 @@ void System::modify_title(SurfaceComponent &surface, const ModifyTitleRequest &r
|
|||
void System::modify_resolution(SurfaceComponent &surface, const ModifyResolutionRequest &request)
|
||||
{
|
||||
// WIP(Light):
|
||||
std::ignore = surface;
|
||||
std::ignore = request;
|
||||
ignore = surface;
|
||||
ignore = request;
|
||||
|
||||
// surface.m_resolution = request.resolution;
|
||||
|
||||
|
|
@ -1059,8 +1052,8 @@ void System::modify_resolution(SurfaceComponent &surface, const ModifyResolution
|
|||
// XResizeWindow(
|
||||
// display,
|
||||
// window,
|
||||
// static_cast<std::uint32_t>(width),
|
||||
// static_cast<std::uint32_t>(height)
|
||||
// static_cast<u32>(width),
|
||||
// static_cast<u32>(height)
|
||||
// );
|
||||
//
|
||||
// // flush output queue and wait for X server to processes the request
|
||||
|
|
@ -1108,52 +1101,22 @@ void System::modify_resolution(SurfaceComponent &surface, const ModifyResolution
|
|||
|
||||
void System::modify_position(SurfaceComponent &surface, const ModifyPositionRequest &request)
|
||||
{
|
||||
// WIP(Light): Use ignored local-variables
|
||||
std::ignore = surface;
|
||||
std::ignore = 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<int>(x), static_cast<int>(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<ConfigureNotify>,
|
||||
// reinterpret_cast<XPointer>(&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);
|
||||
SetWindowPos(
|
||||
surface.m_native_data.window,
|
||||
{},
|
||||
request.position.x,
|
||||
request.position.y,
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
void System::modify_visiblity(SurfaceComponent &surface, const ModifyVisibilityRequest &request)
|
||||
{
|
||||
// WIP(Light): Use ignored local-variables
|
||||
std::ignore = surface;
|
||||
std::ignore = request;
|
||||
ignore = surface;
|
||||
ignore = request;
|
||||
|
||||
// const auto &[display, window, _] = surface.get_native_data();
|
||||
// surface.m_visible = request.visible;
|
||||
|
|
@ -1223,7 +1186,8 @@ auto CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ->
|
|||
switch (uMsg)
|
||||
{
|
||||
case WM_KILLFOCUS:
|
||||
case WM_SETFOCUS: log::debug("GOT FOCUS IN WIN PROC");
|
||||
case WM_MOVE:
|
||||
case WM_SETFOCUS:
|
||||
case WM_ACTIVATE:
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_LBUTTONDOWN:
|
||||
|
|
|
|||
|
|
@ -1,155 +0,0 @@
|
|||
#include <ecs/entity.hpp>
|
||||
#include <ecs/registry.hpp>
|
||||
#include <memory/reference.hpp>
|
||||
#include <surface/components.hpp>
|
||||
#include <surface/system.hpp>
|
||||
#include <test/fuzz.hpp>
|
||||
#include <test/test.hpp>
|
||||
|
||||
namespace lt::surface {
|
||||
|
||||
enum class FuzzAction : uint8_t
|
||||
{
|
||||
create_entity,
|
||||
|
||||
create_surface_component,
|
||||
|
||||
destroy_surface_component,
|
||||
|
||||
push_request,
|
||||
|
||||
push_event,
|
||||
|
||||
tick_system,
|
||||
|
||||
count,
|
||||
};
|
||||
|
||||
enum class EventType : uint8_t
|
||||
{
|
||||
Closed,
|
||||
Moved,
|
||||
Resized,
|
||||
LostFocus,
|
||||
GainFocus,
|
||||
};
|
||||
|
||||
void create_surface_component(test::FuzzDataProvider &provider, ecs::Registry ®istry)
|
||||
{
|
||||
const auto length = std::min(provider.consume<uint32_t>().value_or(16), 255u);
|
||||
const auto title = provider.consume_string(length).value_or("");
|
||||
|
||||
const auto resolution = math::uvec2 {
|
||||
provider.consume<uint32_t>().value_or(32u),
|
||||
provider.consume<uint32_t>().value_or(64u),
|
||||
};
|
||||
const auto visible = provider.consume<bool>().value_or(false);
|
||||
const auto vsync = provider.consume<bool>().value_or(false);
|
||||
|
||||
try
|
||||
{
|
||||
auto entity = registry.create_entity();
|
||||
registry.add<surface::SurfaceComponent>(
|
||||
entity,
|
||||
surface::SurfaceComponent::CreateInfo {
|
||||
.title = std::move(title),
|
||||
.resolution = resolution,
|
||||
.vsync = vsync,
|
||||
.visible = visible,
|
||||
}
|
||||
);
|
||||
}
|
||||
catch (const std::exception &exp)
|
||||
{
|
||||
std::ignore = exp;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_surface_component(ecs::Registry ®istry)
|
||||
{
|
||||
const auto view = registry.view<SurfaceComponent>();
|
||||
|
||||
if (!view.is_empty())
|
||||
{
|
||||
registry.remove<SurfaceComponent>(view[0].first);
|
||||
}
|
||||
}
|
||||
|
||||
void push_request(ecs::Registry ®istry)
|
||||
{
|
||||
}
|
||||
|
||||
void push_event(ecs::Registry ®istry)
|
||||
{
|
||||
}
|
||||
|
||||
void check_invariants()
|
||||
{
|
||||
}
|
||||
|
||||
test::FuzzHarness harness = [](const uint8_t *data, size_t size) {
|
||||
auto provider = test::FuzzDataProvider { data, size };
|
||||
|
||||
auto registry = memory::create_ref<ecs::Registry>();
|
||||
auto system = surface::System { registry };
|
||||
|
||||
while (auto action = provider.consume<uint8_t>())
|
||||
{
|
||||
if (*action > std::to_underlying(FuzzAction::count))
|
||||
{
|
||||
*action = *action % std::to_underlying(FuzzAction::count);
|
||||
}
|
||||
|
||||
switch (static_cast<FuzzAction>(action.value()))
|
||||
{
|
||||
case FuzzAction::create_entity:
|
||||
{
|
||||
const auto length = std::min(provider.consume<uint32_t>().value_or(16), 255u);
|
||||
registry->create_entity();
|
||||
|
||||
break;
|
||||
}
|
||||
case FuzzAction::create_surface_component:
|
||||
{
|
||||
create_surface_component(provider, *registry);
|
||||
break;
|
||||
}
|
||||
case FuzzAction::destroy_surface_component:
|
||||
{
|
||||
remove_surface_component(*registry);
|
||||
break;
|
||||
}
|
||||
case FuzzAction::push_event:
|
||||
{
|
||||
auto view = registry->view<SurfaceComponent>();
|
||||
|
||||
if (!view.is_empty())
|
||||
{
|
||||
for (auto &[entity, component] : view)
|
||||
{
|
||||
provider.consume<uint8_t>().value_or(0);
|
||||
// @TODO(Light): push some event
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case FuzzAction::push_request:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case FuzzAction::count:
|
||||
case FuzzAction::tick_system:
|
||||
{
|
||||
system.tick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
check_invariants();
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
} // namespace lt::surface
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import preliminary;
|
||||
import test.test;
|
||||
import time;
|
||||
import test.expects;
|
||||
|
|
@ -10,7 +11,6 @@ import memory.reference;
|
|||
import logger;
|
||||
import math.vec2;
|
||||
import app.system;
|
||||
import std;
|
||||
|
||||
using ::lt::surface::SurfaceComponent;
|
||||
using ::lt::surface::System;
|
||||
|
|
@ -20,7 +20,6 @@ using ::lt::test::expect_ne;
|
|||
using ::lt::test::expect_not_nullptr;
|
||||
using ::lt::test::expect_throw;
|
||||
using ::lt::test::Suite;
|
||||
using ::std::ignore;
|
||||
using ::lt::test::operator""_suite;
|
||||
|
||||
[[nodiscard]] auto tick_info() -> lt::app::TickInfo
|
||||
|
|
@ -91,203 +90,194 @@ Suite raii = "raii"_suite = [] {
|
|||
Case { "happy path won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
|
||||
auto timer = lt::time::Timer {};
|
||||
lt::log::trace("Ticking for 3 seconds...");
|
||||
while (timer.elapsed_time() < std::chrono::seconds { 3 })
|
||||
{
|
||||
system.tick({});
|
||||
}
|
||||
lt::log::trace("Three seconds passed, quitting...");
|
||||
};
|
||||
|
||||
Case { "many won't freeze/throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
for (auto idx : std::views::iota(0, 250))
|
||||
{
|
||||
ignore = idx;
|
||||
ignore = System { fixture.registry() };
|
||||
}
|
||||
};
|
||||
|
||||
// Case { "many won't freeze/throw" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// for (auto idx : std::views::iota(0, 250))
|
||||
// {
|
||||
// ignore = System { fixture.registry() };
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// Case { "unhappy path throws" } = [] {
|
||||
// expect_throw([] { ignore = System { {} }; });
|
||||
// };
|
||||
//
|
||||
// Case { "post construct has correct state" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// auto system = System { fixture.registry() };
|
||||
// expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
|
||||
// };
|
||||
//
|
||||
// Case { "post destruct has correct state" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// auto system = lt::memory::create_scope<System>(fixture.registry());
|
||||
//
|
||||
// fixture.create_component();
|
||||
// expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
|
||||
//
|
||||
// system.reset();
|
||||
// expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
|
||||
// };
|
||||
Case { "unhappy path throws" } = [] {
|
||||
expect_throw([] { ignore = System { {} }; });
|
||||
};
|
||||
|
||||
Case { "post construct has correct state" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
|
||||
};
|
||||
|
||||
Case { "post destruct has correct state" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = lt::memory::create_scope<System>(fixture.registry());
|
||||
|
||||
fixture.create_component();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
|
||||
|
||||
system.reset();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
|
||||
};
|
||||
};
|
||||
|
||||
// Suite system_events = "system_events"_suite = [] {
|
||||
// Case { "on_register won't throw" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// auto system = System { fixture.registry() };
|
||||
//
|
||||
// system.on_register();
|
||||
// expect_eq(fixture.registry()->view<SurfaceComponent>().get_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>().get_size(), 0);
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// Suite registry_events = "registry_events"_suite = [] {
|
||||
// Case { "on_construct<SurfaceComponent> initializes component" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
//
|
||||
// const auto &component = fixture.create_component();
|
||||
// expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
|
||||
// fixture.check_values(*component);
|
||||
// };
|
||||
//
|
||||
// Case { "unhappy on_construct<SurfaceComponent> throws" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// auto system = System { fixture.registry() };
|
||||
//
|
||||
// expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
|
||||
//
|
||||
// expect_throw([&] { fixture.create_component({ .resolution = { 0, height } }); });
|
||||
//
|
||||
// expect_throw([&] {
|
||||
// fixture.create_component(
|
||||
// { .title = "", .resolution = { SurfaceComponent::max_dimension + 1, height } }
|
||||
// );
|
||||
// });
|
||||
//
|
||||
// expect_throw([&] {
|
||||
// fixture.create_component(
|
||||
// { .title = "", .resolution = { width, SurfaceComponent::max_dimension + 1 } }
|
||||
// );
|
||||
// });
|
||||
//
|
||||
// auto big_str = std::string {};
|
||||
// big_str.resize(SurfaceComponent::max_title_length + 1);
|
||||
// expect_throw([&] {
|
||||
// fixture.create_component({ .title = big_str, .resolution = { width, height } });
|
||||
// });
|
||||
// };
|
||||
//
|
||||
// Case { "unhappy on_construct<SurfaceComponent> removes component" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// auto system = System { fixture.registry() };
|
||||
//
|
||||
// expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
|
||||
// expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
|
||||
// };
|
||||
//
|
||||
// Case { "on_destrroy<SurfaceComponent> cleans up component" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// auto system = lt::memory::create_scope<System>(fixture.registry());
|
||||
//
|
||||
// const auto &component = fixture.create_component();
|
||||
// expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
|
||||
// fixture.check_values(*component);
|
||||
//
|
||||
// system.reset();
|
||||
// expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// Suite tick = "tick"_suite = [] {
|
||||
// Case { "ticking on empty registry won't throw" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// System { fixture.registry() }.tick(tick_info());
|
||||
// };
|
||||
//
|
||||
// Case { "ticking on non-empty registry won't throw" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// auto system = System { fixture.registry() };
|
||||
//
|
||||
// fixture.create_component();
|
||||
// system.tick(tick_info());
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// Suite tick_handles_events = "tick_handles_events"_suite = [] {
|
||||
// Case { "ticking clears previous tick's events" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// auto system = System { fixture.registry() };
|
||||
// auto &surface = **fixture.create_component();
|
||||
//
|
||||
// // flush window-creation events
|
||||
// system.tick(tick_info());
|
||||
// expect_eq(surface.peek_events().size(), 0);
|
||||
//
|
||||
// surface.push_event(lt::surface::MovedEvent({}, {}));
|
||||
// expect_eq(surface.peek_events().size(), 1);
|
||||
//
|
||||
// surface.push_event(lt::surface::ButtonPressedEvent({}));
|
||||
// expect_eq(surface.peek_events().size(), 2);
|
||||
//
|
||||
// system.tick(tick_info());
|
||||
// expect_eq(surface.peek_events().size(), 0);
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// Suite tick_handles_requests = "tick_handles_requests"_suite = [] {
|
||||
// Case { "ticking clears requests" } = [] {
|
||||
// auto fixture = Fixture {};
|
||||
// auto system = System { fixture.registry() };
|
||||
// auto &surface = **fixture.create_component();
|
||||
//
|
||||
// constexpr auto title = "ABC";
|
||||
// constexpr auto position = lt::math::ivec2 { 50, 50 };
|
||||
// constexpr auto resolution = lt::math::uvec2 { 50, 50 };
|
||||
//
|
||||
// expect_eq(surface.peek_requests().size(), 0);
|
||||
//
|
||||
// surface.push_request(lt::surface::ModifyVisibilityRequest(true));
|
||||
// expect_eq(surface.peek_requests().size(), 1);
|
||||
// system.tick(tick_info());
|
||||
// expect_eq(surface.peek_requests().size(), 0);
|
||||
//
|
||||
// surface.push_request(lt::surface::ModifyTitleRequest(title));
|
||||
// expect_eq(surface.peek_requests().size(), 1);
|
||||
//
|
||||
// surface.push_request(lt::surface::ModifyResolutionRequest(resolution));
|
||||
// surface.push_request(lt::surface::ModifyPositionRequest(position));
|
||||
// expect_eq(surface.peek_requests().size(), 1 + 2);
|
||||
//
|
||||
// surface.push_request(lt::surface::ModifyVisibilityRequest(false));
|
||||
// surface.push_request(lt::surface::ModifyVisibilityRequest(true));
|
||||
// surface.push_request(lt::surface::ModifyVisibilityRequest(false));
|
||||
// expect_eq(surface.peek_requests().size(), 1 + 2 + 3);
|
||||
//
|
||||
// system.tick(tick_info());
|
||||
// expect_eq(surface.peek_requests().size(), 0);
|
||||
//
|
||||
// expect_eq(surface.get_title(), title);
|
||||
// expect_eq(surface.get_position(), position);
|
||||
// expect_eq(surface.get_resolution(), resolution);
|
||||
//
|
||||
// lt::log::debug("EVENT COUNT: {}", surface.peek_events().size());
|
||||
// for (const auto &event : surface.peek_events())
|
||||
// {
|
||||
// const auto visitor = overloads {
|
||||
// [&](auto event) { lt::log::debug("event: {}", event.to_string()); },
|
||||
// };
|
||||
//
|
||||
// std::visit(visitor, event);
|
||||
// }
|
||||
// };
|
||||
// };
|
||||
Suite system_events = "system_events"_suite = [] {
|
||||
Case { "on_register won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
|
||||
system.on_register();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().get_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>().get_size(), 0);
|
||||
};
|
||||
};
|
||||
|
||||
Suite registry_events = "registry_events"_suite = [] {
|
||||
Case { "on_construct<SurfaceComponent> initializes component" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
|
||||
const auto &component = fixture.create_component();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
|
||||
fixture.check_values(*component);
|
||||
};
|
||||
|
||||
Case { "unhappy on_construct<SurfaceComponent> throws" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
|
||||
expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
|
||||
|
||||
expect_throw([&] { fixture.create_component({ .resolution = { 0, height } }); });
|
||||
|
||||
expect_throw([&] {
|
||||
fixture.create_component(
|
||||
{ .title = "", .resolution = { SurfaceComponent::max_dimension + 1, height } }
|
||||
);
|
||||
});
|
||||
|
||||
expect_throw([&] {
|
||||
fixture.create_component(
|
||||
{ .title = "", .resolution = { width, SurfaceComponent::max_dimension + 1 } }
|
||||
);
|
||||
});
|
||||
|
||||
auto big_str = std::string {};
|
||||
big_str.resize(SurfaceComponent::max_title_length + 1);
|
||||
expect_throw([&] {
|
||||
fixture.create_component({ .title = big_str, .resolution = { width, height } });
|
||||
});
|
||||
};
|
||||
|
||||
Case { "unhappy on_construct<SurfaceComponent> removes component" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
|
||||
expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
|
||||
};
|
||||
|
||||
Case { "on_destrroy<SurfaceComponent> cleans up component" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = lt::memory::create_scope<System>(fixture.registry());
|
||||
|
||||
const auto &component = fixture.create_component();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
|
||||
fixture.check_values(*component);
|
||||
|
||||
system.reset();
|
||||
expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
|
||||
};
|
||||
};
|
||||
|
||||
Suite tick = "tick"_suite = [] {
|
||||
Case { "ticking on empty registry won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
System { fixture.registry() }.tick(tick_info());
|
||||
};
|
||||
|
||||
Case { "ticking on non-empty registry won't throw" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
|
||||
fixture.create_component();
|
||||
system.tick(tick_info());
|
||||
};
|
||||
};
|
||||
|
||||
Suite tick_handles_events = "tick_handles_events"_suite = [] {
|
||||
Case { "ticking clears previous tick's events" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
auto &surface = **fixture.create_component();
|
||||
|
||||
// flush window-creation events
|
||||
system.tick(tick_info());
|
||||
expect_eq(surface.peek_events().size(), 0);
|
||||
|
||||
surface.push_event(lt::surface::MovedEvent({}, {}));
|
||||
expect_eq(surface.peek_events().size(), 1);
|
||||
|
||||
surface.push_event(lt::surface::ButtonPressedEvent({}));
|
||||
expect_eq(surface.peek_events().size(), 2);
|
||||
|
||||
system.tick(tick_info());
|
||||
expect_eq(surface.peek_events().size(), 0);
|
||||
};
|
||||
};
|
||||
|
||||
Suite tick_handles_requests = "tick_handles_requests"_suite = [] {
|
||||
Case { "ticking clears requests" } = [] {
|
||||
auto fixture = Fixture {};
|
||||
auto system = System { fixture.registry() };
|
||||
auto &surface = **fixture.create_component();
|
||||
|
||||
constexpr auto position = lt::math::ivec2 { 50, 50 };
|
||||
constexpr auto resolution = lt::math::uvec2 { width, height };
|
||||
|
||||
expect_eq(surface.peek_requests().size(), 0);
|
||||
|
||||
surface.push_request(lt::surface::ModifyVisibilityRequest(true));
|
||||
expect_eq(surface.peek_requests().size(), 1);
|
||||
system.tick(tick_info());
|
||||
expect_eq(surface.peek_requests().size(), 0);
|
||||
|
||||
surface.push_request(lt::surface::ModifyTitleRequest(title));
|
||||
expect_eq(surface.peek_requests().size(), 1);
|
||||
|
||||
surface.push_request(lt::surface::ModifyResolutionRequest(resolution));
|
||||
surface.push_request(lt::surface::ModifyPositionRequest(position));
|
||||
expect_eq(surface.peek_requests().size(), 1 + 2);
|
||||
|
||||
surface.push_request(lt::surface::ModifyVisibilityRequest(false));
|
||||
surface.push_request(lt::surface::ModifyVisibilityRequest(true));
|
||||
surface.push_request(lt::surface::ModifyVisibilityRequest(false));
|
||||
expect_eq(surface.peek_requests().size(), 1 + 2 + 3);
|
||||
|
||||
system.tick(tick_info());
|
||||
expect_eq(surface.peek_requests().size(), 0);
|
||||
|
||||
expect_eq(surface.get_title(), title);
|
||||
expect_eq(surface.get_position(), position);
|
||||
expect_eq(surface.get_resolution(), resolution);
|
||||
|
||||
lt::log::debug("EVENT COUNT: {}", surface.peek_events().size());
|
||||
for (const auto &event : surface.peek_events())
|
||||
{
|
||||
const auto visitor = overloads {
|
||||
[&](auto event) { lt::log::debug("event: {}", event.to_string()); },
|
||||
};
|
||||
|
||||
std::visit(visitor, event);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import logger;
|
|||
import test.test;
|
||||
import test.registry;
|
||||
|
||||
import std;
|
||||
import preliminary;
|
||||
|
||||
using namespace ::lt::test;
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ void print_help()
|
|||
std::println("--help | -h --> ~You just used it! :D");
|
||||
}
|
||||
|
||||
auto main(std::int32_t argc, char **argv) -> std::int32_t
|
||||
auto main(i32 argc, char **argv) -> i32
|
||||
try
|
||||
{
|
||||
auto raw_arguments = std::span<char *>(argv, argc);
|
||||
|
|
@ -83,7 +83,7 @@ try
|
|||
}
|
||||
}
|
||||
|
||||
return static_cast<std::int32_t>(Registry::run_all(options));
|
||||
return static_cast<i32>(Registry::run_all(options));
|
||||
}
|
||||
catch (const std::exception &exp)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
export module test.expects;
|
||||
|
||||
import std;
|
||||
|
||||
import preliminary;
|
||||
|
||||
namespace lt::test {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export module test.registry;
|
||||
|
||||
import std;
|
||||
import preliminary;
|
||||
import test.expects;
|
||||
|
||||
///////////////////////////////////////
|
||||
|
|
@ -11,7 +11,7 @@ namespace lt::test {
|
|||
export class Registry
|
||||
{
|
||||
public:
|
||||
enum class ExecutionPolicy : std::uint8_t
|
||||
enum class ExecutionPolicy : u8
|
||||
{
|
||||
normal,
|
||||
stats,
|
||||
|
|
@ -28,7 +28,7 @@ public:
|
|||
std::string case_regex;
|
||||
};
|
||||
|
||||
using FuzzFunction = std::int32_t (*)(const std::uint8_t *, std::size_t);
|
||||
using FuzzFunction = i32 (*)(const u8 *, size_t);
|
||||
|
||||
using SuiteFunction = void (*)();
|
||||
|
||||
|
|
@ -36,9 +36,9 @@ public:
|
|||
|
||||
static void register_fuzz_harness(FuzzFunction suite);
|
||||
|
||||
static auto run_all(Options options) -> std::int32_t;
|
||||
static auto run_all(Options options) -> i32;
|
||||
|
||||
static auto process_fuzz_input(const std::uint8_t *data, std::size_t size) -> std::int32_t;
|
||||
static auto process_fuzz_input(const u8 *data, size_t size) -> i32;
|
||||
|
||||
static void set_last_suite_name(const char *name);
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ private:
|
|||
|
||||
[[nodiscard]] static auto instance() -> Registry &;
|
||||
|
||||
auto run_all_impl() -> std::int32_t;
|
||||
auto run_all_impl() -> i32;
|
||||
|
||||
void print_options();
|
||||
|
||||
|
|
@ -83,25 +83,25 @@ private:
|
|||
|
||||
FuzzFunction m_fuzz_harness {};
|
||||
|
||||
std::int32_t m_total_case_count {};
|
||||
i32 m_total_case_count {};
|
||||
|
||||
std::int32_t m_passed_case_count {};
|
||||
i32 m_passed_case_count {};
|
||||
|
||||
std::int32_t m_failed_case_count {};
|
||||
i32 m_failed_case_count {};
|
||||
|
||||
std::int32_t m_matched_case_count {};
|
||||
i32 m_matched_case_count {};
|
||||
|
||||
std::int32_t m_skipped_case_count {};
|
||||
i32 m_skipped_case_count {};
|
||||
|
||||
std::int32_t m_total_suite_count {};
|
||||
i32 m_total_suite_count {};
|
||||
|
||||
std::int32_t m_passed_suite_count {};
|
||||
i32 m_passed_suite_count {};
|
||||
|
||||
std::int32_t m_failed_suite_count {};
|
||||
i32 m_failed_suite_count {};
|
||||
|
||||
std::int32_t m_matched_suite_count {};
|
||||
i32 m_matched_suite_count {};
|
||||
|
||||
std::int32_t m_skipped_suite_count {};
|
||||
i32 m_skipped_suite_count {};
|
||||
|
||||
std::regex m_case_regex;
|
||||
};
|
||||
|
|
@ -131,14 +131,13 @@ namespace lt::test {
|
|||
instance().m_fuzz_harness = suite;
|
||||
}
|
||||
|
||||
/* static */ auto Registry::run_all(Options options) -> std::int32_t
|
||||
/* static */ auto Registry::run_all(Options options) -> i32
|
||||
{
|
||||
instance().m_options = std::move(options);
|
||||
return instance().run_all_impl();
|
||||
}
|
||||
|
||||
/* static */ auto Registry::process_fuzz_input(const std::uint8_t *data, std::size_t size)
|
||||
-> std::int32_t
|
||||
/* static */ auto Registry::process_fuzz_input(const u8 *data, size_t size) -> i32
|
||||
{
|
||||
if (!instance().m_fuzz_harness)
|
||||
{
|
||||
|
|
@ -220,7 +219,7 @@ namespace lt::test {
|
|||
return instance().m_case_regex;
|
||||
}
|
||||
|
||||
auto Registry::run_all_impl() -> std::int32_t
|
||||
auto Registry::run_all_impl() -> i32
|
||||
{
|
||||
print_options();
|
||||
m_case_regex = std::regex(m_options.case_regex);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
export module test.test;
|
||||
|
||||
import std;
|
||||
import test.expects;
|
||||
import test.registry;
|
||||
import preliminary;
|
||||
|
||||
///////////////////////////////////////
|
||||
// ----------* INTERFACE *--------- //
|
||||
|
|
@ -38,7 +38,7 @@ struct TestFuzzHarness
|
|||
export using Case = const TestCase;
|
||||
export using Suite = const TestSuite;
|
||||
export using FuzzHarness = const TestFuzzHarness;
|
||||
export auto operator""_suite(const char *name, std::size_t size) -> TestSuite;
|
||||
export auto operator""_suite(const char *name, size_t size) -> TestSuite;
|
||||
|
||||
///////////////////////////////////////
|
||||
// * IMPLEMENTATION -- TEMPLATES * //
|
||||
|
|
@ -106,10 +106,10 @@ constexpr TestFuzzHarness::TestFuzzHarness(auto body)
|
|||
#endif
|
||||
};
|
||||
|
||||
auto operator""_suite(const char *name, std::size_t size) -> TestSuite
|
||||
auto operator""_suite(const char *name, size_t size) -> TestSuite
|
||||
{
|
||||
// TODO(Light): do we need the size parameter?
|
||||
std::ignore = size;
|
||||
ignore = size;
|
||||
|
||||
Registry::set_last_suite_name(name);
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import preliminary;
|
||||
import test.test;
|
||||
import test.expects;
|
||||
|
||||
import std;
|
||||
|
||||
using lt::test::Case;
|
||||
using lt::test::Suite;
|
||||
using lt::test::operator""_suite;
|
||||
|
|
@ -69,7 +68,7 @@ Suite expects = "expects"_suite = []() {
|
|||
};
|
||||
|
||||
Case { "expect_false - unhappy" } = [] {
|
||||
auto *oonga_oonga_can_rest_now = (std::uint32_t *)nullptr;
|
||||
auto *oonga_oonga_can_rest_now = (u32 *)nullptr;
|
||||
auto unhappy_counter = 0u;
|
||||
oonga_oonga_can_rest_now = &unhappy_counter;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
export module time;
|
||||
import std;
|
||||
|
||||
namespace lt::time {
|
||||
import preliminary;
|
||||
|
||||
export namespace lt::time {
|
||||
|
||||
/** Simple timer class to keep track of the elapsed time. */
|
||||
export class Timer
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
using Clock = std::chrono::steady_clock;
|
||||
|
||||
using Duration = std::chrono::duration<double>;
|
||||
using Duration = std::chrono::duration<f64>;
|
||||
|
||||
using Timepoint = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import preliminary;
|
||||
import time;
|
||||
import test.test;
|
||||
import test.expects;
|
||||
import std;
|
||||
|
||||
using ::lt::test::Case;
|
||||
using ::lt::test::expect_le;
|
||||
|
|
@ -28,7 +28,7 @@ Suite raii = "raii"_suite = [] {
|
|||
Case { "plenty" } = [] {
|
||||
for (auto idx : std::views::iota(0, 100'001))
|
||||
{
|
||||
std::ignore = idx;
|
||||
ignore = idx;
|
||||
Timer {};
|
||||
}
|
||||
};
|
||||
|
|
@ -40,7 +40,7 @@ Suite reset_and_elapsed_time = "reset_and_elapsed_time"_suite = [] {
|
|||
|
||||
Case { "won't throw" } = [] {
|
||||
Timer {}.reset();
|
||||
std::ignore = Timer {}.elapsed_time();
|
||||
ignore = Timer {}.elapsed_time();
|
||||
};
|
||||
|
||||
Case { "elapsed time is sane" } = [] {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue