diff --git a/cmake/aurora_core.cmake b/cmake/aurora_core.cmake index 04e98ce..edda759 100644 --- a/cmake/aurora_core.cmake +++ b/cmake/aurora_core.cmake @@ -4,6 +4,7 @@ add_library(aurora_core STATIC lib/imgui.cpp lib/input.cpp lib/window.cpp + lib/logging.cpp ) add_library(aurora::core ALIAS aurora_core) diff --git a/lib/gfx/common.cpp b/lib/gfx/common.cpp index 889e608..28f2861 100644 --- a/lib/gfx/common.cpp +++ b/lib/gfx/common.cpp @@ -502,7 +502,8 @@ void map_staging_buffer() { g_stagingBuffers[currentStagingBuffer].MapAsync( wgpu::MapMode::Write, 0, StagingBufferSize, wgpu::CallbackMode::AllowSpontaneous, [](wgpu::MapAsyncStatus status, wgpu::StringView message) { - if (status == wgpu::MapAsyncStatus::CallbackCancelled) { + if (status == wgpu::MapAsyncStatus::CallbackCancelled || status == wgpu::MapAsyncStatus::Aborted) { + Log.warn("Buffer mapping {}: {}", magic_enum::enum_name(status), message); return; } ASSERT(status == wgpu::MapAsyncStatus::Success, "Buffer mapping failed: {} {}", magic_enum::enum_name(status), diff --git a/lib/gfx/common.hpp b/lib/gfx/common.hpp index b963ec0..6bde6e9 100644 --- a/lib/gfx/common.hpp +++ b/lib/gfx/common.hpp @@ -2,11 +2,13 @@ #include "../internal.hpp" -#include +#include +#include +#include #include #include -#include +#include #include #define XXH_STATIC_LINKING_ONLY #include @@ -30,12 +32,12 @@ static inline HashType xxh3_hash(const T& input, HashType seed = 0) { class Hasher { public: - explicit Hasher(XXH64_hash_t seed = 0) { + explicit Hasher(const XXH64_hash_t seed = 0) { XXH3_INITSTATE(&state); XXH3_64bits_reset_withSeed(&state, seed); } - void update(const void* data, size_t size) { XXH3_64bits_update(&state, data, size); } + void update(const void* data, const size_t size) { XXH3_64bits_update(&state, data, size); } template void update(const T& data) { @@ -43,7 +45,7 @@ public: update(&data, sizeof(T)); } - XXH64_hash_t digest() { return XXH3_64bits_digest(&state); } + [[nodiscard]] XXH64_hash_t digest() const { return XXH3_64bits_digest(&state); } private: XXH3_state_t state; @@ -55,7 +57,7 @@ public: explicit ByteBuffer(size_t size) noexcept : m_data(static_cast(calloc(1, size))), m_length(size), m_capacity(size) {} explicit ByteBuffer(uint8_t* data, size_t size) noexcept - : m_data(data), m_length(0), m_capacity(size), m_owned(false) {} + : m_data(data), m_capacity(size), m_owned(false) {} ~ByteBuffer() noexcept { if (m_data != nullptr && m_owned) { free(m_data); @@ -176,7 +178,7 @@ struct ClipRect { struct TextureRef; using TextureHandle = std::shared_ptr; -enum class ShaderType { +enum class ShaderType : uint8_t { Stream, Model, }; diff --git a/lib/internal.hpp b/lib/internal.hpp index 5526ad6..17032e3 100644 --- a/lib/internal.hpp +++ b/lib/internal.hpp @@ -1,8 +1,8 @@ #pragma once +#include "logging.hpp" // IWYU pragma: keep + #include -#include -#include #include #include @@ -20,14 +20,6 @@ using namespace std::string_view_literals; #endif #endif -#ifdef __GNUC__ -[[noreturn]] inline __attribute__((always_inline)) void unreachable() { __builtin_unreachable(); } -#elif defined(_MSC_VER) -[[noreturn]] __forceinline void unreachable() { __assume(false); } -#else -#error Unknown compiler -#endif - #ifndef ALIGN #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) #endif @@ -42,7 +34,7 @@ using namespace std::string_view_literals; #endif #define FATAL(msg, ...) \ { \ - Log.report(LOG_FATAL, msg, ##__VA_ARGS__); \ + Log.fatal(msg, ##__VA_ARGS__); \ unreachable(); \ } #define ASSERT(cond, msg, ...) \ @@ -57,29 +49,16 @@ using namespace std::string_view_literals; #define TRY(cond, msg, ...) \ if (!(cond)) \ UNLIKELY { \ - Log.report(LOG_ERROR, msg, ##__VA_ARGS__); \ + Log.error(msg, ##__VA_ARGS__); \ return false; \ } #define TRY_WARN(cond, msg, ...) \ if (!(cond)) \ - UNLIKELY { Log.report(LOG_WARNING, msg, ##__VA_ARGS__); } + UNLIKELY { Log.warn(msg, ##__VA_ARGS__); } namespace aurora { extern AuroraConfig g_config; -struct Module { - const char* name; - explicit Module(const char* name) noexcept : name(name) {} - - template - void report(AuroraLogLevel level, fmt::format_string fmt, T&&... args) noexcept { - auto message = fmt::format(fmt, std::forward(args)...); - if (g_config.logCallback != nullptr) { - g_config.logCallback(level, name, message.c_str(), message.size()); - } - } -}; - template class ArrayRef { public: diff --git a/lib/logging.cpp b/lib/logging.cpp new file mode 100644 index 0000000..4632d66 --- /dev/null +++ b/lib/logging.cpp @@ -0,0 +1,45 @@ +#include "logging.hpp" + +#include +#include +#include + +#include +#include + +namespace aurora { +extern AuroraConfig g_config; + +void log_internal(const AuroraLogLevel level, const char* module, const char* message, + const unsigned int len) noexcept { + if (g_config.logCallback == nullptr) { + fmt::println(stderr, "[{}] [{}] {}", level, module, std::string_view(message, len)); + } else { + g_config.logCallback(level, module, message, len); + } +} +} // namespace aurora + +auto fmt::formatter::format(const AuroraLogLevel level, format_context& ctx) const -> format_context::iterator { + std::string_view name = "unknown"; + switch (level) { + case LOG_DEBUG: + name = "debug"; + break; + case LOG_INFO: + name = "info"; + break; + case LOG_WARNING: + name = "warning"; + break; + case LOG_ERROR: + name = "error"; + break; + case LOG_FATAL: + name = "fatal"; + break; + default: + break; + } + return formatter::format(name, ctx); +} diff --git a/lib/logging.hpp b/lib/logging.hpp new file mode 100644 index 0000000..bed551c --- /dev/null +++ b/lib/logging.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include + +#include +#include +#include + +#ifdef __GNUC__ +[[noreturn]] inline __attribute__((always_inline)) void unreachable() { __builtin_unreachable(); } +#elif defined(_MSC_VER) +[[noreturn]] __forceinline void unreachable() { __assume(false); } +#else +#error Unknown compiler +#endif + +namespace aurora { +void log_internal(AuroraLogLevel level, const char* module, const char* message, unsigned int len) noexcept; + +struct Module { + const char* name; + explicit Module(const char* name) noexcept : name(name) {} + + template + void report(const AuroraLogLevel level, fmt::format_string fmt, T&&... args) noexcept { + auto message = fmt::format(fmt, std::forward(args)...); + log_internal(level, name, message.c_str(), message.size()); + } + + template + void debug(fmt::format_string fmt, T&&... args) noexcept { + report(LOG_DEBUG, fmt, std::forward(args)...); + } + + template + void info(fmt::format_string fmt, T&&... args) noexcept { + report(LOG_INFO, fmt, std::forward(args)...); + } + + template + void warn(fmt::format_string fmt, T&&... args) noexcept { + report(LOG_WARNING, fmt, std::forward(args)...); + } + + template + void error(fmt::format_string fmt, T&&... args) noexcept { + report(LOG_ERROR, fmt, std::forward(args)...); + } + + template + [[noreturn]] void fatal(fmt::format_string fmt, T&&... args) noexcept { + report(LOG_FATAL, fmt, std::forward(args)...); + unreachable(); + } +}; +} // namespace aurora + +template <> +struct fmt::formatter : formatter { + auto format(AuroraLogLevel level, format_context& ctx) const -> format_context::iterator; +};