Add Assert and AssertOnce macros

This commit is contained in:
DankParrot 2020-08-22 18:44:28 -07:00
parent b95362113b
commit e37883a9bb
3 changed files with 51 additions and 5 deletions

View File

@ -108,7 +108,7 @@ namespace Feather
{
#ifdef _DEBUG
// You must call Finalize() first
assert(m_finalized);
Assert(m_finalized, "NetworkMessage sent or resolved before Finalize() was called.");
#endif
return &m_data[m_startOffset];
}
@ -117,7 +117,7 @@ namespace Feather
{
#ifdef _DEBUG
// You must call Finalize() first
assert(m_finalized);
Assert(m_finalized, "NetworkMessage sent or resolved before Finalize() was called.");
#endif
return m_data.size() - m_startOffset;
}

View File

@ -8,10 +8,40 @@
//#define FEATHER_LOG_COLUMNS
#ifdef _DEBUG
// Prints an error if 'expr' is not false. Message is optional.
#define Assert(expr,/* fmt, */...) \
do { \
if (!(expr)) { \
Feather::Log::Logger::Instance().LogAssert(Feather::Log::Channels::General, __FILE__, __LINE__, #expr, ##__VA_ARGS__); \
} \
} while (0)
// Asserts an expression once only.
#define AssertOnce(expr,/* fmt, */...) \
do { \
static bool asserted = false; \
if (!(expr) && !asserted) { \
asserted = true; \
Feather::Log::Logger::Instance().LogAssert(Feather::Log::Channels::General, __FILE__, __LINE__, #expr, ##__VA_ARGS__); \
} \
} while (0)
#else // !defined(_DEBUG)
#define Assert(expr,...) ((void)0)
#define AssertOnce(expr,...) ((void)0)
#endif
namespace Feather::Log
{
enum class Level
{
// Failed assertions
Assert = -3,
// Serious problems
Error = -2,
@ -32,6 +62,7 @@ namespace Feather::Log
{
switch (level)
{
case Level::Assert: return "Assert";
case Level::Error: return "Error";
case Level::Warning: return "Warning";
case Level::Info: return "Info";
@ -55,9 +86,10 @@ namespace Feather::Log
switch (level)
{
default:
case Level::Info: return fmt::fg(fmt::color::white);
case Level::Assert: return fmt::fg(fmt::color::orange_red);
case Level::Error: return fmt::fg(fmt::color::crimson);
case Level::Warning: return fmt::fg(fmt::color::yellow);
case Level::Info: return fmt::fg(fmt::color::white);
case Level::Debug: return fmt::fg(fmt::color::rebecca_purple);
case Level::Trace: return fmt::fg(fmt::color::aquamarine);
}
@ -125,7 +157,21 @@ namespace Feather::Log
LogRaw(fmt, args...);
LogRaw("\n");
#endif
}
// Prints message for a failed assertion. Use the Assert or AssertOnce macros instead of calling this directly.
template <class S, typename... Args>
void LogAssert(ChannelID channel, const char* file, uint64_t lineNum, const char* expr, const S& fmt, Args... args)
{
std::string msg = fmt::format("{} ({}): {}", file, lineNum, fmt);
Log(channel, Level::Assert, msg, args...);
}
// Prints message for a failed assertion. Use the Assert or AssertOnce macros instead of calling this directly.
void LogAssert(ChannelID channel, const char* file, uint64_t lineNum, const char* expr)
{
// When no message is provided we print the asserted expression instead
Log(channel, Level::Assert, "{} ({}): Assertion failed: {}", file, lineNum, expr);
}
ChannelID RegisterChannel(const char* name);

View File

@ -94,7 +94,7 @@ namespace Feather
continue;
}
assert(blockStates.GetLength() < ChunkSection::MaximumLongCount);
Assert(blockStates.GetLength() < ChunkSection::MaximumLongCount);
for (size_t i = 0; i < blockStates.GetLength(); i++)
section->blockStates[i] = blockStates[i];