main_w32.c (2761B)
1 /* See LICENSE for license details. */ 2 #include "compiler.h" 3 4 #if !OS_WINDOWS 5 #error This file is only meant to be compiled for Win32 6 #endif 7 8 #include "os_win32.c" 9 #include "common.c" 10 11 function void 12 dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena) 13 { 14 s64 offset = 0; 15 Arena start_arena = arena; 16 w32_file_notify_info *fni = (w32_file_notify_info *)buf; 17 do { 18 arena = start_arena; 19 20 Stream path = {.data = arena_commit(&arena, KB(1)), .cap = KB(1)}; 21 22 if (fni->action != FILE_ACTION_MODIFIED) { 23 stream_append_str8(&path, str8("unknown file watch event: ")); 24 stream_append_u64(&path, fni->action); 25 stream_append_byte(&path, '\n'); 26 os_write_file(os->error_handle, stream_to_str8(&path)); 27 stream_reset(&path, 0); 28 } 29 30 stream_append_str8(&path, fw_dir->name); 31 stream_append_byte(&path, '\\'); 32 33 str8 file_name = str16_to_str8(&arena, (str16){.data = fni->filename, 34 .len = fni->filename_size / 2}); 35 stream_append_str8(&path, file_name); 36 stream_append_byte(&path, 0); 37 stream_commit(&path, -1); 38 39 u64 hash = str8_hash(file_name); 40 for (u32 i = 0; i < fw_dir->count; i++) { 41 FileWatch *fw = fw_dir->data + i; 42 if (fw->hash == hash) { 43 fw->callback(os, stream_to_str8(&path), fw->user_data, arena); 44 break; 45 } 46 } 47 48 offset = fni->next_entry_offset; 49 fni = (w32_file_notify_info *)((u8 *)fni + offset); 50 } while (offset); 51 } 52 53 function void 54 clear_io_queue(OS *os, Arena arena) 55 { 56 w32_context *ctx = (w32_context *)os->context; 57 58 sptr handle = ctx->io_completion_handle; 59 w32_overlapped *overlapped; 60 u32 bytes_read; 61 uptr user_data; 62 while (GetQueuedCompletionStatus(handle, &bytes_read, &user_data, &overlapped, 0)) { 63 w32_io_completion_event *event = (w32_io_completion_event *)user_data; 64 switch (event->tag) { 65 case W32_IO_FILE_WATCH: { 66 FileWatchDirectory *dir = (FileWatchDirectory *)event->context; 67 dispatch_file_watch(os, dir, dir->buffer.beg, arena); 68 zero_struct(overlapped); 69 ReadDirectoryChangesW(dir->handle, dir->buffer.beg, 4096, 0, 70 FILE_NOTIFY_CHANGE_LAST_WRITE, 0, overlapped, 0); 71 } break; 72 case W32_IO_PIPE: break; 73 } 74 } 75 } 76 77 extern s32 78 main(void) 79 { 80 Arena memory = os_alloc_arena(GB(1)); 81 ViewerContext *ctx = push_struct(&memory, ViewerContext); 82 ctx->arena = memory; 83 84 w32_context w32_ctx = {0}; 85 w32_ctx.io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0); 86 87 ctx->os.context = (sptr)&w32_ctx; 88 ctx->os.error_handle = GetStdHandle(STD_ERROR_HANDLE); 89 90 init_viewer(ctx); 91 92 while (!ctx->should_exit) { 93 clear_io_queue(&ctx->os, ctx->arena); 94 viewer_frame_step(ctx, get_frame_time_step(ctx)); 95 glfwSwapBuffers(ctx->window); 96 glfwPollEvents(); 97 } 98 }