volviewer

Volumetric Data Toy Viewer
git clone anongit@rnpnr.xyz:volviewer.git
Log | Files | Refs | Feed | LICENSE

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 }