GiteaCI (#1)
Bigfoot / Build & Test Debug (Unity Build: ON) (push) Has been cancelled
Bigfoot / Build & Test RelWithDebInfo (Unity Build: OFF) (push) Has been cancelled
Bigfoot / Build & Test RelWithDebInfo (Unity Build: ON) (push) Has been cancelled
Bigfoot / Build & Test Release (Unity Build: OFF) (push) Has been cancelled
Bigfoot / Build & Test Release (Unity Build: ON) (push) Has been cancelled
Bigfoot / Build & Test Debug (Unity Build: OFF) (push) Has been cancelled

Reviewed-on: #1
Co-authored-by: Romain BOULLARD <romain.boullard@protonmail.com>
Co-committed-by: Romain BOULLARD <romain.boullard@protonmail.com>
This commit was merged in pull request #1.
This commit is contained in:
2026-01-28 14:29:12 +00:00
committed by Romain BOULLARD
parent a82ec43e74
commit 6cd9801ef7
71 changed files with 1639 additions and 745 deletions
+3 -9
View File
@@ -1,21 +1,15 @@
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName})
set(PublicDependencies
$<$<CONFIG:Debug,RelWithDebInfo>:quill::quill>
$<$<CONFIG:Debug,RelWithDebInfo>:cpptrace::cpptrace>)
set(PrivateDependencies)
set(BigfootPublicDependencies
System)
set(BigfootPublicDependencies)
set(BigfootPrivateDependencies)
bigfoot_create_package_lib(
${PackageName}
"${PublicDependencies}"
"${PrivateLibraries}"
"${BigfootPublicDependencies}"
"${BigfootPrivateDependencies}"
"")
target_compile_definitions(${PackageName}
PUBLIC $<$<CONFIG:Debug,RelWithDebInfo>:QUILL_NO_EXCEPTIONS>
PUBLIC $<$<CONFIG:Debug,RelWithDebInfo>:QUILL_DISABLE_NON_PREFIXED_MACROS>)
"")
@@ -11,7 +11,6 @@
#include <cpptrace/cpptrace.hpp>
#include <cstdint>
#include <source_location>
#include <string>
+13 -24
View File
@@ -6,52 +6,41 @@
*********************************************************************/
#ifndef BIGFOOT_UTILS_CASTER_HPP
#define BIGFOOT_UTILS_CASTER_HPP
#include <Utils/UtilsAssertHandler.hpp>
#include <type_traits>
#include <EASTL/type_traits.h>
namespace Bigfoot
{
template<class TO, class FROM>
template<class TO,
class FROM,
eastl::enable_if_t<eastl::is_base_of_v<FROM, TO> || eastl::is_base_of_v<TO, FROM>, bool> = true>
constexpr TO* Cast(FROM* p_object)
{
constexpr bool same = std::is_base_of_v<FROM, TO> || std::is_base_of_v<TO, FROM>;
static_assert(same, "Trying to cast to an incompatible type!");
return static_cast<TO*>(p_object);
}
template<class TO, class FROM>
template<class TO,
class FROM,
eastl::enable_if_t<eastl::is_base_of_v<FROM, TO> || eastl::is_base_of_v<TO, FROM>, bool> = true>
constexpr const TO* Cast(const FROM* p_object)
{
constexpr bool same = std::is_base_of_v<FROM, TO> || std::is_base_of_v<TO, FROM>;
static_assert(same, "Trying to cast to an incompatible type!");
return static_cast<const TO*>(p_object);
}
template<class TO, class FROM>
template<class TO,
class FROM,
eastl::enable_if_t<eastl::is_base_of_v<FROM, TO> || eastl::is_base_of_v<TO, FROM>, bool> = true>
constexpr TO& Cast(FROM& p_object)
{
constexpr bool same = std::is_base_of_v<FROM, TO> || std::is_base_of_v<TO, FROM>;
static_assert(same, "Trying to cast to an incompatible type!");
return static_cast<TO&>(p_object);
}
template<class TO, class FROM>
template<class TO,
class FROM,
eastl::enable_if_t<eastl::is_base_of_v<FROM, TO> || eastl::is_base_of_v<TO, FROM>, bool> = true>
constexpr const TO& Cast(const FROM& p_object)
{
constexpr bool same = std::is_base_of_v<FROM, TO> || std::is_base_of_v<TO, FROM>;
static_assert(same, "Trying to cast to an incompatible type!");
return static_cast<const TO&>(p_object);
}
template<typename TO, typename FROM, std::enable_if_t<std::is_integral_v<FROM> && std::is_integral_v<TO>, bool> = true>
constexpr TO NumericCast(const FROM& p_from)
{
const TO to = static_cast<TO>(p_from);
SOFT_ASSERT(UtilsAssertHandler, static_cast<FROM>(to) == p_from, "We are losing data for this cast!");
return to;
}
} // namespace Bigfoot
#define BIGFOOT_NUMERIC_CAST(p_to, p_data) Bigfoot::NumericCast<p_to>(p_data)
-187
View File
@@ -1,187 +0,0 @@
/*********************************************************************
* \file Log.hpp
*
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#ifndef BIGFOOT_UTILS_LOG_HPP
#define BIGFOOT_UTILS_LOG_HPP
#if defined BIGFOOT_NOT_OPTIMIZED
#include <Utils/Singleton.hpp>
#include <magic_enum/magic_enum.hpp>
#ifdef BIGFOOT_WINDOWS
#pragma warning(disable: 4702)
#endif
#include <quill/Backend.h>
#include <quill/Frontend.h>
#include <quill/LogMacros.h>
#include <quill/Logger.h>
#include <quill/sinks/ConsoleSink.h>
#if defined BIGFOOT_WINDOWS
#pragma warning(default: 4702)
#endif
namespace Bigfoot
{
class Log
{
public:
enum class LogLevel
{
Debug,
Trace,
Info,
Warn,
Error,
Critical
};
struct LoggerInfo
{
std::string m_name;
LogLevel m_level;
};
Log();
Log(const Log& p_logger) = delete;
Log(Log&& p_logger) = delete;
/**
* Register a logger.
*
* \param p_loggerInfo The logger to register
*/
[[nodiscard]]
quill::Logger* RegisterLogger(const LoggerInfo& p_loggerInfo);
/**
* Register a logger.
*
* \param p_loggerInfo The logger to get
* \return The logger, nullptr if it does not exist
*/
[[nodiscard]]
quill::Logger* GetLogger(const LoggerInfo& p_loggerInfo);
/**
* Changes the loglevel of a Logger.
*
* \param p_loggerInfo The logger to change
* \param p_level The new level
*/
void ChangeLoggerLogLevel(LoggerInfo& p_loggerInfo, const LogLevel p_level);
~Log();
Log& operator=(const Log& p_logger) = delete;
Log& operator=(Log&& p_logger) = delete;
private:
/**
* Set the LogLevel of a logger
*
* \param p_loggerInfo The logger to set
*/
void SetLoggerLevel(const LoggerInfo& p_loggerInfo);
enum class SinkType
{
Console
};
/*
* The sinks
*/
std::array<std::shared_ptr<quill::Sink>, magic_enum::enum_count<SinkType>()> m_sinks;
};
} // namespace Bigfoot
#define BIGFOOT_LOG_DEBUG(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_DEBUG(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_DEBUG(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_TRACE(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_TRACE_L3(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_TRACE_L3(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_INFO(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_INFO(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_INFO(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_WARN(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_WARNING(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_WARNING(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_ERROR(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_ERROR(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_ERROR(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_FATAL(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_CRITICAL(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_CRITICAL(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#endif
#endif
@@ -6,10 +6,11 @@
*********************************************************************/
#ifndef BIGFOOT_UTILS_SINGLETON_HPP
#define BIGFOOT_UTILS_SINGLETON_HPP
#include <array>
#include <bit>
#include <type_traits>
#include <utility>
#include <EASTL/array.h>
#include <EASTL/bit.h>
#include <EASTL/type_traits.h>
#include <EASTL/utility.h>
namespace Bigfoot
{
@@ -31,7 +32,7 @@ class Singleton
*/
static constexpr TYPE& Instance()
{
return *std::bit_cast<TYPE*>(ms_instance.data());
return *eastl::bit_cast<TYPE*>(ms_instance.data());
}
class Lifetime
@@ -42,10 +43,11 @@ class Singleton
*
* \param p_args Arguments for the singleton
*/
template<typename... ARGS, typename = std::enable_if_t<!(std::is_same_v<Lifetime, std::decay_t<ARGS>> || ...)>>
template<typename... ARGS,
typename = eastl::enable_if_t<!(eastl::is_same_v<Lifetime, eastl::decay_t<ARGS>> || ...)>>
explicit Lifetime(ARGS&&... p_args)
{
Initialize(std::forward<ARGS>(p_args)...);
Initialize(eastl::forward<ARGS>(p_args)...);
}
Lifetime(const Lifetime& p_lifetime) = delete;
@@ -76,7 +78,7 @@ class Singleton
template<typename... ARGS>
static void Initialize(ARGS&&... p_args)
{
new (ms_instance.data()) TYPE(std::forward<ARGS>(p_args)...);
new (ms_instance.data()) TYPE(eastl::forward<ARGS>(p_args)...);
ms_initialized = true;
}
@@ -87,7 +89,7 @@ class Singleton
*/
static void Finalize()
{
std::bit_cast<TYPE*>(ms_instance.data())->~TYPE();
eastl::bit_cast<TYPE*>(ms_instance.data())->~TYPE();
ms_initialized = false;
}
@@ -95,7 +97,7 @@ class Singleton
/**
* The singleton.
*/
alignas(alignof(TYPE)) inline static std::array<std::byte, sizeof(TYPE)> ms_instance;
alignas(alignof(TYPE)) inline static eastl::array<std::byte, sizeof(TYPE)> ms_instance;
/**
* Is the singleton initialized?
@@ -0,0 +1,131 @@
/*********************************************************************
* \file TaggedType.h
*
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#ifndef BIGFOOT_UTILS_TAGGEDTYPE_H
#define BIGFOOT_UTILS_TAGGEDTYPE_H
#include <compare>
namespace Bigfoot
{
template<typename TYPE>
class TaggedType
{
public:
constexpr TaggedType() = default;
constexpr explicit TaggedType(TYPE p_value):
m_value(p_value)
{
}
constexpr TaggedType(const TaggedType& p_taggedType) = default;
constexpr TaggedType(TaggedType&& p_taggedType) noexcept = default;
~TaggedType() = default;
constexpr TaggedType& operator=(const TaggedType& p_taggedType) = default;
constexpr TaggedType& operator=(TaggedType&& p_taggedType) noexcept = default;
constexpr TaggedType& operator=(const TYPE& p_value)
{
m_value = p_value;
return *this;
}
constexpr explicit operator TYPE() const
{
return m_value;
}
constexpr TYPE Get() const
{
return m_value;
}
constexpr auto operator<=>(const TaggedType& p_other) const = default;
constexpr TaggedType& operator+=(const TYPE& p_value)
{
m_value += p_value;
return *this;
}
constexpr TaggedType& operator-=(const TYPE& p_value)
{
m_value -= p_value;
return *this;
}
constexpr TaggedType& operator*=(const TYPE& p_value)
{
m_value *= p_value;
return *this;
}
constexpr TaggedType& operator/=(const TYPE& p_value)
{
m_value /= p_value;
return *this;
}
constexpr TaggedType& operator+=(const TaggedType& p_other)
{
m_value += p_other.m_value;
return *this;
}
constexpr TaggedType& operator-=(const TaggedType& p_other)
{
m_value -= p_other.m_value;
return *this;
}
constexpr TaggedType& operator*=(const TaggedType& p_other)
{
m_value *= p_other.m_value;
return *this;
}
constexpr TaggedType& operator/=(const TaggedType& p_other)
{
m_value /= p_other.m_value;
return *this;
}
template<typename L, typename R>
friend constexpr TaggedType operator+(L p_left, R p_right)
{
return p_left += p_right;
}
template<typename L, typename R>
friend constexpr TaggedType operator-(L p_left, R p_right)
{
return p_left -= p_right;
}
template<typename L, typename R>
friend constexpr TaggedType operator*(L p_left, R p_right)
{
return p_left *= p_right;
}
template<typename L, typename R>
friend constexpr TaggedType operator/(L p_left, R p_right)
{
return p_left /= p_right;
}
private:
/**
* The value
*/
TYPE m_value {};
};
} // namespace Bigfoot
#endif
@@ -1,21 +0,0 @@
@AUTO_GENERATED_COMMENT@
/*********************************************************************
* \file @LOGGER_FILENAME@.generated.hpp
*
*********************************************************************/
#ifndef BIGFOOT_@LOGGER_FILENAME_UPPER@_GENERATED_HPP
#define BIGFOOT_@LOGGER_FILENAME_UPPER@_GENERATED_HPP
#include <Utils/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot
{
/*
* Logger
*/
inline Log::LoggerInfo @LOGGER_NAME@ {"@LOGGER_NAME@", Log::LogLevel::Trace};
}
#endif
#endif
@@ -1,49 +0,0 @@
/*********************************************************************
* \file UtilsAssertHandler.hpp
*
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#ifndef BIGFOOT_UTILS_UTILSASSERTHANDLER_HPP
#define BIGFOOT_UTILS_UTILSASSERTHANDLER_HPP
#include <Utils/Assert.hpp>
#include <format>
#include <source_location>
#include <string_view>
namespace Bigfoot
{
class UtilsAssertHandler
{
public:
UtilsAssertHandler() = delete;
UtilsAssertHandler(const UtilsAssertHandler& p_handler) = delete;
UtilsAssertHandler(UtilsAssertHandler&& p_handler) = delete;
~UtilsAssertHandler() = delete;
/**
* Handle an assertion.
*
* \param p_location Location of the assertion.
* \param p_stacktrace The stack trace
* \param p_format Format string for the assertion message.
* \param p_args Arguments for the format string.
*/
template<typename... ARGS>
static void Handle([[maybe_unused]] const std::source_location& p_location,
[[maybe_unused]] const std::string_view p_stacktrace,
[[maybe_unused]] std::format_string<ARGS...> p_format,
[[maybe_unused]] ARGS&&... p_args)
{
// We dont have access to logging capabilities here
// So no log
}
UtilsAssertHandler& operator=(const UtilsAssertHandler& p_handler) = delete;
UtilsAssertHandler& operator=(UtilsAssertHandler&& p_handler) = delete;
};
} // namespace Bigfoot
#endif
@@ -57,7 +57,7 @@ class Version
{
constexpr std::uint32_t mask = 0b00000000111111110000000000000000;
return BIGFOOT_NUMERIC_CAST(std::uint8_t, (m_combined & mask) >> 16);
return static_cast<std::uint8_t>((m_combined & mask) >> 16);
}
/**
@@ -70,7 +70,7 @@ class Version
{
constexpr std::uint32_t mask = 0b00000000000000001111111100000000;
return BIGFOOT_NUMERIC_CAST(std::uint8_t, (m_combined & mask) >> 8);
return static_cast<std::uint8_t>((m_combined & mask) >> 8);
}
/**
@@ -83,7 +83,7 @@ class Version
{
constexpr std::uint32_t mask = 0b00000000000000000000000011111111;
return BIGFOOT_NUMERIC_CAST(std::uint8_t, (m_combined & mask));
return static_cast<std::uint8_t>(m_combined & mask);
}
[[nodiscard]]
@@ -92,7 +92,8 @@ class Version
return m_combined;
}
[[nodiscard]] operator std::string() const;
[[nodiscard]]
operator std::string() const;
constexpr Version& operator=(const Version& p_version) = default;
-90
View File
@@ -1,90 +0,0 @@
/*******************************************************************
* \file Log.cpp
*
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#include <Utils/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot
{
Log::Log()
{
quill::Backend::start();
m_sinks[magic_enum::enum_integer(SinkType::Console)] = quill::Frontend::create_or_get_sink<quill::ConsoleSink>(
std::string {magic_enum::enum_name(SinkType::Console)});
}
/****************************************************************************************/
quill::Logger* Log::RegisterLogger(const LoggerInfo& p_loggerInfo)
{
quill::Logger* logger = quill::Frontend::create_or_get_logger(p_loggerInfo.m_name,
m_sinks[magic_enum::enum_integer(SinkType::Console)]);
SetLoggerLevel(p_loggerInfo);
return logger;
}
/****************************************************************************************/
quill::Logger* Log::GetLogger(const LoggerInfo& p_loggerInfo)
{
return quill::Frontend::get_logger(p_loggerInfo.m_name);
}
/****************************************************************************************/
void Log::ChangeLoggerLogLevel(LoggerInfo& p_loggerInfo, const LogLevel p_level)
{
p_loggerInfo.m_level = p_level;
SetLoggerLevel(p_loggerInfo);
}
/****************************************************************************************/
void Log::SetLoggerLevel(const LoggerInfo& p_loggerInfo)
{
constexpr auto logLevelToQuillLogLevel = [](const LogLevel p_level) constexpr -> quill::LogLevel
{
switch (p_level)
{
case LogLevel::Debug:
return quill::LogLevel::Debug;
case LogLevel::Trace:
return quill::LogLevel::TraceL3;
case LogLevel::Info:
return quill::LogLevel::Info;
case LogLevel::Warn:
return quill::LogLevel::Warning;
case LogLevel::Error:
return quill::LogLevel::Error;
case LogLevel::Critical:
return quill::LogLevel::Critical;
}
return quill::LogLevel::TraceL3;
};
if (quill::Logger* logger = GetLogger(p_loggerInfo))
{
logger->set_log_level(logLevelToQuillLogLevel(p_loggerInfo.m_level));
}
}
/****************************************************************************************/
Log::~Log()
{
for (quill::Logger* logger: quill::Frontend::get_all_loggers())
{
quill::Frontend::remove_logger(logger);
}
quill::Backend::stop();
}
} // namespace Bigfoot
#endif