Wed, 30 Jul 2025 00:12:13 +0200
improve the conditional setting of flags
src/2d.c | file | annotate | diff | comparison | revisions | |
src/ascension/datatypes.h | file | annotate | diff | comparison | revisions |
--- a/src/2d.c Mon Jul 28 23:11:30 2025 +0200 +++ b/src/2d.c Wed Jul 30 00:12:13 2025 +0200 @@ -91,7 +91,10 @@ const bool border = rectangle->thickness > 0; // Compute shader flags - int flags = asc_create_flags(1, 3, filled, round, border); + int flags = 0; + asc_set_flag_if(flags, ASC_RECTANGLE_SHADER_FLAG_FILL, filled); + asc_set_flag_if(flags, ASC_RECTANGLE_SHADER_FLAG_ROUND, round); + asc_set_flag_if(flags, ASC_RECTANGLE_SHADER_FLAG_BORDER, border); // Look up and activate the shader const AscShaderProgram *shader = asc_shader_lookup_or_create( @@ -222,12 +225,14 @@ const bool border = ellipsis->thickness > 0; // Compute shader flags - int shader_flags = asc_create_flags(1, 2, filled, border); + int flags = 0; + asc_set_flag_if(flags, ASC_ELLIPSIS_SHADER_FLAG_FILL, filled); + asc_set_flag_if(flags, ASC_ELLIPSIS_SHADER_FLAG_BORDER, border); // Look up and activate the shader const AscShaderProgram *shader = asc_shader_lookup_or_create( - ASC_SHADER_ELLIPSIS(shader_flags), - asc_ellipsis_shader_create, shader_flags + ASC_SHADER_ELLIPSIS(flags), + asc_ellipsis_shader_create, flags ); if (asc_shader_use(shader, camera)) return; asc_cptr_cast(AscEllipsisShader, ellipsis_shader, shader);
--- a/src/ascension/datatypes.h Mon Jul 28 23:11:30 2025 +0200 +++ b/src/ascension/datatypes.h Wed Jul 30 00:12:13 2025 +0200 @@ -55,25 +55,60 @@ */ #define ASC_NONZERO_OR(y, x) ((x) != 0 ? x : y) -#define asc_test_flag(reg, flag) ((reg & flag) == flag) -#define asc_test_flag_masked(reg, mask, flag) ((reg & mask) == flag) -#define asc_clear_flag(reg, flag) (reg &= ~(flag)) -#define asc_set_flag(reg, flag) (reg |= flag) -#define asc_set_flag_masked(reg, mask, flag) (reg = (reg & ~(mask)) | flag) - -static inline int asc_create_flags(unsigned start, unsigned n, ...) { - va_list args; - va_start(args, n); - int result = 0; - for (unsigned i = 0; i < n; i++) { - if (va_arg(args, int)) { - result |= start; - } - start <<= 1; - } - va_end(args); - return result; -} +/** + * Returns true if and only if all tested flags are set. + * + * @param reg the flag register + * @param flags the flags to test + */ +#define asc_test_flag(reg, flags) ((reg & flags) == flags) +/** + * Returns true if and only if the flags selected by a mask have the expected state. + * + * Note that @p expected must not have bits set that are not selected by the @p mask, + * or this will always return false. + * + * @param reg the flag register + * @param mask the mask + * @param expected the expected state of the flags + */ +#define asc_test_flag_masked(reg, mask, expected) ((reg & mask) == expected) +/** + * Clears flags. + * + * @param reg the flag register + * @param flags the flags to clear + */ +#define asc_clear_flag(reg, flags) (reg &= ~(flags)) +/** + * Sets flags. + * + * @param reg the flag register + * @param flags the flags to set + */ +#define asc_set_flag(reg, flags) (reg |= flags) +/** + * Sets flags if a certain condition is true. + * + * @param reg the flag register + * @param flags the flags to set if @p cond is @c true + * @param cond the condition to evaluate + */ +#define asc_set_flag_if(reg, flags, cond) (reg |= (cond)?(flags):0) +/** + * Sets or clears flags. + * + * The @p mask selects the bits that shall be changed. + * The @p state contains the new set (set/cleared) for those bits. + * + * Note that @p state should not have bits set that do not correspond to the @p mask. + * Otherwise, those bits will also get set. + * + * @param reg the flag register + * @param mask the mask for selecting the flags to consider + * @param state the new state of the flags + */ +#define asc_set_flag_masked(reg, mask, state) (reg = (reg & ~(mask)) | state) #define asc_ptr_cast(type, lvalue, rvalue) type *lvalue = (type *)(rvalue); #define asc_cptr_cast(type, lvalue, rvalue) const type *lvalue = (const type *)(rvalue);