util.h (9078B)
1 /* See LICENSE for license details. */ 2 #ifndef _UTIL_H_ 3 #define _UTIL_H_ 4 5 #include <stddef.h> 6 #include <stdint.h> 7 8 #include "compiler.h" 9 10 #ifndef asm 11 #define asm __asm__ 12 #endif 13 14 #ifndef typeof 15 #define typeof __typeof__ 16 #endif 17 18 #ifdef _DEBUG 19 #if OS_WINDOWS 20 #define DEBUG_EXPORT __declspec(dllexport) 21 #ifdef _BEAMFORMER_DLL 22 #define DEBUG_IMPORT __declspec(dllimport) 23 #else 24 #define DEBUG_IMPORT __declspec(dllexport) 25 #endif 26 #else 27 #ifdef _BEAMFORMER_DLL 28 #define DEBUG_IMPORT extern 29 #else 30 #define DEBUG_IMPORT 31 #endif 32 #define DEBUG_EXPORT 33 #endif 34 #define DEBUG_DECL(a) a 35 #define assert(c) do { if (!(c)) debugbreak(); } while (0) 36 #else 37 #define DEBUG_IMPORT global 38 #define DEBUG_EXPORT function 39 #define DEBUG_DECL(a) 40 #define assert(c) 41 #endif 42 #define ASSERT assert 43 44 #define INVALID_CODE_PATH ASSERT(0) 45 #define INVALID_DEFAULT_CASE default: ASSERT(0); break 46 #define InvalidCodePath assert(0) 47 #define InvalidDefaultCase default: assert(0); break 48 49 #define arg_list(type, ...) (type []){__VA_ARGS__}, sizeof((type []){__VA_ARGS__}) / sizeof(type) 50 51 #define function static 52 #define global static 53 #define local_persist static 54 55 #define static_assert _Static_assert 56 57 /* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */ 58 #define str_(x) #x 59 #define str(x) str_(x) 60 61 #define countof(a) (sizeof(a) / sizeof(*a)) 62 #define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a)) 63 #define ABS(x) ((x) < 0 ? (-x) : (x)) 64 #define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b)) 65 #define CLAMP(x, a, b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x)) 66 #define CLAMP01(x) CLAMP(x, 0, 1) 67 #define ISPOWEROF2(a) (((a) & ((a) - 1)) == 0) 68 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 69 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 70 #define ORONE(x) ((x)? (x) : 1) 71 #define SIGN(x) ((x) < 0? -1 : 1) 72 #define swap(a, b) do {typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;} while(0) 73 74 #define EachElement(array, it) (u64 it = 0; it < countof(array); it += 1) 75 #define EachEnumValue(type, it) (type it = (type)0; it < type##_Count; it = (type)(it + 1)) 76 #define EachNonZeroEnumValue(type, it) (type it = (type)1; it < type##_Count; it = (type)(it + 1)) 77 78 /* NOTE(rnp): no guarantees about actually getting an element */ 79 #define SLLPop(list) list; list = list ? list->next : 0 80 #define SLLPush(v, list) do { \ 81 (v)->next = (list); \ 82 (list) = v; \ 83 } while (0) 84 85 #define DLLPushDown(v, list) do { \ 86 (v)->next = (list); \ 87 if ((v)->next) (v)->next->prev = (v); \ 88 (list) = (v); \ 89 } while (0) 90 91 #define DLLRemove(v) do { \ 92 if ((v)->next) (v)->next->prev = (v)->prev; \ 93 if ((v)->prev) (v)->prev->next = (v)->next; \ 94 } while (0) 95 96 #define KB(a) ((u64)(a) << 10ULL) 97 #define MB(a) ((u64)(a) << 20ULL) 98 #define GB(a) ((u64)(a) << 30ULL) 99 100 #define I32_MAX (0x7FFFFFFFL) 101 #define U32_MAX (0xFFFFFFFFUL) 102 #define F32_INFINITY (1e+300*1e+300) 103 104 typedef char c8; 105 typedef uint8_t u8; 106 typedef int16_t i16; 107 typedef uint16_t u16; 108 typedef int32_t i32; 109 typedef uint32_t u32; 110 typedef int64_t i64; 111 typedef uint64_t u64; 112 typedef uint32_t b32; 113 typedef float f32; 114 typedef double f64; 115 typedef ptrdiff_t iz; 116 typedef size_t uz; 117 typedef ptrdiff_t iptr; 118 typedef size_t uptr; 119 120 #include "intrinsics.c" 121 122 typedef struct { u8 *beg, *end; } Arena; 123 typedef struct { Arena *arena; u8 *old_beg; } TempArena; 124 125 typedef struct { iz len; u8 *data; } s8; 126 #define s8(s) (s8){.len = ARRAY_COUNT(s) - 1, .data = (u8 *)s} 127 #define s8_comp(s) {sizeof(s) - 1, (u8 *)s} 128 129 typedef struct { iz len; u16 *data; } s16; 130 131 typedef struct { u32 cp, consumed; } UnicodeDecode; 132 133 /* NOTE: raylib stubs */ 134 #ifndef RAYLIB_H 135 typedef struct { f32 x, y; } Vector2; 136 typedef struct { f32 x, y, w, h; } Rectangle; 137 #endif 138 139 typedef union { 140 struct { i32 x, y; }; 141 struct { i32 w, h; }; 142 i32 E[2]; 143 } iv2; 144 145 typedef union { 146 struct { i32 x, y, z; }; 147 struct { i32 w, h, d; }; 148 iv2 xy; 149 i32 E[3]; 150 } iv3; 151 152 typedef union { 153 struct { u32 x, y; }; 154 struct { u32 w, h; }; 155 u32 E[2]; 156 } uv2; 157 158 typedef union { 159 struct { u32 x, y, z; }; 160 struct { u32 w, h, d; }; 161 uv2 xy; 162 u32 E[3]; 163 } uv3; 164 165 typedef union { 166 struct { u32 x, y, z, w; }; 167 struct { uv3 xyz; u32 _w; }; 168 u32 E[4]; 169 } uv4; 170 171 typedef union { 172 struct { f32 x, y; }; 173 struct { f32 w, h; }; 174 Vector2 rl; 175 f32 E[2]; 176 } v2; 177 178 typedef union { 179 struct { f32 x, y, z; }; 180 struct { f32 w, h, d; }; 181 f32 E[3]; 182 } v3; 183 184 typedef union { 185 struct { f32 x, y, z, w; }; 186 struct { f32 r, g, b, a; }; 187 struct { v3 xyz; f32 _1; }; 188 struct { f32 _2; v3 yzw; }; 189 struct { v2 xy, zw; }; 190 f32 E[4]; 191 } v4; 192 193 #define XZ(v) (v2){.x = v.x, .y = v.z} 194 #define YZ(v) (v2){.x = v.y, .y = v.z} 195 #define XY(v) (v2){.x = v.x, .y = v.y} 196 197 typedef union { 198 struct { v4 x, y, z, w; }; 199 v4 c[4]; 200 f32 E[16]; 201 } m4; 202 203 typedef union { 204 struct { v2 pos, size; }; 205 Rectangle rl; 206 } Rect; 207 #define INVERTED_INFINITY_RECT (Rect){.pos = {.x = -F32_INFINITY, .y = -F32_INFINITY}, \ 208 .size = {.x = -F32_INFINITY, .y = -F32_INFINITY}} 209 210 typedef struct { 211 u8 *data; 212 u32 widx; 213 u32 cap; 214 b32 errors; 215 } Stream; 216 217 #define INVALID_FILE (-1) 218 219 typedef struct OS OS; 220 221 typedef struct { 222 Arena arena; 223 iptr handle; 224 iptr window_handle; 225 iptr gl_context; 226 iptr user_context; 227 i32 sync_variable; 228 b32 asleep; 229 } GLWorkerThreadContext; 230 231 #define FILE_WATCH_CALLBACK_FN(name) b32 name(OS *os, s8 path, iptr user_data, Arena arena) 232 typedef FILE_WATCH_CALLBACK_FN(file_watch_callback); 233 234 typedef struct { 235 iptr user_data; 236 u64 hash; 237 file_watch_callback *callback; 238 } FileWatch; 239 240 typedef struct { 241 u64 hash; 242 iptr handle; 243 s8 name; 244 245 FileWatch *data; 246 iz count; 247 iz capacity; 248 Arena buffer; 249 } FileWatchDirectory; 250 251 typedef struct { 252 FileWatchDirectory *data; 253 iz count; 254 iz capacity; 255 iptr handle; 256 } FileWatchContext; 257 258 typedef struct { 259 void *region; 260 iptr os_context; 261 } SharedMemoryRegion; 262 263 #define OS_ALLOC_ARENA_FN(name) Arena name(iz capacity) 264 typedef OS_ALLOC_ARENA_FN(os_alloc_arena_fn); 265 266 #define OS_ADD_FILE_WATCH_FN(name) void name(OS *os, Arena *a, s8 path, \ 267 file_watch_callback *callback, iptr user_data) 268 typedef OS_ADD_FILE_WATCH_FN(os_add_file_watch_fn); 269 270 #define OS_WAKE_WORKER_FN(name) void name(GLWorkerThreadContext *ctx) 271 typedef OS_WAKE_WORKER_FN(os_wake_worker_fn); 272 273 #define OS_READ_WHOLE_FILE_FN(name) s8 name(Arena *arena, char *file) 274 typedef OS_READ_WHOLE_FILE_FN(os_read_whole_file_fn); 275 276 #define OS_WAIT_ON_VALUE_FN(name) b32 name(i32 *value, i32 current, u32 timeout_ms) 277 typedef OS_WAIT_ON_VALUE_FN(os_wait_on_value_fn); 278 279 #define OS_WAKE_WAITERS_FN(name) void name(i32 *sync) 280 typedef OS_WAKE_WAITERS_FN(os_wake_waiters_fn); 281 282 #define OS_WRITE_NEW_FILE_FN(name) b32 name(char *fname, s8 raw) 283 typedef OS_WRITE_NEW_FILE_FN(os_write_new_file_fn); 284 285 #define OS_WRITE_FILE_FN(name) b32 name(iptr file, s8 raw) 286 typedef OS_WRITE_FILE_FN(os_write_file_fn); 287 288 #define OS_THREAD_ENTRY_POINT_FN(name) iptr name(iptr _ctx) 289 typedef OS_THREAD_ENTRY_POINT_FN(os_thread_entry_point_fn); 290 291 #define OS_SHARED_MEMORY_LOCK_REGION_FN(name) b32 name(SharedMemoryRegion *sm, i32 *locks, i32 lock_index, i32 timeout_ms) 292 typedef OS_SHARED_MEMORY_LOCK_REGION_FN(os_shared_memory_region_lock_fn); 293 294 #define OS_SHARED_MEMORY_UNLOCK_REGION_FN(name) void name(SharedMemoryRegion *sm, i32 *locks, i32 lock_index) 295 typedef OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock_fn); 296 297 #define OS_FNS \ 298 X(add_file_watch) \ 299 X(read_whole_file) \ 300 X(shared_memory_region_lock) \ 301 X(shared_memory_region_unlock) \ 302 X(wake_waiters) \ 303 X(write_new_file) \ 304 X(write_file) 305 306 #define RENDERDOC_GET_API_FN(name) b32 name(u32 version, void **out_api) 307 typedef RENDERDOC_GET_API_FN(renderdoc_get_api_fn); 308 309 #define RENDERDOC_START_FRAME_CAPTURE_FN(name) void name(iptr gl_context, iptr window_handle) 310 typedef RENDERDOC_START_FRAME_CAPTURE_FN(renderdoc_start_frame_capture_fn); 311 312 #define RENDERDOC_END_FRAME_CAPTURE_FN(name) b32 name(iptr gl_context, iptr window_handle) 313 typedef RENDERDOC_END_FRAME_CAPTURE_FN(renderdoc_end_frame_capture_fn); 314 315 typedef align_as(16) u8 RenderDocAPI[216]; 316 #define RENDERDOC_API_FN_ADDR(a, offset) (*(iptr *)((*a) + offset)) 317 #define RENDERDOC_START_FRAME_CAPTURE(a) (renderdoc_start_frame_capture_fn *)RENDERDOC_API_FN_ADDR(a, 152) 318 #define RENDERDOC_END_FRAME_CAPTURE(a) (renderdoc_end_frame_capture_fn *) RENDERDOC_API_FN_ADDR(a, 168) 319 320 struct OS { 321 #define X(name) os_ ## name ## _fn *name; 322 OS_FNS 323 #undef X 324 FileWatchContext file_watch_context; 325 iptr context; 326 iptr error_handle; 327 GLWorkerThreadContext compute_worker; 328 329 DEBUG_DECL(renderdoc_start_frame_capture_fn *start_frame_capture;) 330 DEBUG_DECL(renderdoc_end_frame_capture_fn *end_frame_capture;) 331 }; 332 333 #define LABEL_GL_OBJECT(type, id, s) {s8 _s = (s); glObjectLabel(type, id, _s.len, (c8 *)_s.data);} 334 335 #include "util.c" 336 337 #endif /* _UTIL_H_ */