diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..1df6c35 --- /dev/null +++ b/.clang-format @@ -0,0 +1,199 @@ +# Commented out parameters are those with the same value as base LLVM style. +# We can uncomment them if we want to change their value, or enforce the +# chosen value in case the base style changes (last sync: Clang 14.0). +--- +### General config, applies to all languages ### +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +# AlignArrayOfStructures: None +# AlignConsecutiveMacros: None +# AlignConsecutiveAssignments: None +# AlignConsecutiveBitFields: None +# AlignConsecutiveDeclarations: None +# AlignEscapedNewlines: Right +AlignOperands: DontAlign +AlignTrailingComments: false +# AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +# AllowShortEnumsOnASingleLine: true +# AllowShortBlocksOnASingleLine: Never +# AllowShortCaseLabelsOnASingleLine: false +# AllowShortFunctionsOnASingleLine: All +# AllowShortLambdasOnASingleLine: All +# AllowShortIfStatementsOnASingleLine: Never +# AllowShortLoopsOnASingleLine: false +# AlwaysBreakAfterDefinitionReturnType: None +# AlwaysBreakAfterReturnType: None +# AlwaysBreakBeforeMultilineStrings: false +# AlwaysBreakTemplateDeclarations: MultiLine +# AttributeMacros: +# - __capability +# BinPackArguments: true +# BinPackParameters: true +# BraceWrapping: +# AfterCaseLabel: false +# AfterClass: false +# AfterControlStatement: Never +# AfterEnum: false +# AfterFunction: false +# AfterNamespace: false +# AfterObjCDeclaration: false +# AfterStruct: false +# AfterUnion: false +# AfterExternBlock: false +# BeforeCatch: false +# BeforeElse: false +# BeforeLambdaBody: false +# BeforeWhile: false +# IndentBraces: false +# SplitEmptyFunction: true +# SplitEmptyRecord: true +# SplitEmptyNamespace: true +# BreakBeforeBinaryOperators: None +# BreakBeforeConceptDeclarations: true +# BreakBeforeBraces: Attach +# BreakBeforeInheritanceComma: false +# BreakInheritanceList: BeforeColon +# BreakBeforeTernaryOperators: true +# BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: AfterColon +# BreakStringLiterals: true +ColumnLimit: 0 +# CommentPragmas: '^ IWYU pragma:' +# QualifierAlignment: Leave +# CompactNamespaces: false +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +Cpp11BracedListStyle: false +# DeriveLineEnding: true +# DerivePointerAlignment: false +# DisableFormat: false +# EmptyLineAfterAccessModifier: Never +# EmptyLineBeforeAccessModifier: LogicalBlock +# ExperimentalAutoDetectBinPacking: false +# PackConstructorInitializers: BinPack +ConstructorInitializerAllOnOneLineOrOnePerLine: true +# AllowAllConstructorInitializersOnNextLine: true +# FixNamespaceComments: true +# ForEachMacros: +# - foreach +# - Q_FOREACH +# - BOOST_FOREACH +# IfMacros: +# - KJ_IF_MAYBE +# IncludeBlocks: Preserve +IncludeCategories: + - Regex: '".*"' + Priority: 1 + - Regex: '^<.*\.h>' + Priority: 2 + - Regex: '^<.*' + Priority: 3 +# IncludeIsMainRegex: '(Test)?$' +# IncludeIsMainSourceRegex: '' +# IndentAccessModifiers: false +IndentCaseLabels: true +# IndentCaseBlocks: false +# IndentGotoLabels: true +# IndentPPDirectives: None +# IndentExternBlock: AfterExternBlock +# IndentRequires: false +IndentWidth: 4 +# IndentWrappedFunctionNames: false +# InsertTrailingCommas: None +# JavaScriptQuotes: Leave +# JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +# LambdaBodyIndentation: Signature +# MacroBlockBegin: '' +# MacroBlockEnd: '' +# MaxEmptyLinesToKeep: 1 +# NamespaceIndentation: None +# PenaltyBreakAssignment: 2 +# PenaltyBreakBeforeFirstCallParameter: 19 +# PenaltyBreakComment: 300 +# PenaltyBreakFirstLessLess: 120 +# PenaltyBreakOpenParenthesis: 0 +# PenaltyBreakString: 1000 +# PenaltyBreakTemplateDeclaration: 10 +# PenaltyExcessCharacter: 1000000 +# PenaltyReturnTypeOnItsOwnLine: 60 +# PenaltyIndentedWhitespace: 0 +# PointerAlignment: Right +# PPIndentWidth: -1 +# ReferenceAlignment: Pointer +# ReflowComments: true +# RemoveBracesLLVM: false +# SeparateDefinitionBlocks: Leave +# ShortNamespaceLines: 1 +# SortIncludes: CaseSensitive +# SortJavaStaticImport: Before +# SortUsingDeclarations: true +# SpaceAfterCStyleCast: false +# SpaceAfterLogicalNot: false +# SpaceAfterTemplateKeyword: true +# SpaceBeforeAssignmentOperators: true +# SpaceBeforeCaseColon: false +# SpaceBeforeCpp11BracedList: false +# SpaceBeforeCtorInitializerColon: true +# SpaceBeforeInheritanceColon: true +# SpaceBeforeParens: ControlStatements +# SpaceBeforeParensOptions: +# AfterControlStatements: true +# AfterForeachMacros: true +# AfterFunctionDefinitionName: false +# AfterFunctionDeclarationName: false +# AfterIfMacros: true +# AfterOverloadedOperator: false +# BeforeNonEmptyParentheses: false +# SpaceAroundPointerQualifiers: Default +# SpaceBeforeRangeBasedForLoopColon: true +# SpaceInEmptyBlock: false +# SpaceInEmptyParentheses: false +# SpacesBeforeTrailingComments: 1 +# SpacesInAngles: Never +# SpacesInConditionalStatement: false +# SpacesInContainerLiterals: true +# SpacesInCStyleCastParentheses: false +## Godot TODO: We'll want to use a min of 1, but we need to see how to fix +## our comment capitalization at the same time. +SpacesInLineCommentPrefix: + Minimum: 0 + Maximum: -1 +# SpacesInParentheses: false +# SpacesInSquareBrackets: false +# SpaceBeforeSquareBrackets: false +# BitFieldColonSpacing: Both +# StatementAttributeLikeMacros: +# - Q_EMIT +# StatementMacros: +# - Q_UNUSED +# - QT_REQUIRE_VERSION +TabWidth: 4 +# UseCRLF: false +UseTab: Always +# WhitespaceSensitiveMacros: +# - STRINGIZE +# - PP_STRINGIZE +# - BOOST_PP_STRINGIZE +# - NS_SWIFT_NAME +# - CF_SWIFT_NAME +--- +### C++ specific config ### +Language: Cpp +Standard: c++17 +--- +### ObjC specific config ### +Language: ObjC +# ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +# ObjCBreakBeforeNestedBlockParam: true +# ObjCSpaceAfterProperty: false +# ObjCSpaceBeforeProtocolList: true +--- +### Java specific config ### +Language: Java +# BreakAfterJavaFieldAnnotations: false +JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax'] +... diff --git a/aster_core/CMakeLists.txt b/aster_core/CMakeLists.txt index 26aaaa6..cbf283d 100644 --- a/aster_core/CMakeLists.txt +++ b/aster_core/CMakeLists.txt @@ -4,12 +4,15 @@ cmake_minimum_required( VERSION 3.13 ) find_package( glm CONFIG REQUIRED ) find_path( SCOTTT_DEBUGBREAK_INCLUDE_DIRS "debugbreak.h" ) +find_package( VulkanHeaders CONFIG REQUIRED ) +find_package( VulkanMemoryAllocator CONFIG REQUIRED ) -set( HEADER_FILES "constants.h" "config.h" "logger.h" ) -set( SOURCE_FILES "logger.cpp" ) +set( HEADER_FILES "constants.h" "config.h" "logger.h" "global.h" ) +set( SOURCE_FILES "logger.cpp" "global.cpp" ) add_library( aster_core "aster.cpp" ${SOURCE_FILES} ${HEADER_FILES} ) set_property( TARGET aster_core PROPERTY CXX_STANDARD 20 ) target_link_libraries( aster_core PRIVATE glm::glm-header-only ) target_include_directories( aster_core PRIVATE ${SCOTTT_DEBUGBREAK_INCLUDE_DIRS}) +target_link_libraries( aster_core PRIVATE Vulkan::Headers GPUOpen::VulkanMemoryAllocator ) diff --git a/aster_core/constants.h b/aster_core/constants.h index 9103cda..47f6b55 100644 --- a/aster_core/constants.h +++ b/aster_core/constants.h @@ -29,7 +29,7 @@ using b32 = u32; using usize = size_t; using p64 = intptr_t; -constexpr usize strlen_c(const char* s) { +constexpr usize strlen_c(const char *s) { return *s == '\0' ? 0 : 1 + strlen_c(s + 1); } @@ -43,37 +43,37 @@ constexpr auto ANSI_Cyan = "\u001b[36m"; constexpr auto ANSI_White = "\u001b[37m"; constexpr auto ANSI_Reset = "\u001b[0m"; -using std::move; using std::forward; +using std::move; using std::tie; template using Option = std::optional; template -constexpr auto cast(from_t&& _in) { +constexpr auto cast(from_t &&_in) { return static_cast(forward(_in)); } template -constexpr auto recast(from_t&& _in) { +constexpr auto recast(from_t &&_in) { return reinterpret_cast(forward(_in)); } -constexpr f32 operator ""_deg(long double degrees) { +constexpr f32 operator""_deg(long double degrees) { return glm::radians(cast(degrees)); } -constexpr f32 operator ""_deg(unsigned long long int degrees) { +constexpr f32 operator""_deg(unsigned long long int degrees) { return glm::radians(cast(degrees)); } -constexpr f32 operator ""_rad(long double rads) { - return cast(rads); +constexpr f32 operator""_rad(long double rads) { + return cast(rads); } -constexpr f32 operator ""_rad(unsigned long long int rads) { - return cast(rads); +constexpr f32 operator""_rad(unsigned long long int rads) { + return cast(rads); } using glm::ivec2; @@ -87,7 +87,7 @@ using glm::mat2; using glm::mat3; using glm::mat4; -constexpr const char* PROJECT_NAME = "Aster"; +constexpr const char *PROJECT_NAME = "Aster"; struct Version { u32 major; diff --git a/aster_core/global.cpp b/aster_core/global.cpp new file mode 100644 index 0000000..f348ee6 --- /dev/null +++ b/aster_core/global.cpp @@ -0,0 +1,74 @@ +// ============================================= +// Aster: global.cpp +// Copyright (c) 2020-2024 Anish Bhobe +// ============================================= + +#include "global.h" + +#include +#include + +#pragma warning(push, 0) +#define VMA_IMPLEMENTATION +#include +#pragma warning(pop) + +// NOTE: Vulkan Dispatch Loader Storage - Should only appear once. +VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE + +//int Vsnprintf8(char* pDestination, size_t n, const char* pFormat, va_list arguments) { +// //ERROR_IF(pDestination == nullptr, "Null buffer") THEN_CRASH(1) ELSE_IF_ERROR(n == 0, "Empty buffer") THEN_CRASH(1); +//#ifdef _MSC_VER +// auto v = vsnprintf(pDestination, n, pFormat, arguments); +// ERROR_IF(v == 0, "Final requirement cannot be 0") THEN_CRASH(1); +// return v; +//#else +// return vsnprintf(pDestination, n, pFormat, arguments); +//#endif +//} +// +//int VsnprintfW(wchar_t* pDestination, size_t n, const wchar_t* pFormat, va_list arguments) { +// //ERROR_IF(pDestination == nullptr, "Null buffer") THEN_CRASH(1) ELSE_IF_ERROR(n == 0, "Empty buffer") THEN_CRASH(1); +//#ifdef _MSC_VER +// if (pDestination == nullptr && n == 0) { +// return _vscwprintf(pFormat, arguments); +// } else { +// return _vsnwprintf_s(pDestination, n, _TRUNCATE, pFormat, arguments); +// } +//#else +// char* d = new char[n + 1]; +// int r = vsnprintf(d, n, convertstring(pFormat).c_str(), arguments); +// memcpy(pDestination, convertstring(d).c_str(), (n + 1) * sizeof(char16_t)); +// delete[] d; +// return r; +//#endif +//} +// +//int Vsnprintf16(char16_t* pDestination, size_t n, const char16_t* pFormat, va_list arguments) { +// //ERROR_IF(pDestination == nullptr, "Null buffer") THEN_CRASH(1) ELSE_IF_ERROR(n == 0, "Empty buffer") THEN_CRASH(1); +//#ifdef _MSC_VER +// if (pDestination == nullptr && n == 0) { +// return _vscwprintf((wchar_t*)pFormat, arguments); +// } else { +// return _vsnwprintf_s((wchar_t*)pDestination, n, _TRUNCATE, (wchar_t*)pFormat, arguments); +// } +//#else +// char* d = new char[n + 1]; +// int r = vsnprintf(d, n, convertstring(pFormat).c_str(), arguments); +// memcpy(pDestination, convertstring(d).c_str(), (n + 1) * sizeof(char16_t)); +// delete[] d; +// return r; +//#endif +//} + +std::string std::impl::format(const char *_fmt, ...) { + va_list args; + va_start(args, _fmt); + + const auto req = vsnprintf(nullptr, 0, _fmt, args) + 1; + string buf(req, '\0'); + vsnprintf(buf.data(), buf.size(), _fmt, args); + + va_end(args); + return buf; +} diff --git a/aster_core/global.h b/aster_core/global.h new file mode 100644 index 0000000..f621047 --- /dev/null +++ b/aster_core/global.h @@ -0,0 +1,103 @@ +// ============================================= +// Aster: global.h +// Copyright (c) 2020-2024 Anish Bhobe +// ============================================= + +#pragma once + +#include "config.h" +#include "constants.h" +#include "logger.h" + +#include +#include +#include +#include + +#define VULKAN_HPP_ASSERT(expr) DEBUG_IF(!(expr), "Vulkan assert failed") +#include + +#pragma warning(push, 0) +#include +#pragma warning(pop) + +#define CODE_LOC " @ " __FILE__ ":" VULKAN_HPP_STRINGIFY(__LINE__) +[[nodiscard]] inline bool failed(const vk::Result _result) { + return _result != vk::Result::eSuccess; +} + +namespace std { +namespace impl { +string format(const char *_fmt, ...); +} + +template +[[nodiscard]] string fmt(const char *_fmt, Ts &&..._args) { + return impl::format(_fmt, forward(_args)...); +} +} // namespace std + +template +concept IsVkEnum = requires(T _t) { + { std::is_enum_v }; + { vk::to_string(_t) } -> std::same_as; +}; + +template +requires IsVkEnum [[nodiscard]] const char *to_cstr(const T &_val) { + static std::string buffer; + buffer = vk::to_string(_val); + return buffer.c_str(); +} + +// TODO: Check why inline namespaces aren't working in MSVC 19.27.29110 +using namespace std::literals::string_literals; +using namespace std::literals::string_view_literals; + +template +requires vk::isVulkanHandleType::value [[nodiscard]] constexpr u64 +get_vk_handle(const T &_vk_handle) noexcept { + return reinterpret_cast(cast(_vk_handle)); +} + +template +struct std::hash> { + [[nodiscard]] usize operator()(const vk::Flags &_val) { + return std::hash()(cast(_val)); + } +}; + +template +[[nodiscard]] usize hash_any(const T &_val) { + return std::hash>()(_val); +} + +[[nodiscard]] inline usize hash_combine(const usize _hash0, + const usize _hash1) { + constexpr usize salt_value = 0x9e3779b9; + return _hash0 ^ (_hash1 + salt_value + (_hash0 << 6) + (_hash0 >> 2)); +} + +struct Time { + static constexpr f64 max_delta = 0.1; + + inline static f64 elapsed{ qnan }; + inline static f64 delta{ qnan }; + + static void init() { + WARN_IF(!std::isnan(elapsed), "Time already init."); + elapsed = glfwGetTime(); + delta = 1.0 / 60.0; + } + + static void update() { + ERROR_IF(std::isnan(elapsed), "Time not init."); + const auto new_elapsed = glfwGetTime(); + delta = std::clamp(new_elapsed - elapsed, 0.0, max_delta); + elapsed = new_elapsed; + } +}; + +[[nodiscard]] inline usize closest_multiple(const usize _val, const usize _of) { + return _of * ((_val + _of - 1) / _of); +} diff --git a/aster_core/logger.cpp b/aster_core/logger.cpp index 271bb51..cdc2f6b 100644 --- a/aster_core/logger.cpp +++ b/aster_core/logger.cpp @@ -1,17 +1,17 @@ -// ============================================= -// Aster: logger.cc -// Copyright (c) 2020-2021 Anish Bhobe -// ============================================= - -#include "logger.h" - -Logger g_logger = Logger(); - -/* Credits to Const-me */ -//namespace eastl { -// void __cdecl AssertionFailure(const char* af) -// { -// ERROR(af); -// __debugbreak(); -// } -//} +// ============================================= +// Aster: logger.cpp +// Copyright (c) 2020-2024 Anish Bhobe +// ============================================= + +#include "logger.h" + +Logger g_logger = Logger(); + +/* Credits to Const-me */ +//namespace eastl { +// void __cdecl AssertionFailure(const char* af) +// { +// ERROR(af); +// __debugbreak(); +// } +//} diff --git a/aster_core/logger.h b/aster_core/logger.h index 94cc579..895c175 100644 --- a/aster_core/logger.h +++ b/aster_core/logger.h @@ -1,13 +1,13 @@ // ============================================= // Aster: logger.h -// Copyright (c) 2020-2021 Anish Bhobe +// Copyright (c) 2020-2024 Anish Bhobe // ============================================= #pragma once #include "constants.h" -#include #include +#include struct Logger { enum class LogType : u32 { @@ -25,25 +25,35 @@ struct Logger { } template - constexpr static const char* to_cstr() { - if constexpr (LogLevel == LogType::eError) return "[ERROR]:"; - if constexpr (LogLevel == LogType::eWarning) return "[WARN]: "; - if constexpr (LogLevel == LogType::eInfo) return "[INFO]: "; - if constexpr (LogLevel == LogType::eDebug) return "[DEBUG]:"; - if constexpr (LogLevel == LogType::eVerbose) return "[VERB]: "; + constexpr static const char *to_cstr() { + if constexpr (LogLevel == LogType::eError) + return "[ERROR]:"; + if constexpr (LogLevel == LogType::eWarning) + return "[WARN]: "; + if constexpr (LogLevel == LogType::eInfo) + return "[INFO]: "; + if constexpr (LogLevel == LogType::eDebug) + return "[DEBUG]:"; + if constexpr (LogLevel == LogType::eVerbose) + return "[VERB]: "; } template - constexpr static const char* to_color_cstr() { - if constexpr (LogLevel == LogType::eError) return ANSI_Red; - if constexpr (LogLevel == LogType::eWarning) return ANSI_Yellow; - if constexpr (LogLevel == LogType::eInfo) return ANSI_Green; - if constexpr (LogLevel == LogType::eDebug) return ANSI_White; - if constexpr (LogLevel == LogType::eVerbose) return ANSI_Blue; + constexpr static const char *to_color_cstr() { + if constexpr (LogLevel == LogType::eError) + return ANSI_Red; + if constexpr (LogLevel == LogType::eWarning) + return ANSI_Yellow; + if constexpr (LogLevel == LogType::eInfo) + return ANSI_Green; + if constexpr (LogLevel == LogType::eDebug) + return ANSI_White; + if constexpr (LogLevel == LogType::eVerbose) + return ANSI_Blue; } template - void log(const std::string_view& _message, const char* _loc, u32 _line) const { + void log(const std::string_view &_message, const char *_loc, u32 _line) const { if (cast(LogLevel) <= minimum_logging_level) { printf("%s%s %s%s| at %s:%u%s\n", to_color_cstr(), to_cstr(), _message.data(), ANSI_Black, _loc, _line, ANSI_Reset); } @@ -55,7 +65,7 @@ struct Logger { } template - void log_cond(const char* _expr_str, const std::string_view& _message, const char* _loc, u32 _line) const { + void log_cond(const char *_expr_str, const std::string_view &_message, const char *_loc, u32 _line) const { if (cast(LogLevel) <= minimum_logging_level) { printf("%s%s (%s) %s%s| at %s:%u%s\n", to_color_cstr(), to_cstr(), _expr_str, _message.data(), ANSI_Black, _loc, _line, ANSI_Reset); } @@ -73,50 +83,96 @@ extern Logger g_logger; #define WARN(msg) g_logger.log(msg, __FILE__, __LINE__) #define INFO(msg) g_logger.log(msg, __FILE__, __LINE__) -#define ERROR_IF(expr, msg) if (cast(expr)) [[unlikely]] g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define WARN_IF(expr, msg) if (cast(expr)) [[unlikely]] g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define INFO_IF(expr, msg) if (cast(expr)) g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define ERROR_IF(expr, msg) \ + if (cast(expr)) [[unlikely]] \ + g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define WARN_IF(expr, msg) \ + if (cast(expr)) [[unlikely]] \ + g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define INFO_IF(expr, msg) \ + if (cast(expr)) \ + g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define ELSE_IF_ERROR(expr, msg) ;else if (cast(expr)) [[unlikely]] g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define ELSE_IF_WARN(expr, msg) ;else if (cast(expr)) [[unlikely]] g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define ELSE_IF_INFO(expr, msg) ;else if (cast(expr)) g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define ELSE_IF_ERROR(expr, msg) \ + ; \ + else if (cast(expr)) [[unlikely]] g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define ELSE_IF_WARN(expr, msg) \ + ; \ + else if (cast(expr)) [[unlikely]] g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define ELSE_IF_INFO(expr, msg) \ + ; \ + else if (cast(expr)) g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define ELSE_ERROR(msg) ;else [[unlikely]] g_logger.log(msg, __FILE__, __LINE__) -#define ELSE_WARN(msg) ;else [[unlikely]] g_logger.log(msg, __FILE__, __LINE__) -#define ELSE_INFO(msg) ;else g_logger.log(msg, __FILE__, __LINE__) +#define ELSE_ERROR(msg) \ + ; \ + else [[unlikely]] g_logger.log(msg, __FILE__, __LINE__) +#define ELSE_WARN(msg) \ + ; \ + else [[unlikely]] g_logger.log(msg, __FILE__, __LINE__) +#define ELSE_INFO(msg) \ + ; \ + else g_logger.log(msg, __FILE__, __LINE__) #if !defined(DEBUG_LOG_DISABLED) && !defined(NDEBUG) #define DEBUG(msg) g_logger.log(msg, __FILE__, __LINE__) -#define DEBUG_IF(expr, msg) if (cast(expr)) g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define ELSE_IF_DEBUG(expr, msg) ;else if (cast(expr)) g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define ELSE_DEBUG(msg) ;else [[unlikely]] g_logger.log(msg, __FILE__, __LINE__) +#define DEBUG_IF(expr, msg) \ + if (cast(expr)) \ + g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define ELSE_IF_DEBUG(expr, msg) \ + ; \ + else if (cast(expr)) g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define ELSE_DEBUG(msg) \ + ; \ + else [[unlikely]] g_logger.log(msg, __FILE__, __LINE__) #else // !defined(DEBUG_LOG_DISABLED) -#define DEBUG(msg) {} -#define DEBUG_IF(expr, msg) if (expr) (void)msg -#define ELSE_IF_DEBUG(expr, msg) ;if (expr) (void)msg -#define ELSE_DEBUG(msg) ;{} +#define DEBUG(msg) \ + {} +#define DEBUG_IF(expr, msg) \ + if (expr) \ + (void)msg +#define ELSE_IF_DEBUG(expr, msg) \ + ; \ + if (expr) \ + (void)msg +#define ELSE_DEBUG(msg) \ + ; \ + {} #endif // !defined(DEBUG_LOG_DISABLED) #if !defined(VERBOSE_LOG_DISABLED) && !defined(NDEBUG) #define VERBOSE(msg) g_logger.log(msg, __FILE__, __LINE__) -#define VERBOSE_IF(expr, msg) if (cast(expr)) g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define ELSE_IF_VERBOSE(expr, msg) ;else if (cast(expr)) g_logger.log_cond(#expr, msg, __FILE__, __LINE__) -#define ELSE_VERBOSE(msg) ;else g_logger.log(msg, __FILE__, __LINE__) +#define VERBOSE_IF(expr, msg) \ + if (cast(expr)) \ + g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define ELSE_IF_VERBOSE(expr, msg) \ + ; \ + else if (cast(expr)) g_logger.log_cond(#expr, msg, __FILE__, __LINE__) +#define ELSE_VERBOSE(msg) \ + ; \ + else g_logger.log(msg, __FILE__, __LINE__) #else // !defined(DEBUG_LOG_DISABLED) -#define VERBOSE(msg) {} -#define VERBOSE_IF(expr, msg) if (expr) (void)msg -#define ELSE_IF_VERBOSE(expr, msg) ;if (expr) (void)msg -#define ELSE_VERBOSE(msg) ;{} +#define VERBOSE(msg) \ + {} +#define VERBOSE_IF(expr, msg) \ + if (expr) \ + (void)msg +#define ELSE_IF_VERBOSE(expr, msg) \ + ; \ + if (expr) \ + (void)msg +#define ELSE_VERBOSE(msg) \ + ; \ + {} #endif // !defined(VERBOSE_LOG_DISABLED) #define DO(code) , code #define CRASH(code) exit(cast(code)) -#define THEN_CRASH(code) ,CRASH(code) +#define THEN_CRASH(code) , CRASH(code) diff --git a/vcpkg.json b/vcpkg.json index 3dad767..d55b7c7 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -2,6 +2,7 @@ "dependencies": [ "glfw3", "glm", - "scottt-debugbreak" + "scottt-debugbreak", + "vulkan-memory-allocator" ] }