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