From 557f26e6f0b48136b02255ee84b312f7258563b8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 10 Apr 2024 15:58:16 -0400 Subject: [PATCH] include: Fixed up some more documentation. --- include/SDL3/SDL_assert.h | 138 +++++++++++++++++++++++++++++++++++++- include/SDL3/SDL_atomic.h | 26 +++++-- 2 files changed, 157 insertions(+), 7 deletions(-) diff --git a/include/SDL3/SDL_assert.h b/include/SDL3/SDL_assert.h index 1c27484c7..cbf03398e 100644 --- a/include/SDL3/SDL_assert.h +++ b/include/SDL3/SDL_assert.h @@ -116,7 +116,20 @@ disable assertions. #define SDL_disabled_assert(condition) \ do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION) -typedef enum +/** + * Possible outcomes from a triggered assertion. + * + * When an enabled assertion triggers, it may call the assertion handler + * (possibly one provided by the app via SDL_SetAssertionHandler), which + * will return one of these values, possibly after asking the user. + * + * Then SDL will respond based on this outcome (loop around to + * retry the condition, try to break in a debugger, kill the program, or + * ignore the problem). + * + * \since This enum is available since SDL 3.0.0. + */ +typedef enum SDL_AssertState { SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */ SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */ @@ -204,6 +217,104 @@ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *data } while (SDL_NULL_WHILE_LOOP_CONDITION) /* Enable various levels of assertions. */ +#ifdef SDL_WIKI_DOCUMENTATION_SECTION +/** + * An assertion test that is normally performed only in debug builds. + * + * This macro is enabled when the SDL_ASSERT_LEVEL is >= 2, otherwise it + * is disabled. This is meant to only do these tests in debug builds, so + * they can tend to be more expensive, and they are meant to bring everything + * to a halt when they fail, with the programmer there to assess the problem. + * + * In short: you can sprinkle these around liberally and assume they will + * evaporate out of the build when building for end-users. + * + * When assertions are disabled, this wraps `condition` in a `sizeof` + * operator, which means any function calls and side effects will not run, + * but the compiler will not complain about any otherwise-unused variables + * that are only referenced in the assertion. + * + * One can set the environment variable "SDL_ASSERT" to one of several strings + * ("abort", "break", "retry", "ignore", "always_ignore") to force a default + * behavior, which may be desirable for automation purposes. If your platform + * requires GUI interfaces to happen on the main thread but you're debugging + * an assertion in a background thread, it might be desirable to set this to + * "break" so that your debugger takes control as soon as assert is triggered, + * instead of risking a bad UI interaction (deadlock, etc) in the application. + * + * Note that SDL_ASSERT is an _environment variable_ and not an SDL hint! + * Please refer to your platform's documentation for how to set it! + * + * \param condition boolean value to test + * + * \since This macro is available since SDL 3.0.0. + */ +#define SDL_assert(condition) if (assertion_enabled && (condition)) { trigger_assertion; } + +/** + * An assertion test that is performed even in release builds. + * + * This macro is enabled when the SDL_ASSERT_LEVEL is >= 1, otherwise it + * is disabled. This is meant to be for tests that are cheap to make and + * extremely unlikely to fail; generally it is frowned upon to have an + * assertion failure in a release build, so these assertions generally need + * to be of more than life-and-death importance if there's a chance they + * might trigger. You should almost always consider handling these cases more + * gracefully than an assert allows. + * + * When assertions are disabled, this wraps `condition` in a `sizeof` + * operator, which means any function calls and side effects will not run, + * but the compiler will not complain about any otherwise-unused variables + * that are only referenced in the assertion. + * + * One can set the environment variable "SDL_ASSERT" to one of several strings + * ("abort", "break", "retry", "ignore", "always_ignore") to force a default + * behavior, which may be desirable for automation purposes. If your platform + * requires GUI interfaces to happen on the main thread but you're debugging + * an assertion in a background thread, it might be desirable to set this to + * "break" so that your debugger takes control as soon as assert is triggered, + * instead of risking a bad UI interaction (deadlock, etc) in the application. + * + * Note that SDL_ASSERT is an _environment variable_ and not an SDL hint! + * Please refer to your platform's documentation for how to set it! + * + * \param condition boolean value to test + * + * \since This macro is available since SDL 3.0.0. + */ +#define SDL_assert_release(condition) SDL_disabled_assert(condition) + +/** + * An assertion test that is performed only when built with paranoid settings. + * + * This macro is enabled when the SDL_ASSERT_LEVEL is >= 3, otherwise it + * is disabled. This is a higher level than both release and debug, so these + * tests are meant to be expensive and only run when specifically looking + * for extremely unexpected failure cases in a special build. + * + * When assertions are disabled, this wraps `condition` in a `sizeof` + * operator, which means any function calls and side effects will not run, + * but the compiler will not complain about any otherwise-unused variables + * that are only referenced in the assertion. + * + * One can set the environment variable "SDL_ASSERT" to one of several strings + * ("abort", "break", "retry", "ignore", "always_ignore") to force a default + * behavior, which may be desirable for automation purposes. If your platform + * requires GUI interfaces to happen on the main thread but you're debugging + * an assertion in a background thread, it might be desirable to set this to + * "break" so that your debugger takes control as soon as assert is triggered, + * instead of risking a bad UI interaction (deadlock, etc) in the application. + * + * Note that SDL_ASSERT is an _environment variable_ and not an SDL hint! + * Please refer to your platform's documentation for how to set it! + * + * \param condition boolean value to test + * + * \since This macro is available since SDL 3.0.0. + */ +#define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#endif + #if SDL_ASSERT_LEVEL == 0 /* assertions disabled */ # define SDL_assert(condition) SDL_disabled_assert(condition) # define SDL_assert_release(condition) SDL_disabled_assert(condition) @@ -212,7 +323,7 @@ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *data # define SDL_assert(condition) SDL_disabled_assert(condition) # define SDL_assert_release(condition) SDL_enabled_assert(condition) # define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) -#elif SDL_ASSERT_LEVEL == 2 /* normal settings. */ +#elif SDL_ASSERT_LEVEL == 2 /* debug settings. */ # define SDL_assert(condition) SDL_enabled_assert(condition) # define SDL_assert_release(condition) SDL_enabled_assert(condition) # define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) @@ -224,7 +335,28 @@ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *data # error Unknown assertion level. #endif -/* this assertion is never disabled at any level. */ +/** + * An assertion test that always performed. + * + * This macro is always enabled no matter what SDL_ASSERT_LEVEL is set to. + * You almost never want to use this, as it could trigger on an end-user's + * system, crashing your program. + * + * One can set the environment variable "SDL_ASSERT" to one of several strings + * ("abort", "break", "retry", "ignore", "always_ignore") to force a default + * behavior, which may be desirable for automation purposes. If your platform + * requires GUI interfaces to happen on the main thread but you're debugging + * an assertion in a background thread, it might be desirable to set this to + * "break" so that your debugger takes control as soon as assert is triggered, + * instead of risking a bad UI interaction (deadlock, etc) in the application. + * + * Note that SDL_ASSERT is an _environment variable_ and not an SDL hint! + * Please refer to your platform's documentation for how to set it! + * + * \param condition boolean value to test + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_assert_always(condition) SDL_enabled_assert(condition) diff --git a/include/SDL3/SDL_atomic.h b/include/SDL3/SDL_atomic.h index b5ebe0079..52b79a878 100644 --- a/include/SDL3/SDL_atomic.h +++ b/include/SDL3/SDL_atomic.h @@ -338,20 +338,38 @@ extern DECLSPEC int SDLCALL SDL_AtomicGet(SDL_AtomicInt *a); */ extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_AtomicInt *a, int v); +#ifndef SDL_AtomicIncRef /** * Increment an atomic variable used as a reference count. + * + * ***Note: If you don't know what this macro is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicInt to increment. + * \returns the previous value of the atomic variable. + * + * \since This macro is available since SDL 3.0.0. + * + * \sa SDL_AtomicDecRef */ -#ifndef SDL_AtomicIncRef #define SDL_AtomicIncRef(a) SDL_AtomicAdd(a, 1) #endif +#ifndef SDL_AtomicDecRef /** * Decrement an atomic variable used as a reference count. * - * \return SDL_TRUE if the variable reached zero after decrementing, - * SDL_FALSE otherwise + * ***Note: If you don't know what this macro is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicInt to increment. + * \returns SDL_TRUE if the variable reached zero after decrementing, + * SDL_FALSE otherwise + * + * \since This macro is available since SDL 3.0.0. + * + * \sa SDL_AtomicIncRef */ -#ifndef SDL_AtomicDecRef #define SDL_AtomicDecRef(a) (SDL_AtomicAdd(a, -1) == 1) #endif