This commit is contained in:
parent
72662f3742
commit
19187aa1d6
34 changed files with 487 additions and 534 deletions
|
|
@ -12,12 +12,25 @@ add_module(
|
||||||
hash.cppm
|
hash.cppm
|
||||||
utils.cppm
|
utils.cppm
|
||||||
scope.cppm
|
scope.cppm
|
||||||
bitwise.cppm
|
chrono.cppm
|
||||||
thread.cppm
|
thread.cppm
|
||||||
|
bitwise.cppm
|
||||||
|
concepts.cppm
|
||||||
|
algorithm.cppm
|
||||||
|
filesystem.cppm
|
||||||
primitives.cppm
|
primitives.cppm
|
||||||
|
exceptions.cppm
|
||||||
src_location.cppm
|
src_location.cppm
|
||||||
|
math/algebra.cppm
|
||||||
|
math/trig.cppm
|
||||||
|
math/vec2.cppm
|
||||||
|
math/vec3.cppm
|
||||||
|
math/vec4.cppm
|
||||||
|
math/mat4.cppm
|
||||||
)
|
)
|
||||||
|
|
||||||
add_module(NAME logger INTERFACES logger.cppm DEPENDENCIES lsd)
|
add_module(NAME logger INTERFACES logger.cppm DEPENDENCIES lsd)
|
||||||
|
|
||||||
add_module(
|
add_module(
|
||||||
NAME
|
NAME
|
||||||
test
|
test
|
||||||
|
|
@ -31,10 +44,9 @@ add_module(
|
||||||
lsd
|
lsd
|
||||||
logger
|
logger
|
||||||
)
|
)
|
||||||
return()
|
add_module(NAME env INTERFACES constants.cppm DEPENDENCIES lsd)
|
||||||
add_module(NAME env INTERFACES constants.cppm)
|
# add_module(NAME memory INTERFACES reference.cppm scope.cppm)
|
||||||
add_module(NAME memory INTERFACES null_on_move.cppm reference.cppm scope.cppm)
|
add_module(NAME time INTERFACES timer.cppm DEPENDENCIES lsd)
|
||||||
add_module(NAME time INTERFACES timer.cppm)
|
|
||||||
|
|
||||||
add_module(
|
add_module(
|
||||||
NAME
|
NAME
|
||||||
|
|
@ -42,23 +54,10 @@ add_module(
|
||||||
ROOT_DIR
|
ROOT_DIR
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/debug
|
${CMAKE_CURRENT_SOURCE_DIR}/debug
|
||||||
INTERFACES
|
INTERFACES
|
||||||
instrumentor.cppm
|
|
||||||
assertions.cppm
|
assertions.cppm
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
logger
|
logger
|
||||||
)
|
lsd
|
||||||
|
|
||||||
add_module(
|
|
||||||
NAME
|
|
||||||
math
|
|
||||||
INTERFACES
|
|
||||||
algebra.cppm
|
|
||||||
mat4.cppm
|
|
||||||
trig.cppm
|
|
||||||
vec2.cppm
|
|
||||||
vec3.cppm
|
|
||||||
vec4.cppm
|
|
||||||
components.cppm
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_module(
|
add_module(
|
||||||
|
|
@ -80,6 +79,7 @@ add_module(
|
||||||
INTERFACES
|
INTERFACES
|
||||||
bakers.cppm
|
bakers.cppm
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
lsd
|
||||||
assets
|
assets
|
||||||
logger
|
logger
|
||||||
lt_debug
|
lt_debug
|
||||||
|
|
@ -88,7 +88,15 @@ add_module(
|
||||||
# add_executable(asset_baker entrypoint.cpp) target_link_libraries(asset_baker
|
# add_executable(asset_baker entrypoint.cpp) target_link_libraries(asset_baker
|
||||||
# PRIVATE libasset_baker)
|
# PRIVATE libasset_baker)
|
||||||
|
|
||||||
add_module(NAME camera INTERFACES components.cppm DEPENDENCIES math)
|
add_module(
|
||||||
|
NAME
|
||||||
|
camera
|
||||||
|
INTERFACES
|
||||||
|
components.cppm
|
||||||
|
DEPENDENCIES
|
||||||
|
math
|
||||||
|
lsd
|
||||||
|
)
|
||||||
|
|
||||||
add_module(
|
add_module(
|
||||||
NAME
|
NAME
|
||||||
|
|
@ -96,10 +104,9 @@ add_module(
|
||||||
INTERFACES
|
INTERFACES
|
||||||
application.cppm
|
application.cppm
|
||||||
system.cppm
|
system.cppm
|
||||||
DEPENDENCIES
|
|
||||||
memory
|
|
||||||
PRIVATE_DEPENDENCIES
|
PRIVATE_DEPENDENCIES
|
||||||
lt_debug
|
lt_debug
|
||||||
|
lsd
|
||||||
)
|
)
|
||||||
|
|
||||||
add_module(
|
add_module(
|
||||||
|
|
@ -112,9 +119,11 @@ add_module(
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
logger
|
logger
|
||||||
lt_debug
|
lt_debug
|
||||||
memory
|
lsd
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_module(
|
add_module(
|
||||||
NAME
|
NAME
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
export module app;
|
export module app;
|
||||||
import app.system;
|
import app.system;
|
||||||
import memory.reference;
|
import lsd;
|
||||||
import memory.scope;
|
|
||||||
import std;
|
|
||||||
|
|
||||||
namespace lt::app {
|
namespace lt::app {
|
||||||
|
|
||||||
|
|
@ -25,19 +23,19 @@ public:
|
||||||
|
|
||||||
void game_loop();
|
void game_loop();
|
||||||
|
|
||||||
void register_system(memory::Ref<app::ISystem> system);
|
void register_system(lsd::ref<app::ISystem> system);
|
||||||
|
|
||||||
void unregister_system(memory::Ref<app::ISystem> system);
|
void unregister_system(lsd::ref<app::ISystem> system);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Application() = default;
|
Application() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<memory::Ref<app::ISystem>> m_systems;
|
lsd::vec<lsd::ref<app::ISystem>> m_systems;
|
||||||
|
|
||||||
std::vector<memory::Ref<app::ISystem>> m_systems_to_be_unregistered;
|
lsd::vec<lsd::ref<app::ISystem>> m_systems_to_be_unregistered;
|
||||||
|
|
||||||
std::vector<memory::Ref<app::ISystem>> m_systems_to_be_registered;
|
lsd::vec<lsd::ref<app::ISystem>> m_systems_to_be_registered;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lt::app
|
} // namespace lt::app
|
||||||
|
|
@ -52,11 +50,11 @@ void Application::game_loop()
|
||||||
for (auto &system : m_systems)
|
for (auto &system : m_systems)
|
||||||
{
|
{
|
||||||
const auto &last_tick = system->get_last_tick_result();
|
const auto &last_tick = system->get_last_tick_result();
|
||||||
const auto now = std::chrono::steady_clock::now();
|
const auto now = lsd::chrono::steady_clock::now();
|
||||||
|
|
||||||
system->tick(TickInfo {
|
system->tick(TickInfo {
|
||||||
.delta_time = now - last_tick.end_time,
|
.delta_time = now - last_tick.end_time,
|
||||||
.budget = std::chrono::milliseconds { 10 },
|
.budget = lsd::chrono::milliseconds { 10 },
|
||||||
.start_time = now,
|
.start_time = now,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +67,7 @@ void Application::game_loop()
|
||||||
for (auto &system : m_systems_to_be_unregistered)
|
for (auto &system : m_systems_to_be_unregistered)
|
||||||
{
|
{
|
||||||
m_systems.erase(
|
m_systems.erase(
|
||||||
std::remove(m_systems.begin(), m_systems.end(), system),
|
lsd::remove(m_systems.begin(), m_systems.end(), system),
|
||||||
m_systems.end()
|
m_systems.end()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -81,14 +79,14 @@ void Application::game_loop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::register_system(memory::Ref<app::ISystem> system)
|
void Application::register_system(lsd::ref<app::ISystem> system)
|
||||||
{
|
{
|
||||||
m_systems.emplace_back(std::move(system));
|
m_systems.emplace_back(lsd::move(system));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::unregister_system(memory::Ref<app::ISystem> system)
|
void Application::unregister_system(lsd::ref<app::ISystem> system)
|
||||||
{
|
{
|
||||||
m_systems_to_be_unregistered.emplace_back(std::move(system));
|
m_systems_to_be_unregistered.emplace_back(lsd::move(system));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lt::app
|
} // namespace lt::app
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
export module app.system;
|
export module app.system;
|
||||||
import logger;
|
import logger;
|
||||||
import std;
|
import lsd;
|
||||||
|
|
||||||
namespace lt::app {
|
namespace lt::app {
|
||||||
|
|
||||||
|
|
@ -9,9 +9,9 @@ namespace lt::app {
|
||||||
*/
|
*/
|
||||||
export struct TickInfo
|
export struct TickInfo
|
||||||
{
|
{
|
||||||
using Timepoint_T = std::chrono::time_point<std::chrono::steady_clock>;
|
using Timepoint_T = lsd::chrono::time_point<lsd::chrono::steady_clock>;
|
||||||
|
|
||||||
using Duration_T = std::chrono::duration<double>;
|
using Duration_T = lsd::chrono::duration<f64>;
|
||||||
|
|
||||||
/** Duration since previous tick's end_time to current tick's start_time. */
|
/** Duration since previous tick's end_time to current tick's start_time. */
|
||||||
Duration_T delta_time {};
|
Duration_T delta_time {};
|
||||||
|
|
@ -32,9 +32,9 @@ export struct TickInfo
|
||||||
/** Information about how a system's tick performed */
|
/** Information about how a system's tick performed */
|
||||||
export struct TickResult
|
export struct TickResult
|
||||||
{
|
{
|
||||||
using Timepoint_T = std::chrono::time_point<std::chrono::steady_clock>;
|
using Timepoint_T = lsd::chrono::time_point<lsd::chrono::steady_clock>;
|
||||||
|
|
||||||
using Duration_T = std::chrono::duration<double>;
|
using Duration_T = lsd::chrono::duration<f64>;
|
||||||
|
|
||||||
/** The info supplied to the system for ticking. */
|
/** The info supplied to the system for ticking. */
|
||||||
TickInfo info;
|
TickInfo info;
|
||||||
|
|
@ -48,7 +48,7 @@ export struct TickResult
|
||||||
|
|
||||||
export struct SystemDiagnosis
|
export struct SystemDiagnosis
|
||||||
{
|
{
|
||||||
enum class Severity : std::uint8_t
|
enum class Severity : u8
|
||||||
{
|
{
|
||||||
verbose,
|
verbose,
|
||||||
info,
|
info,
|
||||||
|
|
@ -57,9 +57,9 @@ export struct SystemDiagnosis
|
||||||
fatal,
|
fatal,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string message;
|
lsd::str message;
|
||||||
|
|
||||||
std::string code;
|
lsd::str code;
|
||||||
|
|
||||||
Severity severity;
|
Severity severity;
|
||||||
};
|
};
|
||||||
|
|
@ -69,9 +69,9 @@ export class SystemStats
|
||||||
public:
|
public:
|
||||||
void push_diagnosis(SystemDiagnosis &&diagnosis)
|
void push_diagnosis(SystemDiagnosis &&diagnosis)
|
||||||
{
|
{
|
||||||
auto &diag = m_diagnosis.emplace_back(std::move(diagnosis));
|
auto &diag = m_diagnosis.emplace_back(lsd::move(diagnosis));
|
||||||
|
|
||||||
log::info("message: {}", std::string { diag.message });
|
log::info("message: {}", lsd::str { diag.message });
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto empty_diagnosis() const -> bool
|
[[nodiscard]] auto empty_diagnosis() const -> bool
|
||||||
|
|
@ -80,7 +80,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<SystemDiagnosis> m_diagnosis;
|
lsd::vec<SystemDiagnosis> m_diagnosis;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class ISystem
|
export class ISystem
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,33 @@
|
||||||
export module bakers;
|
export module bakers;
|
||||||
|
|
||||||
import debug.assertions;
|
import debug.assertions;
|
||||||
import assets.metadata;
|
import assets.metadata;
|
||||||
import assets.shader;
|
import assets.shader;
|
||||||
import logger;
|
import logger;
|
||||||
import std;
|
import lsd;
|
||||||
|
|
||||||
|
namespace lt {
|
||||||
|
|
||||||
export void bake_shader(
|
export void bake_shader(
|
||||||
const std::filesystem::path &in_path,
|
const lsd::file::path &in_path,
|
||||||
const std::filesystem::path &out_path,
|
const lsd::file::path &out_path,
|
||||||
lt::assets::ShaderAsset::Type type
|
assets::ShaderAsset::Type type
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
using lt::assets::ShaderAsset;
|
using assets::ShaderAsset;
|
||||||
using enum lt::assets::ShaderAsset::Type;
|
using enum assets::ShaderAsset::Type;
|
||||||
|
|
||||||
auto glsl_path = std::string { in_path.string() };
|
auto glsl_path = lsd::str { in_path.string() };
|
||||||
auto spv_path = std::format("{}.spv", glsl_path);
|
auto spv_path = lsd::format("{}.spv", glsl_path);
|
||||||
lt::log::trace(
|
log::trace(
|
||||||
"Compiling {} shader {} -> {}",
|
"Compiling {} shader {} -> {}",
|
||||||
type == vertex ? "vertex" : "fragment",
|
type == vertex ? "vertex" : "fragment",
|
||||||
std::string { glsl_path },
|
lsd::str { glsl_path },
|
||||||
std::string { spv_path }
|
lsd::str { spv_path }
|
||||||
);
|
);
|
||||||
|
|
||||||
// Don't bother linking to shaderc, just invoke the command with a system call.
|
// Don't bother linking to shaderc, just invoke the command with a system call.
|
||||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
||||||
std::system(std::format(
|
lsd::system(lsd::format(
|
||||||
"glslc --target-env=vulkan1.4 -std=450core -fshader-stage={} {} -o {}",
|
"glslc --target-env=vulkan1.4 -std=450core -fshader-stage={} {} -o {}",
|
||||||
type == vertex ? "vert" : "frag",
|
type == vertex ? "vert" : "frag",
|
||||||
glsl_path,
|
glsl_path,
|
||||||
|
|
@ -34,33 +35,35 @@ export void bake_shader(
|
||||||
)
|
)
|
||||||
.c_str());
|
.c_str());
|
||||||
|
|
||||||
auto stream = std::ifstream(spv_path, std::ios::binary);
|
auto stream = lsd::file::in_stream(spv_path, lsd::file::ios_binary);
|
||||||
lt::debug::ensure(
|
debug::ensure(
|
||||||
stream.is_open(),
|
stream.is_open(),
|
||||||
"Failed to open compiled {} shader at: {}",
|
"Failed to open compiled {} shader at: {}",
|
||||||
type == vertex ? "vert" : "frag",
|
type == vertex ? "vert" : "frag",
|
||||||
spv_path
|
spv_path
|
||||||
);
|
);
|
||||||
|
|
||||||
stream.seekg(0, std::ios::end);
|
stream.seekg(0, lsd::file::ios_end);
|
||||||
const auto size = stream.tellg();
|
const auto size = stream.tellg();
|
||||||
|
|
||||||
auto bytes = std::vector<std::byte>(size);
|
auto bytes = lsd::vec<byte>(size);
|
||||||
stream.seekg(0, std::ios::beg);
|
stream.seekg(0, lsd::file::ios_beg);
|
||||||
stream.read((char *)bytes.data(), size); // NOLINT
|
stream.read((char *)bytes.data(), size); // NOLINT
|
||||||
lt::log::debug("BYTES: {}", bytes.size());
|
log::debug("BYTES: {}", bytes.size());
|
||||||
stream.close();
|
stream.close();
|
||||||
std::filesystem::remove(spv_path);
|
lsd::file::remove(spv_path);
|
||||||
|
|
||||||
ShaderAsset::pack(
|
ShaderAsset::pack(
|
||||||
out_path,
|
out_path,
|
||||||
lt::assets::AssetMetadata {
|
assets::AssetMetadata {
|
||||||
.version = lt::assets::current_version,
|
.version = assets::current_version,
|
||||||
.type = ShaderAsset::asset_type_identifier,
|
.type = ShaderAsset::asset_type_identifier,
|
||||||
},
|
},
|
||||||
ShaderAsset::Metadata {
|
ShaderAsset::Metadata {
|
||||||
.type = type,
|
.type = type,
|
||||||
},
|
},
|
||||||
std::move(bytes)
|
lsd::move(bytes)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace lt
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ export module assets.shader;
|
||||||
import assets.metadata;
|
import assets.metadata;
|
||||||
import debug.assertions;
|
import debug.assertions;
|
||||||
|
|
||||||
import std;
|
import lsd;
|
||||||
|
|
||||||
export namespace lt::assets {
|
export namespace lt::assets {
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ public:
|
||||||
code,
|
code,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Type : std::uint8_t
|
enum class Type : u8
|
||||||
{
|
{
|
||||||
vertex,
|
vertex,
|
||||||
fragment,
|
fragment,
|
||||||
|
|
@ -30,15 +30,15 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pack(
|
static void pack(
|
||||||
const std::filesystem::path &destination,
|
const lsd::file::path &destination,
|
||||||
AssetMetadata asset_metadata,
|
AssetMetadata asset_metadata,
|
||||||
Metadata metadata,
|
Metadata metadata,
|
||||||
Blob code_blob
|
Blob code_blob
|
||||||
);
|
);
|
||||||
|
|
||||||
ShaderAsset(const std::filesystem::path &path);
|
ShaderAsset(const lsd::file::path &path);
|
||||||
|
|
||||||
void unpack_to(BlobTag tag, std::span<std::byte> destination) const;
|
void unpack_to(BlobTag tag, lsd::span<byte> destination) const;
|
||||||
|
|
||||||
[[nodiscard]] auto unpack(BlobTag tag) const -> Blob;
|
[[nodiscard]] auto unpack(BlobTag tag) const -> Blob;
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ public:
|
||||||
debug::ensure(
|
debug::ensure(
|
||||||
tag == BlobTag::code,
|
tag == BlobTag::code,
|
||||||
"Invalid blob tag for shader asset: {}",
|
"Invalid blob tag for shader asset: {}",
|
||||||
std::to_underlying(tag)
|
lsd::to_underlying(tag)
|
||||||
);
|
);
|
||||||
|
|
||||||
return m_code_blob_metadata;
|
return m_code_blob_metadata;
|
||||||
|
|
@ -88,15 +88,15 @@ constexpr auto total_metadata_size = //
|
||||||
+ sizeof(BlobMetadata::compressed_size) //
|
+ sizeof(BlobMetadata::compressed_size) //
|
||||||
+ sizeof(BlobMetadata::uncompressed_size);
|
+ sizeof(BlobMetadata::uncompressed_size);
|
||||||
|
|
||||||
ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path)
|
ShaderAsset::ShaderAsset(const lsd::file::path &path): m_stream(path)
|
||||||
{
|
{
|
||||||
debug::ensure(m_stream.is_open(), "Failed to open shader asset at: {}", path.string());
|
debug::ensure(m_stream.is_open(), "Failed to open shader asset at: {}", path.string());
|
||||||
const auto read = [this](auto &field) {
|
const auto read = [this](auto &field) {
|
||||||
m_stream.read(std::bit_cast<char *>(&field), sizeof(field));
|
m_stream.read(bit_cast<char *>(&field), sizeof(field));
|
||||||
};
|
};
|
||||||
|
|
||||||
m_stream.seekg(0, std::ifstream::end);
|
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(
|
debug::ensure(
|
||||||
file_size > total_metadata_size,
|
file_size > total_metadata_size,
|
||||||
"Failed to open shader asset at: {}, file smaller than metadata: {} < {}",
|
"Failed to open shader asset at: {}, file smaller than metadata: {} < {}",
|
||||||
|
|
@ -132,14 +132,14 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path)
|
||||||
);
|
);
|
||||||
|
|
||||||
debug::ensure(
|
debug::ensure(
|
||||||
std::to_underlying(m_metadata.type) <= std::to_underlying(Type::compute),
|
lsd::to_underlying(m_metadata.type) <= std::to_underlying(Type::compute),
|
||||||
"Failed to open shader asset at: {}, invalid shader type: {}",
|
"Failed to open shader asset at: {}, invalid shader type: {}",
|
||||||
path.string(),
|
path.string(),
|
||||||
std::to_underlying(m_metadata.type)
|
lsd::to_underlying(m_metadata.type)
|
||||||
);
|
);
|
||||||
|
|
||||||
debug::ensure(
|
debug::ensure(
|
||||||
m_code_blob_metadata.tag == std::to_underlying(BlobTag::code),
|
m_code_blob_metadata.tag == lsd::to_underlying(BlobTag::code),
|
||||||
"Failed to open shader asset at: {}, invalid blob tag: {}",
|
"Failed to open shader asset at: {}, invalid blob tag: {}",
|
||||||
path.string(),
|
path.string(),
|
||||||
m_code_blob_metadata.tag
|
m_code_blob_metadata.tag
|
||||||
|
|
@ -156,7 +156,7 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ShaderAsset::pack(
|
/* static */ void ShaderAsset::pack(
|
||||||
const std::filesystem::path &destination,
|
const lsd::file::path &destination,
|
||||||
AssetMetadata asset_metadata,
|
AssetMetadata asset_metadata,
|
||||||
Metadata metadata,
|
Metadata metadata,
|
||||||
Blob code_blob
|
Blob code_blob
|
||||||
|
|
@ -168,7 +168,7 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path)
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto code_blob_metadata = BlobMetadata {
|
const auto code_blob_metadata = BlobMetadata {
|
||||||
.tag = std::to_underlying(BlobTag::code),
|
.tag = lsd::to_underlying(BlobTag::code),
|
||||||
.offset = total_metadata_size,
|
.offset = total_metadata_size,
|
||||||
.compression_type = CompressionType::none,
|
.compression_type = CompressionType::none,
|
||||||
.compressed_size = code_blob.size(),
|
.compressed_size = code_blob.size(),
|
||||||
|
|
@ -177,7 +177,7 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path)
|
||||||
|
|
||||||
debug::ensure(stream.is_open(), "Failed to pack shader asset to {}", destination.string());
|
debug::ensure(stream.is_open(), "Failed to pack shader asset to {}", destination.string());
|
||||||
const auto write = [&stream](auto &field) {
|
const auto write = [&stream](auto &field) {
|
||||||
stream.write(std::bit_cast<char *>(&field), sizeof(field));
|
stream.write(bit_cast<char *>(&field), sizeof(field));
|
||||||
};
|
};
|
||||||
write(asset_metadata.type);
|
write(asset_metadata.type);
|
||||||
write(asset_metadata.version);
|
write(asset_metadata.version);
|
||||||
|
|
@ -187,31 +187,31 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path)
|
||||||
write(code_blob_metadata.compression_type);
|
write(code_blob_metadata.compression_type);
|
||||||
write(code_blob_metadata.compressed_size);
|
write(code_blob_metadata.compressed_size);
|
||||||
write(code_blob_metadata.uncompressed_size);
|
write(code_blob_metadata.uncompressed_size);
|
||||||
stream.write(std::bit_cast<char *>(code_blob.data()), static_cast<long long>(code_blob.size()));
|
stream.write(bit_cast<char *>(code_blob.data()), static_cast<stream_size>(code_blob.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderAsset::unpack_to(BlobTag tag, std::span<std::byte> destination) const
|
void ShaderAsset::unpack_to(BlobTag tag, lsd::span<byte> destination) const
|
||||||
{
|
{
|
||||||
debug::ensure(
|
debug::ensure(
|
||||||
tag == BlobTag::code,
|
tag == BlobTag::code,
|
||||||
"Invalid blob tag for shader asset: {}",
|
"Invalid blob tag for shader asset: {}",
|
||||||
std::to_underlying(tag)
|
lsd::to_underlying(tag)
|
||||||
);
|
);
|
||||||
|
|
||||||
debug::ensure(
|
debug::ensure(
|
||||||
destination.size() >= m_code_blob_metadata.uncompressed_size,
|
destination.size() >= m_code_blob_metadata.uncompressed_size,
|
||||||
"Failed to unpack shader blob {} to destination ({}) of size {} since it's smaller "
|
"Failed to unpack shader blob {} to destination ({}) of size {} since it's smaller "
|
||||||
"than the blobl's uncompressed size: {}",
|
"than the blobl's uncompressed size: {}",
|
||||||
std::to_underlying(tag),
|
lsd::to_underlying(tag),
|
||||||
std::bit_cast<std::size_t>(destination.data()),
|
bit_cast<size_t>(destination.data()),
|
||||||
destination.size(),
|
destination.size(),
|
||||||
m_code_blob_metadata.uncompressed_size
|
m_code_blob_metadata.uncompressed_size
|
||||||
);
|
);
|
||||||
|
|
||||||
m_stream.seekg(static_cast<long long>(m_code_blob_metadata.offset));
|
m_stream.seekg(static_cast<stream_size>(m_code_blob_metadata.offset));
|
||||||
m_stream.read(
|
m_stream.read(
|
||||||
std::bit_cast<char *>(destination.data()),
|
bit_cast<char *>(destination.data()),
|
||||||
static_cast<long long>(m_code_blob_metadata.uncompressed_size)
|
static_cast<stream_size>(m_code_blob_metadata.uncompressed_size)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,7 +220,7 @@ void ShaderAsset::unpack_to(BlobTag tag, std::span<std::byte> destination) const
|
||||||
debug::ensure(
|
debug::ensure(
|
||||||
tag == BlobTag::code,
|
tag == BlobTag::code,
|
||||||
"Invalid blob tag for shader asset: {}",
|
"Invalid blob tag for shader asset: {}",
|
||||||
std::to_underlying(tag)
|
lsd::to_underlying(tag)
|
||||||
);
|
);
|
||||||
|
|
||||||
auto blob = Blob(m_code_blob_metadata.uncompressed_size);
|
auto blob = Blob(m_code_blob_metadata.uncompressed_size);
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
export module camera.components;
|
export module camera.components;
|
||||||
import math.vec4;
|
import lsd;
|
||||||
|
|
||||||
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;
|
lsd::vec4 background_color;
|
||||||
|
|
||||||
bool is_primary {};
|
bool is_primary {};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,36 @@
|
||||||
export module debug.assertions;
|
export module debug.assertions;
|
||||||
|
|
||||||
import std;
|
import lsd;
|
||||||
|
|
||||||
namespace lt::debug {
|
export namespace lt::debug {
|
||||||
|
|
||||||
///////////////////////////////////////
|
template<typename Expression_T, typename... Args_T>
|
||||||
// ----------* INTERFACE *--------- //
|
|
||||||
/////////////////////////////////////
|
|
||||||
export template<typename Expression_T, typename... Args_T>
|
|
||||||
struct ensure
|
struct ensure
|
||||||
{
|
{
|
||||||
ensure(
|
ensure(
|
||||||
const Expression_T &expression,
|
const Expression_T &expression,
|
||||||
std::format_string<Args_T...> fmt,
|
lsd::format_str<Args_T...> fmt,
|
||||||
Args_T &&...args,
|
Args_T &&...args,
|
||||||
const std::source_location &location = std::source_location::current()
|
const lsd::src_location &location = lsd::src_location::current()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export template<typename Expression_T, typename... Args_T>
|
template<typename Expression_T, typename... Args_T>
|
||||||
ensure(Expression_T, std::format_string<Args_T...>, Args_T &&...)
|
ensure(Expression_T, lsd::format_str<Args_T...>, Args_T &&...) -> ensure<Expression_T, Args_T...>;
|
||||||
-> ensure<Expression_T, Args_T...>;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
// * IMPLEMENTATION -- TEMPLATES * //
|
|
||||||
/////////////////////////////////////
|
|
||||||
template<typename Expression_T, typename... Args_T>
|
template<typename Expression_T, typename... Args_T>
|
||||||
ensure<Expression_T, Args_T...>::ensure(
|
ensure<Expression_T, Args_T...>::ensure(
|
||||||
const Expression_T &expression,
|
const Expression_T &expression,
|
||||||
std::format_string<Args_T...> fmt,
|
lsd::format_str<Args_T...> fmt,
|
||||||
Args_T &&...args,
|
Args_T &&...args,
|
||||||
const std::source_location &location
|
const lsd::src_location &location
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!static_cast<bool>(expression))
|
if (!static_cast<bool>(expression))
|
||||||
{
|
{
|
||||||
throw std::runtime_error { std::format(
|
throw lsd::runtime_error { lsd::format(
|
||||||
"exception: {}\nlocation: {}:{}",
|
"exception: {}\nlocation: {}:{}",
|
||||||
std::format(fmt, std::forward<Args_T>(args)...),
|
lsd::format(fmt, lsd::forward<Args_T>(args)...),
|
||||||
location.file_name(),
|
location.file_name(),
|
||||||
location.line()
|
location.line()
|
||||||
) };
|
) };
|
||||||
|
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
export module debug.instrumentor;
|
|
||||||
|
|
||||||
import std;
|
|
||||||
import logger;
|
|
||||||
|
|
||||||
namespace lt::debug {
|
|
||||||
|
|
||||||
struct ScopeProfileResult
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
long long start, duration;
|
|
||||||
std::uint32_t threadID;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Instrumentor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static auto instance() -> Instrumentor &
|
|
||||||
{
|
|
||||||
static auto instance = Instrumentor {};
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void begin_session(const std::string &outputPath)
|
|
||||||
{
|
|
||||||
instance().begin_session_impl(outputPath);
|
|
||||||
}
|
|
||||||
static void end_session()
|
|
||||||
{
|
|
||||||
instance().end_session_impl();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void submit_scope_profile(const ScopeProfileResult &profileResult)
|
|
||||||
{
|
|
||||||
instance().submit_scope_profile_impl(profileResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::ofstream m_output_file_stream;
|
|
||||||
|
|
||||||
unsigned int m_current_session_count { 0u };
|
|
||||||
|
|
||||||
Instrumentor() = default;
|
|
||||||
|
|
||||||
void begin_session_impl(const std::string &outputPath);
|
|
||||||
|
|
||||||
void end_session_impl();
|
|
||||||
|
|
||||||
void submit_scope_profile_impl(const ScopeProfileResult &profileResult);
|
|
||||||
};
|
|
||||||
|
|
||||||
class InstrumentorTimer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InstrumentorTimer(const std::string &scopeName);
|
|
||||||
|
|
||||||
~InstrumentorTimer();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ScopeProfileResult m_result;
|
|
||||||
|
|
||||||
std::chrono::time_point<std::chrono::steady_clock> m_start;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt::debug
|
|
||||||
|
|
||||||
/* scope */
|
|
||||||
#define lt_profile_scope(name) lt_profile_scope_no_redifinition(name, __LINE__)
|
|
||||||
#define lt_profile_scope_no_redifinition(name, line) lt_profile_scope_no_redifinition2(name, line)
|
|
||||||
#define lt_profile_scope_no_redifinition2(name, line) InstrumentorTimer timer##line(name)
|
|
||||||
|
|
||||||
/* function */
|
|
||||||
#define LT_PROFILE_FUNCTION lt_profile_scope(__FUNCSIG__)
|
|
||||||
|
|
||||||
/* session */
|
|
||||||
#define lt_profile_begin_session(outputPath) ::lt::Instrumentor::begin_session(outputPath)
|
|
||||||
#define lt_profile_end_session() ::lt::Instrumentor::end_session()
|
|
||||||
|
|
||||||
module :private;
|
|
||||||
namespace lt::debug {
|
|
||||||
|
|
||||||
void Instrumentor::begin_session_impl(const std::string &outputPath)
|
|
||||||
{
|
|
||||||
std::filesystem::create_directory(outputPath.substr(0, outputPath.find_last_of('/') + 1));
|
|
||||||
|
|
||||||
m_output_file_stream.open(outputPath);
|
|
||||||
m_output_file_stream << "{\"traceEvents\":[";
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instrumentor::end_session_impl()
|
|
||||||
{
|
|
||||||
if (m_current_session_count == 0u)
|
|
||||||
{
|
|
||||||
log::warn("0 profiling for the ended session");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_current_session_count = 0u;
|
|
||||||
|
|
||||||
m_output_file_stream << "]}";
|
|
||||||
m_output_file_stream.flush();
|
|
||||||
m_output_file_stream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instrumentor::submit_scope_profile_impl(const ScopeProfileResult &profileResult)
|
|
||||||
{
|
|
||||||
if (m_current_session_count++ == 0u)
|
|
||||||
{
|
|
||||||
m_output_file_stream << "{";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_output_file_stream << ",{";
|
|
||||||
}
|
|
||||||
|
|
||||||
m_output_file_stream << R"("name":")" << profileResult.name << "\",";
|
|
||||||
m_output_file_stream << R"("cat": "scope",)";
|
|
||||||
m_output_file_stream << R"("ph": "X",)";
|
|
||||||
m_output_file_stream << "\"ts\":" << profileResult.start << ",";
|
|
||||||
m_output_file_stream << "\"dur\":" << profileResult.duration << ",";
|
|
||||||
m_output_file_stream << "\"pid\":0,";
|
|
||||||
m_output_file_stream << "\"tid\":" << profileResult.threadID << "";
|
|
||||||
m_output_file_stream << "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
InstrumentorTimer::InstrumentorTimer(const std::string &scopeName)
|
|
||||||
: m_result({ .name = scopeName, .start = 0, .duration = 0, .threadID = 0 })
|
|
||||||
, m_start(std::chrono::steady_clock::now())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InstrumentorTimer::~InstrumentorTimer()
|
|
||||||
{
|
|
||||||
auto end = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
m_result.start = std::chrono::time_point_cast<std::chrono::microseconds>(m_start)
|
|
||||||
.time_since_epoch()
|
|
||||||
.count();
|
|
||||||
|
|
||||||
m_result.duration = std::chrono::time_point_cast<std::chrono::microseconds>(end)
|
|
||||||
.time_since_epoch()
|
|
||||||
.count()
|
|
||||||
- m_result.start;
|
|
||||||
|
|
||||||
Instrumentor::submit_scope_profile(m_result);
|
|
||||||
}
|
|
||||||
} // namespace lt::debug
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
export module ecs.sparse_set;
|
export module ecs.sparse_set;
|
||||||
import debug.assertions;
|
import debug.assertions;
|
||||||
import std;
|
import lsd;
|
||||||
|
|
||||||
namespace lt::ecs {
|
export namespace lt::ecs {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ref https://programmingpraxis.com/2012/03/09/sparse-sets/
|
* @ref https://programmingpraxis.com/2012/03/09/sparse-sets/
|
||||||
*/
|
*/
|
||||||
export template<typename Identifier_T = std::uint32_t>
|
template<typename Identifier_T = u32>
|
||||||
class TypeErasedSparseSet
|
class TypeErasedSparseSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -26,17 +26,17 @@ public:
|
||||||
virtual void remove(Identifier_T identifier) = 0;
|
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>
|
class SparseSet: public TypeErasedSparseSet<Identifier_T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Dense_T = std::pair<Identifier_T, Value_T>;
|
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();
|
static constexpr auto null_identifier = lsd::numeric_limits<Identifier_T>().max();
|
||||||
|
|
||||||
explicit SparseSet(std::size_t initial_capacity = 1)
|
explicit SparseSet(size_t initial_capacity = 1)
|
||||||
{
|
{
|
||||||
debug::ensure(
|
debug::ensure(
|
||||||
initial_capacity <= max_capacity,
|
initial_capacity <= max_capacity,
|
||||||
|
|
@ -53,10 +53,7 @@ public:
|
||||||
{
|
{
|
||||||
if (m_sparse.size() < identifier + 1)
|
if (m_sparse.size() < identifier + 1)
|
||||||
{
|
{
|
||||||
auto new_capacity = std::max(
|
auto new_capacity = std::max(static_cast<size_t>(identifier + 1), m_sparse.size() * 2);
|
||||||
static_cast<std::size_t>(identifier + 1),
|
|
||||||
m_sparse.size() * 2
|
|
||||||
);
|
|
||||||
new_capacity = std::min(new_capacity, max_capacity);
|
new_capacity = std::min(new_capacity, max_capacity);
|
||||||
|
|
||||||
// log::debug("Increasing sparse vector size:", m_dead_count);
|
// log::debug("Increasing sparse vector size:", m_dead_count);
|
||||||
|
|
@ -122,12 +119,12 @@ public:
|
||||||
&& m_dense[m_sparse[identifier]].first == identifier;
|
&& m_dense[m_sparse[identifier]].first == identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto begin() -> std::vector<Dense_T>::iterator
|
auto begin() -> lsd::vector<Dense_T>::iterator
|
||||||
{
|
{
|
||||||
return m_dense.begin();
|
return m_dense.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end() -> std::vector<Dense_T>::iterator
|
auto end() -> lsd::vector<Dense_T>::iterator
|
||||||
{
|
{
|
||||||
return m_dense.end();
|
return m_dense.end();
|
||||||
}
|
}
|
||||||
|
|
@ -146,15 +143,15 @@ public:
|
||||||
[[nodiscard]] auto &&operator[](this auto &&self, Identifier_T identifier)
|
[[nodiscard]] auto &&operator[](this auto &&self, Identifier_T identifier)
|
||||||
{
|
{
|
||||||
using Self_T = decltype(self);
|
using Self_T = decltype(self);
|
||||||
return std::forward<Self_T>(self).m_dense[std::forward<Self_T>(self).m_sparse[identifier]];
|
return lsd::forward<Self_T>(self).m_dense[lsd::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;
|
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();
|
return m_sparse.capacity();
|
||||||
}
|
}
|
||||||
|
|
@ -165,13 +162,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Dense_T> m_dense;
|
lsd::vector<Dense_T> m_dense;
|
||||||
|
|
||||||
std::vector<Identifier_T> m_sparse;
|
lsd::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
|
} // namespace lt::ecs
|
||||||
|
|
|
||||||
23
modules/env/constants.cppm
vendored
23
modules/env/constants.cppm
vendored
|
|
@ -1,10 +1,9 @@
|
||||||
export module env;
|
export module env;
|
||||||
|
import lsd;
|
||||||
|
|
||||||
import std;
|
export namespace lt {
|
||||||
|
|
||||||
namespace lt {
|
enum class Platform : u8
|
||||||
|
|
||||||
enum class Platform : std::uint8_t
|
|
||||||
{
|
{
|
||||||
/** The GNU/Linux platform.
|
/** The GNU/Linux platform.
|
||||||
* Tested on the following distros: arch-x86_64
|
* Tested on the following distros: arch-x86_64
|
||||||
|
|
@ -26,7 +25,7 @@ enum class Platform : std::uint8_t
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The compiler that was used for compiling the project. */
|
/** The compiler that was used for compiling the project. */
|
||||||
enum class Compiler : std::uint8_t
|
enum class Compiler : u8
|
||||||
{
|
{
|
||||||
clang,
|
clang,
|
||||||
gcc,
|
gcc,
|
||||||
|
|
@ -36,19 +35,25 @@ enum class Compiler : std::uint8_t
|
||||||
|
|
||||||
namespace constants {
|
namespace constants {
|
||||||
|
|
||||||
|
#define lt_windows_only(x)
|
||||||
|
#define lt_linux_only(x)
|
||||||
|
#define lt_mac_only(x)
|
||||||
|
|
||||||
#if defined(LIGHT_PLATFORM_WINDOWS)
|
#if defined(LIGHT_PLATFORM_WINDOWS)
|
||||||
#define lt_win(x)
|
// NOLINTNEXTLINE
|
||||||
|
#define lt_windows_only(x) x
|
||||||
constexpr auto platform = Platform::windows;
|
constexpr auto platform = Platform::windows;
|
||||||
constexpr auto platform_name = "windows";
|
constexpr auto platform_name = "windows";
|
||||||
|
|
||||||
#undef LIGHT_PLATFORM_WINDOWS
|
|
||||||
|
|
||||||
#elif defined(LIGHT_PLATFORM_LINUX)
|
#elif defined(LIGHT_PLATFORM_LINUX)
|
||||||
|
// NOLINTNEXTLINE
|
||||||
|
#define lt_linux_only(x) x
|
||||||
constexpr auto platform = Platform::gnu_linux;
|
constexpr auto platform = Platform::gnu_linux;
|
||||||
constexpr auto platform_name = "gnu_linux";
|
constexpr auto platform_name = "gnu_linux";
|
||||||
|
|
||||||
#elif defined(LIGHT_PLATFORM_MAC)
|
#elif defined(LIGHT_PLATFORM_MAC)
|
||||||
#define lt_mac(x) x
|
// NOLINTNEXTLINE
|
||||||
|
#define lt_mac_only(x) x
|
||||||
constexpr auto platform = Platform::mac;
|
constexpr auto platform = Platform::mac;
|
||||||
constexpr auto platform_name = "mac";
|
constexpr auto platform_name = "mac";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ struct [[maybe_unused]] print
|
||||||
lsd::unreachable();
|
lsd::unreachable();
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto path = lsd::filesystem::path { location.file_name() };
|
const auto path = lsd::file::path { location.file_name() };
|
||||||
|
|
||||||
lsd::println(
|
lsd::println(
|
||||||
"{} {} ==> {}",
|
"{} {} ==> {}",
|
||||||
|
|
|
||||||
9
modules/lsd/algorithm.cppm
Normal file
9
modules/lsd/algorithm.cppm
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export module lsd.algorithm;
|
||||||
|
import std;
|
||||||
|
|
||||||
|
export namespace lt::lsd {
|
||||||
|
|
||||||
|
using ::std::remove;
|
||||||
|
using ::std::remove_if;
|
||||||
|
|
||||||
|
} // namespace lt::lsd
|
||||||
13
modules/lsd/chrono.cppm
Normal file
13
modules/lsd/chrono.cppm
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
export module lsd.chrono;
|
||||||
|
import std;
|
||||||
|
|
||||||
|
export namespace lt::lsd::chrono {
|
||||||
|
|
||||||
|
using std::chrono::duration;
|
||||||
|
using std::chrono::steady_clock;
|
||||||
|
using std::chrono::time_point;
|
||||||
|
using std::chrono::time_point_cast;
|
||||||
|
|
||||||
|
using std::chrono::milliseconds;
|
||||||
|
|
||||||
|
} // namespace lt::lsd::chrono
|
||||||
9
modules/lsd/concepts.cppm
Normal file
9
modules/lsd/concepts.cppm
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export module lsd.concepts;
|
||||||
|
|
||||||
|
import std;
|
||||||
|
|
||||||
|
export namespace lt::lsd {
|
||||||
|
|
||||||
|
using std::invocable;
|
||||||
|
|
||||||
|
}
|
||||||
10
modules/lsd/exceptions.cppm
Normal file
10
modules/lsd/exceptions.cppm
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
export module lsd.exceptions;
|
||||||
|
|
||||||
|
import std;
|
||||||
|
|
||||||
|
export namespace lt::lsd {
|
||||||
|
|
||||||
|
using std::exception;
|
||||||
|
using std::runtime_error;
|
||||||
|
|
||||||
|
} // namespace lt::lsd
|
||||||
16
modules/lsd/filesystem.cppm
Normal file
16
modules/lsd/filesystem.cppm
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
export module lsd.filesystem;
|
||||||
|
import std;
|
||||||
|
|
||||||
|
export namespace lt::lsd::file {
|
||||||
|
|
||||||
|
using path = ::std::filesystem::path;
|
||||||
|
using ::std::filesystem::remove;
|
||||||
|
using in_stream = ::std::ifstream;
|
||||||
|
using out_stream = ::std::ofstream;
|
||||||
|
|
||||||
|
constexpr auto ios_binary = std::ios::binary;
|
||||||
|
constexpr auto ios_end = std::ios::end;
|
||||||
|
constexpr auto ios_beg = std::ios::beg;
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace lt::lsd::file
|
||||||
|
|
@ -7,8 +7,21 @@ export import lsd.hash;
|
||||||
export import lsd.span;
|
export import lsd.span;
|
||||||
export import lsd.utils;
|
export import lsd.utils;
|
||||||
export import lsd.thread;
|
export import lsd.thread;
|
||||||
|
export import lsd.chrono;
|
||||||
export import lsd.ref_ptr;
|
export import lsd.ref_ptr;
|
||||||
export import lsd.bitwise;
|
export import lsd.bitwise;
|
||||||
|
export import lsd.concepts;
|
||||||
export import lsd.scope_ptr;
|
export import lsd.scope_ptr;
|
||||||
|
export import lsd.exceptions;
|
||||||
export import lsd.primitives;
|
export import lsd.primitives;
|
||||||
|
export import lsd.filesystem;
|
||||||
export import lsd.src_location;
|
export import lsd.src_location;
|
||||||
|
|
||||||
|
export import lsd.math.vec2;
|
||||||
|
export import lsd.math.vec3;
|
||||||
|
export import lsd.math.vec4;
|
||||||
|
export import lsd.math.mat4;
|
||||||
|
export import lsd.math.algebra;
|
||||||
|
export import lsd.math.trig;
|
||||||
|
|
||||||
|
export import lsd.algorithm;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
export module math.algebra;
|
export module lsd.math.algebra;
|
||||||
import math.mat4;
|
import lsd.math.mat4;
|
||||||
import std;
|
import lsd.math.trig;
|
||||||
|
|
||||||
export namespace lt::math {
|
export namespace lt::lsd {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* let...
|
* let...
|
||||||
|
|
@ -37,19 +37,19 @@ export namespace lt::math {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr auto perspective(T field_of_view, T aspect_ratio, T z_near, T z_far)
|
constexpr auto perspective(T field_of_view, T aspect_ratio, T z_near, T z_far)
|
||||||
{
|
{
|
||||||
const T half_fov_tan = std::tan(field_of_view / static_cast<T>(2));
|
const T half_fov_tan = tan(field_of_view / static_cast<T>(2u));
|
||||||
|
|
||||||
auto result = mat4_impl<T>::identity();
|
auto result = mat4_impl<T>::identity();
|
||||||
|
|
||||||
result[0][0] = T { 1 } / (aspect_ratio * half_fov_tan);
|
result[0][0] = T { 1u } / (aspect_ratio * half_fov_tan);
|
||||||
//
|
//
|
||||||
result[1][1] = T { 1 } / (half_fov_tan);
|
result[1][1] = T { 1u } / (half_fov_tan);
|
||||||
//
|
//
|
||||||
// result[2][2] = -(z_far + z_near) / (z_far - z_near);
|
// result[2][2] = -(z_far + z_near) / (z_far - z_near);
|
||||||
//
|
//
|
||||||
result[2][2] = z_far / (z_far - z_near);
|
result[2][2] = z_far / (z_far - z_near);
|
||||||
//
|
//
|
||||||
result[2][3] = -T { 1 };
|
result[2][3] = -T { 1u };
|
||||||
//
|
//
|
||||||
// result[3][2] = -(T { 2 } * z_far * z_near) / (z_far - z_near);
|
// result[3][2] = -(T { 2 } * z_far * z_near) / (z_far - z_near);
|
||||||
result[3][2] = -(z_far * z_near) / (z_far - z_near);
|
result[3][2] = -(z_far * z_near) / (z_far - z_near);
|
||||||
|
|
@ -57,4 +57,4 @@ constexpr auto perspective(T field_of_view, T aspect_ratio, T z_near, T z_far)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lt::math
|
} // namespace lt::lsd
|
||||||
|
|
@ -1,24 +1,27 @@
|
||||||
export module math.mat4;
|
export module lsd.math.mat4;
|
||||||
import math.vec3;
|
import lsd.math.vec2;
|
||||||
import math.vec4;
|
import lsd.math.vec3;
|
||||||
import std;
|
import lsd.math.vec4;
|
||||||
|
import lsd.primitives;
|
||||||
|
import lsd.arr;
|
||||||
|
import lsd.str;
|
||||||
|
|
||||||
namespace lt::math {
|
export namespace lt::lsd {
|
||||||
|
|
||||||
export template<typename T = float>
|
template<typename T>
|
||||||
struct mat4_impl
|
struct mat4_impl
|
||||||
{
|
{
|
||||||
using Column_T = vec4_impl<T>;
|
using Column_T = vec4_impl<T>;
|
||||||
|
|
||||||
|
constexpr mat4_impl() = default;
|
||||||
|
|
||||||
constexpr explicit mat4_impl(T scalar = 0)
|
constexpr explicit mat4_impl(T scalar = 0)
|
||||||
: values(
|
: values({
|
||||||
{
|
Column_T { scalar },
|
||||||
Column_T { scalar },
|
Column_T { scalar },
|
||||||
Column_T { scalar },
|
Column_T { scalar },
|
||||||
Column_T { scalar },
|
Column_T { scalar },
|
||||||
Column_T { scalar },
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,12 +57,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];
|
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];
|
return values[idx];
|
||||||
}
|
}
|
||||||
|
|
@ -74,37 +77,37 @@ struct mat4_impl
|
||||||
return vec4_impl<T> {};
|
return vec4_impl<T> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<Column_T, 4> values; // NOLINT
|
lsd::arr<Column_T, 4uz> values; // NOLINT
|
||||||
};
|
};
|
||||||
|
|
||||||
export template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] auto translate(const vec3_impl<T> &value) -> mat4_impl<T>
|
[[nodiscard]] auto translate(const vec3_impl<T> &value) -> mat4_impl<T>
|
||||||
{
|
{
|
||||||
return mat4_impl<T> {};
|
return mat4_impl<T> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
export template<typename T>
|
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> {};
|
return mat4_impl<T> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
export template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] auto scale(const vec3_impl<T> &value) -> mat4_impl<T>
|
[[nodiscard]] auto scale(const vec3_impl<T> &value) -> mat4_impl<T>
|
||||||
{
|
{
|
||||||
return mat4_impl<T> {};
|
return mat4_impl<T> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
export template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] auto inverse(const mat4_impl<T> &value) -> mat4_impl<T>
|
[[nodiscard]] auto inverse(const mat4_impl<T> &value) -> mat4_impl<T>
|
||||||
{
|
{
|
||||||
return mat4_impl<T> {};
|
return mat4_impl<T> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
export using mat4 = mat4_impl<float>;
|
using mat4 = mat4_impl<f32>;
|
||||||
|
|
||||||
export using imat4 = mat4_impl<std::int32_t>;
|
using imat4 = mat4_impl<i32>;
|
||||||
|
|
||||||
export using umat4 = mat4_impl<std::uint32_t>;
|
using umat4 = mat4_impl<u32>;
|
||||||
|
|
||||||
} // namespace lt::math
|
} // namespace lt::lsd
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
export module math.trig;
|
export module lsd.math.trig;
|
||||||
|
import std;
|
||||||
|
|
||||||
export namespace lt::math {
|
export namespace lt::lsd {
|
||||||
|
|
||||||
|
using ::std::cos;
|
||||||
|
using ::std::sin;
|
||||||
|
using ::std::tan;
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto radians(float degrees) -> float
|
[[nodiscard]] constexpr auto radians(float degrees) -> float
|
||||||
{
|
{
|
||||||
|
|
@ -23,4 +28,4 @@ export namespace lt::math {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace lt::math
|
} // namespace lt::lsd
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
export module math.vec2;
|
export module lsd.math.vec2;
|
||||||
|
import lsd.primitives;
|
||||||
|
import lsd.str;
|
||||||
|
|
||||||
import std;
|
export namespace lt::lsd {
|
||||||
|
|
||||||
namespace lt::math {
|
template<typename T>
|
||||||
|
|
||||||
export template<typename T = float>
|
|
||||||
struct vec2_impl
|
struct vec2_impl
|
||||||
{
|
{
|
||||||
constexpr vec2_impl(): x(), y()
|
constexpr vec2_impl() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr explicit vec2_impl(T scalar): x(scalar), y(scalar)
|
constexpr explicit vec2_impl(T scalar): x(scalar), y(scalar)
|
||||||
{
|
{
|
||||||
|
|
@ -45,7 +44,7 @@ struct vec2_impl
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto operator*(float scalar) const -> vec2_impl
|
[[nodiscard]] auto operator*(f32 scalar) const -> vec2_impl
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
x * scalar,
|
x * scalar,
|
||||||
|
|
@ -59,24 +58,26 @@ struct vec2_impl
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export using vec2 = vec2_impl<float>;
|
using vec2 = vec2_impl<f32>;
|
||||||
|
|
||||||
export using ivec2 = vec2_impl<std::int32_t>;
|
using dvec2 = vec2_impl<f64>;
|
||||||
|
|
||||||
export using uvec2 = vec2_impl<std::uint32_t>;
|
using ivec2 = vec2_impl<i32>;
|
||||||
|
|
||||||
} // namespace lt::math
|
using uvec2 = vec2_impl<u32>;
|
||||||
|
|
||||||
|
} // namespace lt::lsd
|
||||||
|
|
||||||
export template<typename T>
|
export template<typename T>
|
||||||
struct std::formatter<lt::math::vec2_impl<T>>
|
struct lt::lsd::formatter<lt::lsd::vec2_impl<T>>
|
||||||
{
|
{
|
||||||
constexpr auto parse(std::format_parse_context &context)
|
constexpr auto parse(lt::lsd::format_parse_context &context)
|
||||||
{
|
{
|
||||||
return context.begin();
|
return context.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto format(const lt::math::vec2_impl<T> &val, std::format_context &context) const
|
auto format(const lt::lsd::vec2_impl<T> &val, lt::lsd::format_context &context) const
|
||||||
{
|
{
|
||||||
return std::format_to(context.out(), "{}, {}", val.x, val.y);
|
return lt::lsd::format_to(context.out(), "{}, {}", val.x, val.y);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
export module math.vec3;
|
export module lsd.math.vec3;
|
||||||
|
|
||||||
import math.vec2;
|
import lsd.math.vec2;
|
||||||
import std;
|
import lsd.primitives;
|
||||||
|
import lsd.str;
|
||||||
|
|
||||||
namespace lt::math {
|
export namespace lt::lsd {
|
||||||
|
|
||||||
export template<typename T = float>
|
template<typename T>
|
||||||
struct vec3_impl
|
struct vec3_impl
|
||||||
{
|
{
|
||||||
constexpr vec3_impl(): x(), y(), z()
|
constexpr vec3_impl() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr explicit vec3_impl(T scalar): x(scalar), y(scalar), z(scalar)
|
constexpr explicit vec3_impl(T scalar): x(scalar), y(scalar), z(scalar)
|
||||||
{
|
{
|
||||||
|
|
@ -48,11 +48,11 @@ struct vec3_impl
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
friend auto operator<<(std::ostream &stream, vec3_impl<T> value) -> std::ostream &
|
// friend auto operator<<(std::ostream &stream, vec3_impl<T> value) -> std::ostream &
|
||||||
{
|
// {
|
||||||
stream << value.x << ", " << value.y << ", " << value.z;
|
// stream << value.x << ", " << value.y << ", " << value.z;
|
||||||
return stream;
|
// return stream;
|
||||||
}
|
// }
|
||||||
|
|
||||||
T x; // NOLINT
|
T x; // NOLINT
|
||||||
|
|
||||||
|
|
@ -61,24 +61,26 @@ struct vec3_impl
|
||||||
T z; // NOLINT
|
T z; // NOLINT
|
||||||
};
|
};
|
||||||
|
|
||||||
export using vec3 = vec3_impl<float>;
|
using vec3 = vec3_impl<f32>;
|
||||||
|
|
||||||
export using ivec3 = vec3_impl<std::int32_t>;
|
using dvec3 = vec3_impl<f32>;
|
||||||
|
|
||||||
export using uvec3 = vec3_impl<std::uint32_t>;
|
using ivec3 = vec3_impl<i32>;
|
||||||
|
|
||||||
} // namespace lt::math
|
using uvec3 = vec3_impl<u32>;
|
||||||
|
|
||||||
|
} // namespace lt::lsd
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct std::formatter<lt::math::vec3_impl<T>>
|
struct lt::lsd::formatter<lt::lsd::vec3_impl<T>>
|
||||||
{
|
{
|
||||||
constexpr auto parse(std::format_parse_context &context)
|
constexpr auto parse(lt::lsd::format_parse_context &context)
|
||||||
{
|
{
|
||||||
return context.begin();
|
return context.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto format(const lt::math::vec3_impl<T> &val, std::format_context &context) const
|
auto format(const lt::lsd::vec3_impl<T> &val, lt::lsd::format_context &context) const
|
||||||
{
|
{
|
||||||
return std::format_to(context.out(), "{}, {}, {}", val.x, val.y, val.z);
|
return lt::lsd::format_to(context.out(), "{}, {}, {}", val.x, val.y, val.z);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
104
modules/lsd/math/vec4.cppm
Normal file
104
modules/lsd/math/vec4.cppm
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
export module lsd.math.vec4;
|
||||||
|
import lsd.math.vec2;
|
||||||
|
import lsd.math.vec3;
|
||||||
|
import lsd.primitives;
|
||||||
|
import lsd.arr;
|
||||||
|
import lsd.str;
|
||||||
|
|
||||||
|
export namespace lt::lsd {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct vec4_impl
|
||||||
|
{
|
||||||
|
constexpr vec4_impl() = default;
|
||||||
|
|
||||||
|
constexpr explicit vec4_impl(T scalar): x(scalar), y(scalar), z(scalar), w(scalar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr vec4_impl(T x, T y, T z, T w): x(x), y(y), z(z), w(w)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto operator==(const vec4_impl<T> &other) const -> bool
|
||||||
|
{
|
||||||
|
return x == other.x && y == other.y && z == other.z && w == other.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto operator!=(const vec4_impl<T> &other) const -> bool
|
||||||
|
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr auto operator-(const vec4_impl<T> &other) const -> vec4_impl
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
x - other.x,
|
||||||
|
y - other.y,
|
||||||
|
z - other.z,
|
||||||
|
w - other.w,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr auto operator[](size_t idx) -> T &
|
||||||
|
{
|
||||||
|
return values[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr auto operator[](size_t idx) const -> const T &
|
||||||
|
{
|
||||||
|
return values[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
T x;
|
||||||
|
|
||||||
|
T y;
|
||||||
|
|
||||||
|
T z;
|
||||||
|
|
||||||
|
T w;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
T r;
|
||||||
|
|
||||||
|
T g;
|
||||||
|
|
||||||
|
T b;
|
||||||
|
|
||||||
|
T a;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
lsd::arr<T, 4uz> values;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
using vec4 = vec4_impl<f32>;
|
||||||
|
|
||||||
|
using ivec4 = vec4_impl<i32>;
|
||||||
|
|
||||||
|
using uvec4 = vec4_impl<u32>;
|
||||||
|
|
||||||
|
} // namespace lt::lsd
|
||||||
|
|
||||||
|
export template<typename T>
|
||||||
|
struct lt::lsd::formatter<lt::lsd::vec4_impl<T>>
|
||||||
|
{
|
||||||
|
constexpr auto parse(lt::lsd::format_parse_context &context)
|
||||||
|
{
|
||||||
|
return context.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto format(const lt::lsd::vec4_impl<T> &val, lt::lsd::format_context &context) const
|
||||||
|
{
|
||||||
|
return lt::lsd::format_to(context.out(), "{}, {}, {}, {}", val.x, val.y, val.z, val.w);
|
||||||
|
}
|
||||||
|
};
|
||||||
8
modules/lsd/numeric_limits.cppm
Normal file
8
modules/lsd/numeric_limits.cppm
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
export module lsd.numeric_limits;
|
||||||
|
import std;
|
||||||
|
|
||||||
|
export namespace lt::lsd {
|
||||||
|
|
||||||
|
using ::std::numeric_limits;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -5,19 +5,30 @@ import std;
|
||||||
THAT HAS NO SUB-NAMESPACE IDENTIFIER. */
|
THAT HAS NO SUB-NAMESPACE IDENTIFIER. */
|
||||||
export namespace lt {
|
export namespace lt {
|
||||||
|
|
||||||
using u8 = std::uint8_t;
|
using byte = ::std::byte;
|
||||||
using u16 = std::uint16_t;
|
|
||||||
using u32 = std::uint32_t;
|
|
||||||
using u64 = std::uint64_t;
|
|
||||||
|
|
||||||
using i8 = std::int8_t;
|
using u8 = ::std::uint8_t;
|
||||||
using i16 = std::int16_t;
|
using u16 = ::std::uint16_t;
|
||||||
using i32 = std::int32_t;
|
using u32 = ::std::uint32_t;
|
||||||
using i64 = std::int64_t;
|
using u64 = ::std::uint64_t;
|
||||||
|
|
||||||
|
using i8 = ::std::int8_t;
|
||||||
|
using i16 = ::std::int16_t;
|
||||||
|
using i32 = ::std::int32_t;
|
||||||
|
using i64 = ::std::int64_t;
|
||||||
|
|
||||||
using f32 = float;
|
using f32 = float;
|
||||||
using f64 = double;
|
using f64 = double;
|
||||||
|
|
||||||
using size_t = std::size_t;
|
using size_t = ::std::size_t;
|
||||||
|
|
||||||
|
using stream_size = ::std::streamsize;
|
||||||
|
|
||||||
|
// The fact that bit_cast is a part of the standard library,
|
||||||
|
// rather than a builtin like static_cast is language quirk.
|
||||||
|
//
|
||||||
|
// From the end-user's perspective, it would be convenient
|
||||||
|
// for the bit_cast to be a language keyword.
|
||||||
|
using ::std::bit_cast;
|
||||||
|
|
||||||
} // namespace lt
|
} // namespace lt
|
||||||
|
|
|
||||||
|
|
@ -10,23 +10,23 @@ export namespace lt::lsd {
|
||||||
* @ref https://en.cppreference.com/w/cpp/memory/shared_ptr.html
|
* @ref https://en.cppreference.com/w/cpp/memory/shared_ptr.html
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using Ref = std::shared_ptr<T>;
|
using ref = std::shared_ptr<T>;
|
||||||
|
|
||||||
/** Allocates memory for an `Underlying_T` and directly constructs it there.
|
/** Allocates memory for an `Underlying_T` and directly constructs it there.
|
||||||
*
|
*
|
||||||
* @return A Ref<Underlying_T> to the constructed object.
|
* @return A Ref<Underlying_T> to the constructed object.
|
||||||
*/
|
*/
|
||||||
template<typename Underlying_T, typename... Args>
|
template<typename Underlying_T, typename... Args>
|
||||||
constexpr Ref<Underlying_T> create_ref(Args &&...args)
|
constexpr auto create_ref(Args &&...args) -> ref<Underlying_T>
|
||||||
{
|
{
|
||||||
return std::make_shared<Underlying_T>(std::forward<Args>(args)...);
|
return std::make_shared<Underlying_T>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Converts c-style pointer of type `Underlying_T` to a `Ref<Underlying_T>`. */
|
/** Converts c-style pointer of type `Underlying_T` to a `Ref<Underlying_T>`. */
|
||||||
template<typename Underlying_T>
|
template<typename Underlying_T>
|
||||||
constexpr Ref<Underlying_T> make_ref(Underlying_T *raw_pointer)
|
constexpr auto make_ref(Underlying_T *raw_pointer) -> ref<Underlying_T>
|
||||||
{
|
{
|
||||||
return Ref<Underlying_T>(raw_pointer);
|
return ref<Underlying_T>(raw_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lt::lsd
|
} // namespace lt::lsd
|
||||||
|
|
|
||||||
|
|
@ -9,23 +9,23 @@ export namespace lt::lsd {
|
||||||
* @ref https://en.cppreference.com/w/cpp/memory/unique_ptr.html
|
* @ref https://en.cppreference.com/w/cpp/memory/unique_ptr.html
|
||||||
*/
|
*/
|
||||||
template<typename t>
|
template<typename t>
|
||||||
using Scope = std::unique_ptr<t>;
|
using scope = std::unique_ptr<t>;
|
||||||
|
|
||||||
/** Allocates memory for an `Underlying_T` and directly constructs it there.
|
/** Allocates memory for an `Underlying_T` and directly constructs it there.
|
||||||
*
|
*
|
||||||
* @return A Scope<Underlying_T> to the constructed object.
|
* @return A Scope<Underlying_T> to the constructed object.
|
||||||
*/
|
*/
|
||||||
template<typename Underlying_T, typename... Args>
|
template<typename Underlying_T, typename... Args>
|
||||||
constexpr Scope<Underlying_T> create_scope(Args &&...args)
|
constexpr auto create_scope(Args &&...args) -> scope<Underlying_T>
|
||||||
{
|
{
|
||||||
return std::make_unique<Underlying_T>(std::forward<Args>(args)...);
|
return std::make_unique<Underlying_T>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Converts c-style pointer of type `Underlying_T` to a `Scope<Underlying_T>`. */
|
/** Converts c-style pointer of type `Underlying_T` to a `Scope<Underlying_T>`. */
|
||||||
template<typename Underlying_T>
|
template<typename Underlying_T>
|
||||||
constexpr Scope<Underlying_T> make_scope(Underlying_T *raw_pointer)
|
constexpr auto make_scope(Underlying_T *raw_pointer) -> scope<Underlying_T>
|
||||||
{
|
{
|
||||||
return Scope<Underlying_T>(raw_pointer);
|
return scope<Underlying_T>(raw_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lt::lsd
|
} // namespace lt::lsd
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,9 @@ using str_view = std::string_view;
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
using format_str = std::format_string<T...>;
|
using format_str = std::format_string<T...>;
|
||||||
|
|
||||||
|
using std::format_context;
|
||||||
|
using std::format_parse_context;
|
||||||
|
using std::format_to;
|
||||||
|
using std::formatter;
|
||||||
|
|
||||||
} // namespace lt::lsd
|
} // namespace lt::lsd
|
||||||
|
|
|
||||||
|
|
@ -16,17 +16,15 @@ export namespace lt::lsd {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOLINTBEGIN
|
// NOLINTBEGIN
|
||||||
|
using ::std::bit_cast;
|
||||||
using ::std::declval;
|
using ::std::declval;
|
||||||
using ::std::format;
|
using ::std::format;
|
||||||
using ::std::forward;
|
using ::std::forward;
|
||||||
using ::std::move;
|
using ::std::move;
|
||||||
using ::std::println;
|
using ::std::println;
|
||||||
|
using ::std::system;
|
||||||
|
using ::std::to_underlying;
|
||||||
|
|
||||||
namespace filesystem {
|
|
||||||
|
|
||||||
using ::std::filesystem::path;
|
|
||||||
|
|
||||||
}
|
|
||||||
// NOLINTEND
|
// NOLINTEND
|
||||||
|
|
||||||
} // namespace lt::lsd
|
} // namespace lt::lsd
|
||||||
|
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
export module math.vec4;
|
|
||||||
import math.vec2;
|
|
||||||
import math.vec3;
|
|
||||||
import std;
|
|
||||||
|
|
||||||
namespace lt::math {
|
|
||||||
|
|
||||||
export template<typename T = float>
|
|
||||||
struct vec4_impl
|
|
||||||
{
|
|
||||||
constexpr vec4_impl(): x(), y(), z(), w()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr explicit vec4_impl(T scalar): x(scalar), y(scalar), z(scalar), w(scalar)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr vec4_impl(T x, T y, T z, T w): x(x), y(y), z(z), w(w)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto operator==(const vec4_impl<T> &other) const -> bool
|
|
||||||
{
|
|
||||||
return x == other.x && y == other.y && z == other.z && w == other.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto operator!=(const vec4_impl<T> &other) const -> bool
|
|
||||||
{
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto operator-(const vec4_impl<T> &other) const -> vec4_impl
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
x - other.x,
|
|
||||||
y - other.y,
|
|
||||||
z - other.z,
|
|
||||||
w - other.w,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto operator[](std::size_t idx) -> T &
|
|
||||||
{
|
|
||||||
return values[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto operator[](std::size_t idx) const -> const T &
|
|
||||||
{
|
|
||||||
return values[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
friend auto operator<<(std::ostream &stream, vec4_impl<T> value) -> std::ostream &
|
|
||||||
{
|
|
||||||
stream << value.x << ", " << value.y << ", " << value.z << ", " << value.w;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOLINTNEXTLINE
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
T x;
|
|
||||||
|
|
||||||
T y;
|
|
||||||
|
|
||||||
T z;
|
|
||||||
|
|
||||||
T w;
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
T r;
|
|
||||||
|
|
||||||
T g;
|
|
||||||
|
|
||||||
T b;
|
|
||||||
|
|
||||||
T a;
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
std::array<T, 4> values;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export using vec4 = vec4_impl<float>;
|
|
||||||
|
|
||||||
export using ivec4 = vec4_impl<std::int32_t>;
|
|
||||||
|
|
||||||
export using uvec4 = vec4_impl<std::uint32_t>;
|
|
||||||
|
|
||||||
} // namespace lt::math
|
|
||||||
|
|
||||||
export template<typename T>
|
|
||||||
struct std::formatter<lt::math::vec4_impl<T>>
|
|
||||||
{
|
|
||||||
constexpr auto parse(std::format_parse_context &context)
|
|
||||||
{
|
|
||||||
return context.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto format(const lt::math::vec4_impl<T> &val, std::format_context &context) const
|
|
||||||
{
|
|
||||||
return std::format_to(context.out(), "{}, {}, {}, {}", val.x, val.y, val.z, val.w);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -7,23 +7,18 @@ import lsd;
|
||||||
using namespace ::lt;
|
using namespace ::lt;
|
||||||
using namespace ::lt::test;
|
using namespace ::lt::test;
|
||||||
|
|
||||||
constexpr lsd::str_view operator""_sv(const char *str, unsigned long len) noexcept
|
|
||||||
{
|
|
||||||
return lsd::str_view { str, len };
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_option(lsd::str_view argument, Registry::Options &options)
|
void parse_option(lsd::str_view argument, Registry::Options &options)
|
||||||
{
|
{
|
||||||
constexpr auto case_str = lsd::str_view { "--case=" };
|
constexpr auto case_str = lsd::str_view { "--case=" };
|
||||||
constexpr auto suite_str = lsd::str_view { "--suite=" };
|
constexpr auto suite_str = lsd::str_view { "--suite=" };
|
||||||
|
|
||||||
if (argument == "--stop-on-fail"_sv)
|
if (argument == "--stop-on-fail")
|
||||||
{
|
{
|
||||||
options.stop_on_fail = true;
|
options.stop_on_fail = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argument.starts_with("--mode="_sv) && argument.substr(7ul) == "stats")
|
if (argument.starts_with("--mode=") && argument.substr(7ul) == "stats")
|
||||||
{
|
{
|
||||||
options.execution_policy = Registry::ExecutionPolicy::stats;
|
options.execution_policy = Registry::ExecutionPolicy::stats;
|
||||||
return;
|
return;
|
||||||
|
|
@ -91,7 +86,7 @@ try
|
||||||
|
|
||||||
return static_cast<i32>(Registry::run_all(options));
|
return static_cast<i32>(Registry::run_all(options));
|
||||||
}
|
}
|
||||||
catch (const std::exception &exp)
|
catch (const lsd::exception &exp)
|
||||||
{
|
{
|
||||||
lt::log::critical("Terminated due to uncaught exception:");
|
lt::log::critical("Terminated due to uncaught exception:");
|
||||||
lt::log::critical("\twhat: {}", exp.what());
|
lt::log::critical("\twhat: {}", exp.what());
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
export module test.test;
|
export module test.test;
|
||||||
|
|
||||||
import std;
|
|
||||||
import test.expects;
|
import test.expects;
|
||||||
import test.registry;
|
import test.registry;
|
||||||
|
import std;
|
||||||
|
import lsd;
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// ----------* INTERFACE *--------- //
|
// ----------* INTERFACE *--------- //
|
||||||
|
|
@ -12,16 +13,16 @@ namespace lt::test {
|
||||||
class TestCase
|
class TestCase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TestCase(std::string_view name);
|
TestCase(lsd::str_view name);
|
||||||
|
|
||||||
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
|
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
|
||||||
auto operator=(std::invocable auto test) const -> void;
|
auto operator=(lsd::invocable auto test) const -> void;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run_normal(std::invocable auto test) const;
|
void run_normal(lsd::invocable auto test) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string_view m_name;
|
lsd::str_view m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TestSuite
|
struct TestSuite
|
||||||
|
|
@ -38,25 +39,25 @@ struct TestFuzzHarness
|
||||||
export using Case = const TestCase;
|
export using Case = const TestCase;
|
||||||
export using Suite = const TestSuite;
|
export using Suite = const TestSuite;
|
||||||
export using FuzzHarness = const TestFuzzHarness;
|
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 * //
|
// * IMPLEMENTATION -- TEMPLATES * //
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
|
||||||
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
|
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
|
||||||
auto TestCase::operator=(std::invocable auto test) const -> void
|
auto TestCase::operator=(lsd::invocable auto test) const -> void
|
||||||
{
|
{
|
||||||
using enum Registry::ExecutionPolicy;
|
using enum Registry::ExecutionPolicy;
|
||||||
|
|
||||||
switch (Registry::get_options().execution_policy)
|
switch (Registry::get_options().execution_policy)
|
||||||
{
|
{
|
||||||
case normal: run_normal(std::move(test)); break;
|
case normal: run_normal(lsd::move(test)); break;
|
||||||
case stats: Registry::increment_total_case_count(); break;
|
case stats: Registry::increment_total_case_count(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCase::run_normal(std::invocable auto test) const
|
void TestCase::run_normal(lsd::invocable auto test) const
|
||||||
{
|
{
|
||||||
Registry::increment_total_case_count();
|
Registry::increment_total_case_count();
|
||||||
|
|
||||||
|
|
@ -68,16 +69,16 @@ void TestCase::run_normal(std::invocable auto test) const
|
||||||
}
|
}
|
||||||
Registry::increment_matched_case_count();
|
Registry::increment_matched_case_count();
|
||||||
|
|
||||||
std::println("[Running-----------] --> ");
|
lsd::println("[Running-----------] --> ");
|
||||||
std::println("{}", m_name);
|
lsd::println("{}", m_name);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
test();
|
test();
|
||||||
}
|
}
|
||||||
catch (const std::exception &exp)
|
catch (const std::exception &exp)
|
||||||
{
|
{
|
||||||
std::println("{}", exp.what());
|
lsd::println("{}", exp.what());
|
||||||
std::println("[-----------FAIL !!]");
|
lsd::println("[-----------FAIL !!]");
|
||||||
Registry::increment_failed_case_count();
|
Registry::increment_failed_case_count();
|
||||||
|
|
||||||
if (Registry::should_return_on_failure())
|
if (Registry::should_return_on_failure())
|
||||||
|
|
@ -89,7 +90,7 @@ void TestCase::run_normal(std::invocable auto test) const
|
||||||
}
|
}
|
||||||
|
|
||||||
Registry::increment_passed_case_count();
|
Registry::increment_passed_case_count();
|
||||||
std::println("[--------SUCCESS :D]");
|
lsd::println("[--------SUCCESS :D]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TestSuite::TestSuite(auto body)
|
TestSuite::TestSuite(auto body)
|
||||||
|
|
@ -106,7 +107,7 @@ constexpr TestFuzzHarness::TestFuzzHarness(auto body)
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
auto operator""_suite(const char *name, std::size_t size) -> TestSuite
|
auto operator""_suite(const char *name, size_t size) -> TestSuite
|
||||||
{
|
{
|
||||||
Registry::set_last_suite_name(name);
|
Registry::set_last_suite_name(name);
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -120,7 +121,7 @@ auto operator""_suite(const char *name, std::size_t size) -> TestSuite
|
||||||
module :private;
|
module :private;
|
||||||
namespace lt::test {
|
namespace lt::test {
|
||||||
|
|
||||||
TestCase::TestCase(std::string_view name): m_name(name)
|
TestCase::TestCase(lsd::str_view name): m_name(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
export module time;
|
export module time;
|
||||||
import std;
|
import lsd;
|
||||||
|
|
||||||
namespace lt::time {
|
namespace lt::time {
|
||||||
|
|
||||||
|
|
@ -7,11 +7,11 @@ namespace lt::time {
|
||||||
export class Timer
|
export class Timer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Clock = std::chrono::steady_clock;
|
using Clock = lsd::chrono::steady_clock;
|
||||||
|
|
||||||
using Duration = std::chrono::duration<double>;
|
using Duration = lsd::chrono::duration<f64>;
|
||||||
|
|
||||||
using Timepoint = std::chrono::time_point<std::chrono::steady_clock>;
|
using Timepoint = lsd::chrono::time_point<lsd::chrono::steady_clock>;
|
||||||
|
|
||||||
Timer(Timepoint start = Clock::now());
|
Timer(Timepoint start = Clock::now());
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ void Timer::reset(Timepoint start)
|
||||||
|
|
||||||
[[nodiscard]] auto Timer::elapsed_time() const -> Duration
|
[[nodiscard]] auto Timer::elapsed_time() const -> Duration
|
||||||
{
|
{
|
||||||
return { std::chrono::steady_clock::now() - m_start };
|
return { lsd::chrono::steady_clock::now() - m_start };
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lt::time
|
} // namespace lt::time
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue