main_w32.c (3797B)
1 /* See LICENSE for license details. */ 2 #ifndef _WIN32 3 #error This file is only meant to be compiled for Win32 4 #endif 5 6 #include "beamformer.h" 7 8 #include "os_win32.c" 9 10 #define OS_DEBUG_LIB_NAME ".\\beamformer.dll" 11 #define OS_DEBUG_LIB_TEMP_NAME ".\\beamformer_temp.dll" 12 13 #define OS_CUDA_LIB_NAME "external\\cuda_toolkit.dll" 14 #define OS_CUDA_LIB_TEMP_NAME "external\\cuda_toolkit_temp.dll" 15 16 #define OS_RENDERDOC_SONAME "renderdoc.dll" 17 18 #define OS_PATH_SEPERATOR "\\" 19 20 iptr glfwGetWGLContext(iptr); 21 22 function iptr 23 os_get_native_gl_context(iptr window) 24 { 25 return glfwGetWGLContext(window); 26 } 27 28 #include "static.c" 29 30 function void 31 dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena) 32 { 33 i64 offset = 0; 34 TempArena save_point = {0}; 35 w32_file_notify_info *fni = (w32_file_notify_info *)buf; 36 do { 37 end_temp_arena(save_point); 38 save_point = begin_temp_arena(&arena); 39 40 Stream path = {.data = arena_commit(&arena, KB(1)), .cap = KB(1)}; 41 42 if (fni->action != FILE_ACTION_MODIFIED) { 43 stream_append_s8(&path, s8("unknown file watch event: ")); 44 stream_append_u64(&path, fni->action); 45 stream_append_byte(&path, '\n'); 46 os->write_file(os->stderr, stream_to_s8(&path)); 47 stream_reset(&path, 0); 48 } 49 50 stream_append_s8(&path, fw_dir->name); 51 stream_append_byte(&path, '\\'); 52 53 s8 file_name = s16_to_s8(&arena, (s16){.data = fni->filename, 54 .len = fni->filename_size / 2}); 55 stream_append_s8(&path, file_name); 56 stream_append_byte(&path, 0); 57 stream_commit(&path, -1); 58 59 u64 hash = s8_hash(file_name); 60 for (u32 i = 0; i < fw_dir->count; i++) { 61 FileWatch *fw = fw_dir->data + i; 62 if (fw->hash == hash) { 63 fw->callback(os, stream_to_s8(&path), fw->user_data, arena); 64 break; 65 } 66 } 67 68 offset = fni->next_entry_offset; 69 fni = (w32_file_notify_info *)((u8 *)fni + offset); 70 } while (offset); 71 } 72 73 static void 74 clear_io_queue(OS *os, BeamformerInput *input, Arena arena) 75 { 76 w32_context *ctx = (w32_context *)os->context; 77 78 iptr handle = ctx->io_completion_handle; 79 w32_overlapped *overlapped; 80 u32 bytes_read; 81 uptr user_data; 82 while (GetQueuedCompletionStatus(handle, &bytes_read, &user_data, &overlapped, 0)) { 83 w32_io_completion_event *event = (w32_io_completion_event *)user_data; 84 switch (event->tag) { 85 case W32_IO_FILE_WATCH: { 86 FileWatchDirectory *dir = (FileWatchDirectory *)event->context; 87 dispatch_file_watch(os, dir, dir->buffer.beg, arena); 88 zero_struct(overlapped); 89 ReadDirectoryChangesW(dir->handle, dir->buffer.beg, 4096, 0, 90 FILE_NOTIFY_CHANGE_LAST_WRITE, 0, overlapped, 0); 91 } break; 92 case W32_IO_PIPE: break; 93 } 94 } 95 } 96 97 int 98 main(void) 99 { 100 BeamformerCtx ctx = {0}; 101 BeamformerInput input = {.executable_reloaded = 1}; 102 Arena temp_memory = os_alloc_arena((Arena){0}, MB(16)); 103 ctx.error_stream = stream_alloc(&temp_memory, MB(1)); 104 105 ctx.ui_backing_store = sub_arena(&temp_memory, MB(2), KB(4)); 106 ctx.os.compute_worker.arena = sub_arena(&temp_memory, MB(2), KB(4)); 107 108 #define X(name) ctx.os.name = os_ ## name; 109 OS_FNS 110 #undef X 111 112 w32_context w32_ctx = {0}; 113 w32_ctx.io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0); 114 115 ctx.os.context = (iptr)&w32_ctx; 116 ctx.os.compute_worker.asleep = 1; 117 ctx.os.stderr = GetStdHandle(STD_ERROR_HANDLE); 118 ctx.os.export_pipe_name = OS_EXPORT_PIPE_NAME; 119 120 debug_init(&ctx.os, (iptr)&input, &temp_memory); 121 setup_beamformer(&ctx, &temp_memory); 122 os_wake_waiters(&ctx.os.compute_worker.sync_variable); 123 124 while (!ctx.should_exit) { 125 clear_io_queue(&ctx.os, &input, temp_memory); 126 127 input.last_mouse = input.mouse; 128 input.mouse.rl = GetMousePosition(); 129 130 beamformer_frame_step(&ctx, &temp_memory, &input); 131 132 input.executable_reloaded = 0; 133 } 134 }