diff options
-rw-r--r-- | deimos/core/BUILD | 5 | ||||
-rw-r--r-- | deimos/core/api_registry.cpp | 2 | ||||
-rw-r--r-- | deimos/core/base.h | 10 | ||||
-rw-r--r-- | deimos/core/format.h | 5 | ||||
-rw-r--r-- | deimos/core/hash.h | 2 | ||||
-rw-r--r-- | deimos/core/io.cpp | 18 | ||||
-rw-r--r-- | deimos/core/io.h | 20 | ||||
-rw-r--r-- | deimos/core/log.cpp | 82 | ||||
-rw-r--r-- | deimos/core/log.h | 71 | ||||
-rw-r--r-- | main/main.cpp | 10 |
10 files changed, 216 insertions, 9 deletions
diff --git a/deimos/core/BUILD b/deimos/core/BUILD index fcedb22..08f1ada 100644 --- a/deimos/core/BUILD +++ b/deimos/core/BUILD @@ -8,6 +8,7 @@ cc_library( "hash.h",
"id_name.h",
"io.h",
+ "log.h",
"os.h",
"std.h",
"format.h",
@@ -15,8 +16,10 @@ cc_library( srcs = [
"allocator.cpp",
"api_registry.cpp",
- "os_win32.cpp",
"format.cpp",
+ "io.cpp",
+ "log.cpp",
+ "os_win32.cpp",
],
visibility = ["//:__subpackages__"],
)
diff --git a/deimos/core/api_registry.cpp b/deimos/core/api_registry.cpp index 1489484..24ea201 100644 --- a/deimos/core/api_registry.cpp +++ b/deimos/core/api_registry.cpp @@ -8,6 +8,7 @@ namespace deimos AllocatorApi* BootstrapAllocatorApi();
void RegisterOsApi(ApiRegistry*);
+void RegisterLogApi(ApiRegistry*);
struct ApiEntry
{
@@ -56,6 +57,7 @@ ApiRegistry* InitializeGlobalApiRegistry() api_registry->Set(g_allocator_api);
RegisterOsApi(api_registry);
+ RegisterLogApi(api_registry);
return api_registry;
}
diff --git a/deimos/core/base.h b/deimos/core/base.h index 21cad3d..4bcb7c7 100644 --- a/deimos/core/base.h +++ b/deimos/core/base.h @@ -53,6 +53,14 @@ struct SourceLocation {}
};
+template<typename T> T Min(T a, T b) { return (a < b) ? a : b; }
+template<typename T> T Max(T a, T b) { return (a > b) ? a : b; }
+
+constexpr void MemoryCopy(void* dst, const void* src, int64_t size)
+{
+ __builtin_memcpy(dst, src, (size_t)size);
+}
+
template<typename T>
class Span
{
@@ -79,7 +87,7 @@ public: template<typename U>
requires std::convertible_to<U*, T*>
- constexpr Span(const Span<U>& other) : // NOLINT
+ constexpr Span(const Span<U>& other) : // NOLINT(*-explicit-conversions)
m_begin{other.begin()},
m_size{other.size()}
{}
diff --git a/deimos/core/format.h b/deimos/core/format.h index 98d9001..be2e4bf 100644 --- a/deimos/core/format.h +++ b/deimos/core/format.h @@ -37,6 +37,11 @@ struct FormatArg unsigned_integer{value}
{}
+ explicit FormatArg(Span<const char> value) :
+ type{kString},
+ string{value}
+ {}
+
explicit FormatArg(gsl::czstring value) :
type{kString},
string{value, (int64_t)__builtin_strlen(value)}
diff --git a/deimos/core/hash.h b/deimos/core/hash.h index f0eeafd..3198541 100644 --- a/deimos/core/hash.h +++ b/deimos/core/hash.h @@ -43,8 +43,6 @@ constexpr uint64_t MurmurHash3_Fmix64(uint64_t k) constexpr uint128_t MurmurHash3_x64_128(const char* key, uint64_t len)
{
- if consteval { return { 12, 12 }; }
-
// NOLINTBEGIN
const uint64_t nblocks = len / 16;
diff --git a/deimos/core/io.cpp b/deimos/core/io.cpp new file mode 100644 index 0000000..7764ee2 --- /dev/null +++ b/deimos/core/io.cpp @@ -0,0 +1,18 @@ +#include "deimos/core/io.h"
+
+namespace deimos
+{
+
+void BufferWriter::Write(Span<const std::byte> to_write)
+{
+ Expects(m_written <= m_size);
+
+ int64_t n_to_write = Min(to_write.size(), m_size - m_written);
+ MemoryCopy(m_buffer + m_written, to_write.data(), n_to_write); // NOLINT
+ m_written += n_to_write;
+
+ Ensures(m_written <= m_size);
+}
+
+} // namespace deimos
+
diff --git a/deimos/core/io.h b/deimos/core/io.h index 90caadc..12de30e 100644 --- a/deimos/core/io.h +++ b/deimos/core/io.h @@ -17,5 +17,25 @@ public: virtual void Write(Span<const std::byte>) = 0;
};
+class BufferWriter : public IWriter
+{
+ std::byte* m_buffer;
+ int64_t m_size;
+ int64_t m_written = 0;
+
+public:
+ explicit BufferWriter(Span<std::byte> buffer) :
+ m_buffer{buffer.begin()},
+ m_size{buffer.size()}
+ {}
+
+ void Write(Span<const std::byte>) override;
+
+ constexpr Span<const std::byte> GetWritten() const
+ {
+ return { m_buffer, m_written };
+ }
+};
+
} // namespace deimos
diff --git a/deimos/core/log.cpp b/deimos/core/log.cpp new file mode 100644 index 0000000..befe4b7 --- /dev/null +++ b/deimos/core/log.cpp @@ -0,0 +1,82 @@ +#include "deimos/core/log.h"
+#include "deimos/core/api_registry.h"
+#include "deimos/core/allocator.h"
+#include "deimos/core/os.h"
+
+namespace deimos
+{
+
+class DefaultLogger : public ILogger
+{
+ OsConsoleWriter m_writer;
+
+ static const char* SeverityToStr(LogSeverity s)
+ {
+ switch (s)
+ {
+ case LogSeverity::kInfo: return "INFO ";
+ case LogSeverity::kDebug: return "DEBUG";
+ case LogSeverity::kError: return "ERROR";
+ }
+ }
+
+ static const char* SeverityToColor(LogSeverity s)
+ {
+ switch (s)
+ {
+ case LogSeverity::kInfo: return "";
+ case LogSeverity::kDebug: return "\033[2m";
+ case LogSeverity::kError: return "\033[91m";
+ }
+ }
+
+public:
+ explicit DefaultLogger(OsConsoleApi* os_console_api) :
+ m_writer(os_console_api, OsConsoleType::kStdOut)
+ {}
+
+ // @Todo Use string views
+ void Log(LogSeverity severity, const SourceLocation& location, Span<const char> msg) override
+ {
+ Format(&m_writer, "$[ $ ] $:$: $\033[0m\n", SeverityToColor(severity),
+ SeverityToStr(severity), location.file, location.line, msg);
+ }
+};
+
+class LogApiImpl : public LogApi
+{
+ ILogger* m_default_logger;
+
+public:
+ explicit LogApiImpl(ILogger* default_logger) :
+ m_default_logger{default_logger}
+ {}
+
+ void LogVa(
+ LogSeverity severity,
+ const SourceLocation& location,
+ gsl::czstring msg,
+ Span<const FormatArg> args) override
+ {
+ std::byte buffer[1024];
+ BufferWriter message_writer({&buffer[0], 1024});
+ FormatVa(&message_writer, msg, args);
+
+ auto written = message_writer.GetWritten();
+ m_default_logger->Log(severity, location, {(const char*)written.data(), written.size()});
+ }
+};
+
+void RegisterLogApi(ApiRegistry* api_registry)
+{
+ auto* allocator = api_registry->Get<AllocatorApi>()->system;
+ auto* os_console_api = api_registry->Get<OsApi>()->console;
+
+ auto* default_logger = allocator->New<DefaultLogger>(os_console_api);
+ auto* log_api = allocator->New<LogApiImpl>(default_logger);
+
+ api_registry->Set(log_api);
+}
+
+} // namespace deimos
+
diff --git a/deimos/core/log.h b/deimos/core/log.h new file mode 100644 index 0000000..cf92391 --- /dev/null +++ b/deimos/core/log.h @@ -0,0 +1,71 @@ +#pragma once
+
+#include "deimos/core/base.h"
+#include "deimos/core/id_name.h"
+#include "deimos/core/format.h"
+
+namespace deimos
+{
+
+enum class LogSeverity
+{
+ kInfo,
+ kDebug,
+ kError,
+};
+
+class ILogger
+{
+public:
+ ILogger() = default;
+ deimos_NO_COPY_MOVE(ILogger);
+ virtual ~ILogger() = default;
+
+ // @Todo Use string view
+ virtual void Log(LogSeverity, const SourceLocation&, Span<const char>) = 0;
+};
+
+// Just a helper to pass a SourceLocation without having to write {} to logging functions.
+struct LogSourceLocation
+{
+ gsl::czstring fmt;
+ SourceLocation source_location;
+
+ // NOLINTNEXTLINE(*-explicit-conversions)
+ LogSourceLocation(gsl::czstring fmt_, const SourceLocation& source_location_ = {}) :
+ fmt{fmt_}, source_location{source_location_}
+ {}
+};
+
+class LogApi
+{
+public:
+ static constexpr IdName kApiName{"deimos::LogApi"};
+
+ LogApi() = default;
+ deimos_NO_COPY_MOVE(LogApi);
+ virtual ~LogApi() = default;
+
+ virtual void LogVa(LogSeverity, const SourceLocation&, gsl::czstring msg, Span<const FormatArg>) = 0;
+
+ template<Formattable... Args>
+ void LogInfo(const LogSourceLocation& fmt_source_location, Args&&... args)
+ {
+ LogVa(LogSeverity::kInfo, fmt_source_location.source_location, fmt_source_location.fmt, { FormatArg(std::forward<Args>(args))... });
+ }
+
+ template<Formattable... Args>
+ void LogDebug(const LogSourceLocation& fmt_source_location, Args&&... args)
+ {
+ LogVa(LogSeverity::kDebug, fmt_source_location.source_location, fmt_source_location.fmt, { FormatArg(std::forward<Args>(args))... });
+ }
+
+ template<Formattable... Args>
+ void LogError(const LogSourceLocation& fmt_source_location, Args&&... args)
+ {
+ LogVa(LogSeverity::kError, fmt_source_location.source_location, fmt_source_location.fmt, { FormatArg(std::forward<Args>(args))... });
+ }
+};
+
+} // namespace deimos
+
diff --git a/main/main.cpp b/main/main.cpp index 10a7dc4..03c2097 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,16 +1,16 @@ #include <deimos/core/api_registry.h>
-#include <deimos/core/os.h>
-#include <deimos/core/format.h>
+#include <deimos/core/log.h>
using namespace deimos;
int main(int /* argc */, char* /* argv */[])
{
auto* api_registry = InitializeGlobalApiRegistry();
- auto* os_api = api_registry->Get<OsApi>();
+ auto* log_api = api_registry->Get<LogApi>();
- OsConsoleWriter writer(os_api->console, OsConsoleType::kStdOut);
- Format(&writer, "Hello, $!", "world");
+ log_api->LogInfo("Hello, world!");
+ log_api->LogDebug("Hello, $!", "world");
+ log_api->LogError("This is an error OMG $ $ $", 1, 2, 3);
return 0;
}
|