/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/Engine/Foundation/Basics/Assert.h
189 строк
10 KB
Jan Krassnigg
FMOD, Project Export and other fixes (#1350)
14 июл 2024, 23:06
Не верифицирован
14 июл 2024, 23:06
1c33687
Код
Авторство
О чём код?
#pragma once #ifndef EZ_INCLUDING_BASICS_H # error "Please don't include Assert.h directly, but instead include Foundation/Basics.h" #endif /// \file /// ***** Assert Usage Guidelines ***** /// /// For your typical code, use EZ_ASSERT_DEV to check that vital preconditions are met. /// Be aware that EZ_ASSERT_DEV is removed in non-development builds (ie. when EZ_COMPILE_FOR_DEVELOPMENT is disabled), /// INCLUDING your code in the assert condition. /// If the code that you are checking must be executed, even in non-development builds, use EZ_VERIFY instead. /// EZ_ASSERT_DEV and EZ_VERIFY will trigger a breakpoint in debug builds, but will not interrupt the application /// in release builds. /// /// For conditions that are rarely violated or checking is very costly, use EZ_ASSERT_DEBUG. This assert is only active /// in debug builds. This allows to have extra checking while debugging a program, but not waste performance when a /// development or release build is used. /// /// If you need to check something that is so vital that the application can only fail (i.e. crash), if that condition /// is not met, even in release builds, then use EZ_ASSERT_RELEASE. This should not be used in frequently executed code, /// as it is not stripped from non-development builds by default. /// /// If you need to squeeze the last bit of performance out of your code, EZ_ASSERT_RELEASE can be disabled, by defining /// EZ_DISABLE_RELEASE_ASSERTS. /// Please be aware that EZ_ASSERT_RELEASE works like the other asserts, i.e. once it is deactivated, the code in the condition /// is not executed anymore. /// class ezFormatString; /// \brief Assert handler callback. Should return true to trigger a break point or false if the assert should be ignored using ezAssertHandler = bool (*)(const char* szSourceFile, ezUInt32 uiLine, const char* szFunction, const char* szExpression, const char* szAssertMsg); EZ_FOUNDATION_DLL bool ezDefaultAssertHandler(const char* szSourceFile, ezUInt32 uiLine, const char* szFunction, const char* szExpression, const char* szAssertMsg); /// \brief Gets the current assert handler. The default assert handler shows a dialog on windows or prints to the console on other platforms. EZ_FOUNDATION_DLL ezAssertHandler ezGetAssertHandler(); /// \brief Sets the assert handler. It is the responsibility of the user to chain assert handlers if needed. EZ_FOUNDATION_DLL void ezSetAssertHandler(ezAssertHandler handler); /// \brief Called by the assert macros whenever a check failed. Returns true if the user wants to trigger a break point EZ_FOUNDATION_DLL bool ezFailedCheck(const char* szSourceFile, ezUInt32 uiLine, const char* szFunction, const char* szExpression, const class ezFormatString& msg); EZ_FOUNDATION_DLL bool ezFailedCheck(const char* szSourceFile, ezUInt32 uiLine, const char* szFunction, const char* szExpression, const char* szMsg); /// \brief Dummy version of ezFmt that only takes a single argument inline const char* ezFmt(const char* szFormat) { return szFormat; } #if EZ_ENABLED(EZ_COMPILER_MSVC) // Hides the call to __debugbreak from MSVCs optimizer to work around a bug in VS 2019 // that can lead to code (memcpy) after an assert to be omitted EZ_FOUNDATION_DLL void MSVC_OutOfLine_DebugBreak(...); #endif #ifdef BUILDSYSTEM_CLANG_TIDY [[noreturn]] void ClangTidyDoNotReturn(); # define EZ_REPORT_FAILURE(szErrorMsg, ...) ClangTidyDoNotReturn() #else /// \brief Macro to report a failure when that code is reached. This will ALWAYS be executed, even in release builds, therefore might crash the /// application (or trigger a debug break). # define EZ_REPORT_FAILURE(szErrorMsg, ...) \ do \ { \ if (ezFailedCheck(EZ_SOURCE_FILE, EZ_SOURCE_LINE, EZ_SOURCE_FUNCTION, "", ezFmt(szErrorMsg, ##__VA_ARGS__))) \ EZ_DEBUG_BREAK; \ } while (false) #endif #ifdef BUILDSYSTEM_CLANG_TIDY # define EZ_ASSERT_ALWAYS(bCondition, szErrorMsg, ...) \ do \ { \ if (!!(bCondition) == false) \ ClangTidyDoNotReturn(); \ } while (false) # define EZ_ANALYSIS_ASSUME(bCondition) EZ_ASSERT_ALWAYS(bCondition, "") #else /// \brief Macro to raise an error, if a condition is not met. Allows to write a message using ezFormatString style. This assert will be triggered, even in /// non-development builds and cannot be deactivated. # define EZ_ASSERT_ALWAYS(bCondition, szErrorMsg, ...) \ do \ { \ EZ_MSVC_ANALYSIS_WARNING_PUSH \ EZ_MSVC_ANALYSIS_WARNING_DISABLE(6326) /* disable static analysis for the comparison */ \ if (!!(bCondition) == false) \ { \ if (ezFailedCheck(EZ_SOURCE_FILE, EZ_SOURCE_LINE, EZ_SOURCE_FUNCTION, #bCondition, ezFmt(szErrorMsg, ##__VA_ARGS__))) \ EZ_DEBUG_BREAK; \ } \ EZ_MSVC_ANALYSIS_WARNING_POP \ } while (false) /// \brief Macro to inform the static analysis that the given condition can be assumed to be true. Useful to give additional information to /// static analysis if it can't figure it out by itself. Will do nothing outside of static analysis runs. # define EZ_ANALYSIS_ASSUME(bCondition) #endif /// \brief This type of assert can be used to mark code as 'not (yet) implemented' and makes it easier to find it later on by just searching for these /// asserts. #define EZ_ASSERT_NOT_IMPLEMENTED EZ_REPORT_FAILURE("Not implemented"); // Occurrences of EZ_ASSERT_DEBUG are compiled out in non-debug builds #if EZ_ENABLED(EZ_COMPILE_FOR_DEBUG) /// \brief Macro to raise an error, if a condition is not met. /// /// Allows to write a message using ezFormatString style. /// Compiled out in non-debug builds. /// The condition is not evaluated, when this is compiled out, so do not execute important code in it. # define EZ_ASSERT_DEBUG EZ_ASSERT_ALWAYS #else /// \brief Macro to raise an error, if a condition is not met. /// /// Allows to write a message using ezFormatString style. /// Compiled out in non-debug builds. /// The condition is not evaluated, when this is compiled out, so do not execute important code in it. # define EZ_ASSERT_DEBUG(bCondition, szErrorMsg, ...) #endif // Occurrences of EZ_ASSERT_DEV are compiled out in non-development builds #if EZ_ENABLED(EZ_COMPILE_FOR_DEVELOPMENT) /// \brief Macro to raise an error, if a condition is not met. /// /// Allows to write a message using ezFormatString style. /// Compiled out in non-development builds. /// The condition is not evaluated, when this is compiled out, so do not execute important code in it. # define EZ_ASSERT_DEV EZ_ASSERT_ALWAYS /// \brief Macro to raise an error, if a condition is not met. /// /// Allows to write a message using ezFormatString style. /// Compiled out in non-development builds, however the condition is always evaluated, /// so you may execute important code in it. # define EZ_VERIFY EZ_ASSERT_ALWAYS #else /// \brief Macro to raise an error, if a condition is not met. /// /// Allows to write a message using ezFormatString style. /// Compiled out in non-development builds. /// The condition is not evaluated, when this is compiled out, so do not execute important code in it. # define EZ_ASSERT_DEV(bCondition, szErrorMsg, ...) /// \brief Macro to raise an error, if a condition is not met. /// /// Allows to write a message using ezFormatString style. /// Compiled out in non-development builds, however the condition is always evaluated, /// so you may execute important code in it. # define EZ_VERIFY(bCondition, szErrorMsg, ...) \ if (!!(bCondition) == false) \ { /* The condition is evaluated, even though nothing is done with it. */ \ } #endif #if EZ_DISABLE_RELEASE_ASSERTS /// \brief An assert to check conditions even in release builds. /// /// These asserts can be disabled (and then their condition will not be evaluated), /// but this needs to be specifically done by the user by defining EZ_DISABLE_RELEASE_ASSERTS. /// That should only be done, if you are intending to ship a product, and want get rid of all unnecessary overhead. # define EZ_ASSERT_RELEASE(bCondition, szErrorMsg, ...) #else /// \brief An assert to check conditions even in release builds. /// /// These asserts can be disabled (and then their condition will not be evaluated), /// but this needs to be specifically done by the user by defining EZ_DISABLE_RELEASE_ASSERTS. /// That should only be done, if you are intending to ship a product, and want get rid of all unnecessary overhead. # define EZ_ASSERT_RELEASE EZ_ASSERT_ALWAYS #endif /// \brief Macro to make unhandled cases in a switch block an error. #define EZ_DEFAULT_CASE_NOT_IMPLEMENTED \ default: \ EZ_ASSERT_NOT_IMPLEMENTED \ break;