main_w32.c (4181B)
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 typedef struct { 9 iptr io_completion_handle; 10 } w32_context; 11 12 enum w32_io_events { 13 W32_IO_FILE_WATCH, 14 W32_IO_PIPE, 15 }; 16 17 typedef struct { 18 u64 tag; 19 iptr context; 20 } w32_io_completion_event; 21 22 #include "os_win32.c" 23 24 #define OS_DEBUG_LIB_NAME ".\\beamformer.dll" 25 #define OS_DEBUG_LIB_TEMP_NAME ".\\beamformer_temp.dll" 26 27 #define OS_CUDA_LIB_NAME "external\\cuda_toolkit.dll" 28 #define OS_CUDA_LIB_TEMP_NAME "external\\cuda_toolkit_temp.dll" 29 30 #define OS_PIPE_NAME "\\\\.\\pipe\\beamformer_data_fifo" 31 #define OS_SMEM_NAME "Local\\ogl_beamformer_parameters" 32 33 #define OS_PATH_SEPERATOR "\\" 34 35 #include "static.c" 36 37 static void 38 w32_wide_char_to_mb(Stream *s, u16 *wstr, u32 wide_char_length) 39 { 40 /* NOTE(rnp): this assumes the wstr is strictly ASCII */ 41 s->errors |= (s->cap - s->widx) < wide_char_length; 42 if (!s->errors) { 43 for (u32 i = 0; i < wide_char_length; i++) 44 s->data[s->widx++] = wstr[i] & 0xFF; 45 } 46 } 47 48 static void 49 dispatch_file_watch(FileWatchDirectory *fw_dir, u8 *buf, Arena arena) 50 { 51 i64 offset = 0; 52 Stream path = stream_alloc(&arena, 256); 53 w32_file_notify_info *fni = (w32_file_notify_info *)buf; 54 do { 55 if (fni->action != FILE_ACTION_MODIFIED) { 56 path.widx = 0; 57 stream_append_s8(&path, s8("unknown file watch event: ")); 58 stream_append_u64(&path, fni->action); 59 stream_append_byte(&path, '\n'); 60 os_write_err_msg(stream_to_s8(&path)); 61 } 62 63 path.widx = 0; 64 stream_append_s8(&path, fw_dir->name); 65 stream_append_byte(&path, '\\'); 66 67 s8 file_name = {.data = path.data + path.widx, .len = fni->filename_size / 2}; 68 w32_wide_char_to_mb(&path, fni->filename, fni->filename_size / 2); 69 stream_append_byte(&path, 0); 70 path.widx--; 71 72 u64 hash = s8_hash(file_name); 73 for (u32 i = 0; i < fw_dir->file_watch_count; i++) { 74 FileWatch *fw = fw_dir->file_watches + i; 75 if (fw->hash == hash) { 76 fw->callback(stream_to_s8(&path), 77 fw->user_data, arena); 78 break; 79 } 80 } 81 82 offset = fni->next_entry_offset; 83 fni = (w32_file_notify_info *)((u8 *)fni + offset); 84 } while (offset); 85 } 86 87 static void 88 clear_io_queue(Platform *platform, BeamformerInput *input, Arena arena) 89 { 90 w32_context *ctx = (w32_context *)platform->os_context; 91 92 iptr handle = ctx->io_completion_handle; 93 w32_overlapped *overlapped; 94 u32 bytes_read; 95 uptr user_data; 96 while (GetQueuedCompletionStatus(handle, &bytes_read, &user_data, &overlapped, 0)) { 97 w32_io_completion_event *event = (w32_io_completion_event *)user_data; 98 switch (event->tag) { 99 case W32_IO_FILE_WATCH: { 100 FileWatchDirectory *dir = (FileWatchDirectory *)event->context; 101 dispatch_file_watch(dir, dir->buffer.beg, arena); 102 zero_struct(overlapped); 103 ReadDirectoryChangesW(dir->handle, dir->buffer.beg, 4096, 0, 104 FILE_NOTIFY_CHANGE_LAST_WRITE, 0, overlapped, 0); 105 } break; 106 case W32_IO_PIPE: break; 107 } 108 } 109 } 110 111 int 112 main(void) 113 { 114 BeamformerCtx ctx = {0}; 115 BeamformerInput input = {.executable_reloaded = 1}; 116 Arena temp_memory = os_alloc_arena((Arena){0}, 16 * MEGABYTE); 117 ctx.error_stream = stream_alloc(&temp_memory, 1 * MEGABYTE); 118 119 ctx.ui_backing_store = sub_arena(&temp_memory, 2 * MEGABYTE, 4096); 120 121 Pipe data_pipe = os_open_named_pipe(OS_PIPE_NAME); 122 input.pipe_handle = data_pipe.file; 123 ASSERT(data_pipe.file != INVALID_FILE); 124 125 #define X(name) ctx.platform.name = os_ ## name; 126 PLATFORM_FNS 127 #undef X 128 129 w32_context w32_ctx = {0}; 130 w32_ctx.io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0); 131 ctx.platform.os_context = (iptr)&w32_ctx; 132 133 setup_beamformer(&ctx, &temp_memory); 134 debug_init(&ctx.platform, (iptr)&input, &temp_memory); 135 136 while (!(ctx.flags & SHOULD_EXIT)) { 137 clear_io_queue(&ctx.platform, &input, temp_memory); 138 139 input.last_mouse = input.mouse; 140 input.mouse.rl = GetMousePosition(); 141 142 i32 bytes_available = 0; 143 input.pipe_data_available = PeekNamedPipe(data_pipe.file, 0, 1 * MEGABYTE, 0, 144 &bytes_available, 0) && bytes_available; 145 146 beamformer_frame_step(&ctx, &temp_memory, &input); 147 148 input.executable_reloaded = 0; 149 } 150 }