mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-03 04:28:12 +00:00
simplification pass over os core layer; simplification pass over base arena; set up build.sh; stub out new spot for linux os core
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,88 +1,7 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef LINUX_H
|
||||
#define LINUX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Get all these linux includes
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): File Iterator
|
||||
|
||||
struct LNX_FileIter{
|
||||
int fd;
|
||||
DIR *dir;
|
||||
};
|
||||
StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(LNX_FileIter), file_iter_memory_size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Threading Entities
|
||||
|
||||
enum LNX_EntityKind{
|
||||
LNX_EntityKind_Null,
|
||||
LNX_EntityKind_Thread,
|
||||
LNX_EntityKind_Mutex,
|
||||
LNX_EntityKind_ConditionVariable,
|
||||
};
|
||||
|
||||
struct LNX_Entity{
|
||||
LNX_Entity *next;
|
||||
LNX_EntityKind kind;
|
||||
volatile U32 reference_mask;
|
||||
union{
|
||||
struct{
|
||||
OS_ThreadFunctionType *func;
|
||||
void *ptr;
|
||||
pthread_t handle;
|
||||
} thread;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Safe Call Chain
|
||||
|
||||
struct LNX_SafeCallChain{
|
||||
LNX_SafeCallChain *next;
|
||||
OS_ThreadFunctionType *fail_handler;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Helpers
|
||||
|
||||
internal B32 lnx_write_list_to_file_descriptor(int fd, String8List list);
|
||||
|
||||
internal void lnx_date_time_from_tm(DateTime *out, struct tm *in, U32 msec);
|
||||
internal void lnx_tm_from_date_time(struct tm *out, DateTime *in);
|
||||
internal void lnx_dense_time_from_timespec(DenseTime *out, struct timespec *in);
|
||||
internal void lnx_file_properties_from_stat(FileProperties *out, struct stat *in);
|
||||
|
||||
internal String8 lnx_string_from_signal(int signum);
|
||||
internal String8 lnx_string_from_errno(int error_number);
|
||||
|
||||
internal LNX_Entity* lnx_alloc_entity(LNX_EntityKind kind);
|
||||
internal void lnx_free_entity(LNX_Entity *entity);
|
||||
internal void* lnx_thread_base(void *ptr);
|
||||
|
||||
internal void lnx_safe_call_sig_handler(int);
|
||||
|
||||
#endif //LINUX_H
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_CORE_LINUX_H
|
||||
#define OS_CORE_LINUX_H
|
||||
|
||||
#endif // OS_CORE_LINUX_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef LINUX_H
|
||||
#define LINUX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Get all these linux includes
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): File Iterator
|
||||
|
||||
struct LNX_FileIter{
|
||||
int fd;
|
||||
DIR *dir;
|
||||
};
|
||||
StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(LNX_FileIter), file_iter_memory_size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Threading Entities
|
||||
|
||||
enum LNX_EntityKind{
|
||||
LNX_EntityKind_Null,
|
||||
LNX_EntityKind_Thread,
|
||||
LNX_EntityKind_Mutex,
|
||||
LNX_EntityKind_ConditionVariable,
|
||||
};
|
||||
|
||||
struct LNX_Entity{
|
||||
LNX_Entity *next;
|
||||
LNX_EntityKind kind;
|
||||
volatile U32 reference_mask;
|
||||
union{
|
||||
struct{
|
||||
OS_ThreadFunctionType *func;
|
||||
void *ptr;
|
||||
pthread_t handle;
|
||||
} thread;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Safe Call Chain
|
||||
|
||||
struct LNX_SafeCallChain{
|
||||
LNX_SafeCallChain *next;
|
||||
OS_ThreadFunctionType *fail_handler;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Helpers
|
||||
|
||||
internal B32 lnx_write_list_to_file_descriptor(int fd, String8List list);
|
||||
|
||||
internal void lnx_date_time_from_tm(DateTime *out, struct tm *in, U32 msec);
|
||||
internal void lnx_tm_from_date_time(struct tm *out, DateTime *in);
|
||||
internal void lnx_dense_time_from_timespec(DenseTime *out, struct timespec *in);
|
||||
internal void lnx_file_properties_from_stat(FileProperties *out, struct stat *in);
|
||||
|
||||
internal String8 lnx_string_from_signal(int signum);
|
||||
internal String8 lnx_string_from_errno(int error_number);
|
||||
|
||||
internal LNX_Entity* lnx_alloc_entity(LNX_EntityKind kind);
|
||||
internal void lnx_free_entity(LNX_Entity *entity);
|
||||
internal void* lnx_thread_base(void *ptr);
|
||||
|
||||
internal void lnx_safe_call_sig_handler(int);
|
||||
|
||||
#endif //LINUX_H
|
||||
+173
-243
@@ -1,243 +1,173 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Functions (Helpers, Implemented Once)
|
||||
|
||||
internal OS_Handle
|
||||
os_handle_zero(void)
|
||||
{
|
||||
OS_Handle handle = {0};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_handle_match(OS_Handle a, OS_Handle b)
|
||||
{
|
||||
return a.u64[0] == b.u64[0];
|
||||
}
|
||||
|
||||
internal void
|
||||
os_handle_list_push(Arena *arena, OS_HandleList *handles, OS_Handle handle)
|
||||
{
|
||||
OS_HandleNode *n = push_array(arena, OS_HandleNode, 1);
|
||||
n->v = handle;
|
||||
SLLQueuePush(handles->first, handles->last, n);
|
||||
handles->count += 1;
|
||||
}
|
||||
|
||||
internal OS_HandleArray
|
||||
os_handle_array_from_list(Arena *arena, OS_HandleList *list)
|
||||
{
|
||||
OS_HandleArray result = {0};
|
||||
result.count = list->count;
|
||||
result.v = push_array_no_zero(arena, OS_Handle, result.count);
|
||||
U64 idx = 0;
|
||||
for(OS_HandleNode *n = list->first; n != 0; n = n->next, idx += 1)
|
||||
{
|
||||
result.v[idx] = n->v;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: System Path Helper (Helper, Implemented Once)
|
||||
|
||||
internal String8
|
||||
os_string_from_system_path(Arena *arena, OS_SystemPath path)
|
||||
{
|
||||
String8List strs = {0};
|
||||
os_string_list_from_system_path(arena, path, &strs);
|
||||
String8 result = str8_list_first(&strs);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Command Line Argc/Argv Helper (Helper, Implemented Once)
|
||||
|
||||
internal String8List
|
||||
os_string_list_from_argcv(Arena *arena, int argc, char **argv)
|
||||
{
|
||||
String8List result = {0};
|
||||
for(int i = 0; i < argc; i += 1)
|
||||
{
|
||||
String8 str = str8_cstring(argv[i]);
|
||||
str8_list_push(arena, &result, str);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal String8
|
||||
os_data_from_file_path(Arena *arena, String8 path)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
|
||||
FileProperties props = os_properties_from_file(file);
|
||||
String8 data = os_string_from_file_range(arena, file, r1u64(0, props.size));
|
||||
os_file_close(file);
|
||||
return data;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_write_data_to_file_path(String8 path, String8 data)
|
||||
{
|
||||
B32 good = 0;
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
|
||||
if(!os_handle_match(file, os_handle_zero()))
|
||||
{
|
||||
good = 1;
|
||||
os_file_write(file, r1u64(0, data.size), data.str);
|
||||
os_file_close(file);
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_write_data_list_to_file_path(String8 path, String8List list)
|
||||
{
|
||||
B32 good = 0;
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
|
||||
if(!os_handle_match(file, os_handle_zero()))
|
||||
{
|
||||
good = 1;
|
||||
U64 off = 0;
|
||||
for(String8Node *n = list.first; n != 0; n = n->next)
|
||||
{
|
||||
os_file_write(file, r1u64(off, off+n->string.size), n->string.str);
|
||||
off += n->string.size;
|
||||
}
|
||||
os_file_close(file);
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_append_data_to_file_path(String8 path, String8 data)
|
||||
{
|
||||
B32 good = 0;
|
||||
if(data.size != 0)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append, path);
|
||||
if(!os_handle_match(file, os_handle_zero()))
|
||||
{
|
||||
good = 1;
|
||||
U64 pos = os_properties_from_file(file).size;
|
||||
os_file_write(file, r1u64(pos, pos+data.size), data.str);
|
||||
os_file_close(file);
|
||||
}
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
internal OS_FileID
|
||||
os_id_from_file_path(String8 path)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
|
||||
OS_FileID id = os_id_from_file(file);
|
||||
os_file_close(file);
|
||||
return id;
|
||||
}
|
||||
|
||||
internal S64
|
||||
os_file_id_compare(OS_FileID a, OS_FileID b)
|
||||
{
|
||||
S64 cmp = MemoryCompare((void*)&a.v[0], (void*)&b.v[0], sizeof(a.v));
|
||||
return cmp;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range)
|
||||
{
|
||||
U64 pre_pos = arena_pos(arena);
|
||||
String8 result;
|
||||
result.size = dim_1u64(range);
|
||||
result.str = push_array_no_zero(arena, U8, result.size);
|
||||
U64 actual_read_size = os_file_read(file, range, result.str);
|
||||
if(actual_read_size < result.size)
|
||||
{
|
||||
arena_pop_to(arena, pre_pos + actual_read_size);
|
||||
result.size = actual_read_size;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Synchronization Primitive Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal void
|
||||
os_mutex_take(OS_Handle mutex){
|
||||
os_mutex_take_(mutex);
|
||||
}
|
||||
|
||||
internal void
|
||||
os_mutex_drop(OS_Handle mutex){
|
||||
os_mutex_drop_(mutex);
|
||||
}
|
||||
|
||||
internal void
|
||||
os_rw_mutex_take_r(OS_Handle rw_mutex){
|
||||
os_rw_mutex_take_r_(rw_mutex);
|
||||
}
|
||||
|
||||
internal void
|
||||
os_rw_mutex_drop_r(OS_Handle rw_mutex){
|
||||
os_rw_mutex_drop_r_(rw_mutex);
|
||||
}
|
||||
|
||||
internal void
|
||||
os_rw_mutex_take_w(OS_Handle rw_mutex){
|
||||
os_rw_mutex_take_w_(rw_mutex);
|
||||
}
|
||||
|
||||
internal void
|
||||
os_rw_mutex_drop_w(OS_Handle rw_mutex){
|
||||
os_rw_mutex_drop_w_(rw_mutex);
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_condition_variable_wait(OS_Handle cv, OS_Handle mutex, U64 endt_us){
|
||||
B32 result = os_condition_variable_wait_(cv, mutex, endt_us);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_condition_variable_wait_rw_r(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us){
|
||||
B32 result = os_condition_variable_wait_rw_r_(cv, mutex_rw, endt_us);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_condition_variable_wait_rw_w(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us){
|
||||
B32 result = os_condition_variable_wait_rw_w_(cv, mutex_rw, endt_us);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
os_condition_variable_signal(OS_Handle cv){
|
||||
os_condition_variable_signal_(cv);
|
||||
}
|
||||
|
||||
internal void
|
||||
os_condition_variable_broadcast(OS_Handle cv){
|
||||
os_condition_variable_broadcast_(cv);
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_string_from_guid(Arena *arena, OS_Guid guid)
|
||||
{
|
||||
String8 result = push_str8f(arena, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
guid.data1,
|
||||
guid.data2,
|
||||
guid.data3,
|
||||
guid.data4[0],
|
||||
guid.data4[1],
|
||||
guid.data4[2],
|
||||
guid.data4[3],
|
||||
guid.data4[4],
|
||||
guid.data4[5],
|
||||
guid.data4[6],
|
||||
guid.data4[7]);
|
||||
return result;
|
||||
}
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Functions (Helpers, Implemented Once)
|
||||
|
||||
internal OS_Handle
|
||||
os_handle_zero(void)
|
||||
{
|
||||
OS_Handle handle = {0};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_handle_match(OS_Handle a, OS_Handle b)
|
||||
{
|
||||
return a.u64[0] == b.u64[0];
|
||||
}
|
||||
|
||||
internal void
|
||||
os_handle_list_push(Arena *arena, OS_HandleList *handles, OS_Handle handle)
|
||||
{
|
||||
OS_HandleNode *n = push_array(arena, OS_HandleNode, 1);
|
||||
n->v = handle;
|
||||
SLLQueuePush(handles->first, handles->last, n);
|
||||
handles->count += 1;
|
||||
}
|
||||
|
||||
internal OS_HandleArray
|
||||
os_handle_array_from_list(Arena *arena, OS_HandleList *list)
|
||||
{
|
||||
OS_HandleArray result = {0};
|
||||
result.count = list->count;
|
||||
result.v = push_array_no_zero(arena, OS_Handle, result.count);
|
||||
U64 idx = 0;
|
||||
for(OS_HandleNode *n = list->first; n != 0; n = n->next, idx += 1)
|
||||
{
|
||||
result.v[idx] = n->v;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Command Line Argc/Argv Helper (Helper, Implemented Once)
|
||||
|
||||
internal String8List
|
||||
os_string_list_from_argcv(Arena *arena, int argc, char **argv)
|
||||
{
|
||||
String8List result = {0};
|
||||
for(int i = 0; i < argc; i += 1)
|
||||
{
|
||||
String8 str = str8_cstring(argv[i]);
|
||||
str8_list_push(arena, &result, str);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal String8
|
||||
os_data_from_file_path(Arena *arena, String8 path)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
|
||||
FileProperties props = os_properties_from_file(file);
|
||||
String8 data = os_string_from_file_range(arena, file, r1u64(0, props.size));
|
||||
os_file_close(file);
|
||||
return data;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_write_data_to_file_path(String8 path, String8 data)
|
||||
{
|
||||
B32 good = 0;
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
|
||||
if(!os_handle_match(file, os_handle_zero()))
|
||||
{
|
||||
good = 1;
|
||||
os_file_write(file, r1u64(0, data.size), data.str);
|
||||
os_file_close(file);
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_write_data_list_to_file_path(String8 path, String8List list)
|
||||
{
|
||||
B32 good = 0;
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
|
||||
if(!os_handle_match(file, os_handle_zero()))
|
||||
{
|
||||
good = 1;
|
||||
U64 off = 0;
|
||||
for(String8Node *n = list.first; n != 0; n = n->next)
|
||||
{
|
||||
os_file_write(file, r1u64(off, off+n->string.size), n->string.str);
|
||||
off += n->string.size;
|
||||
}
|
||||
os_file_close(file);
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_append_data_to_file_path(String8 path, String8 data)
|
||||
{
|
||||
B32 good = 0;
|
||||
if(data.size != 0)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append, path);
|
||||
if(!os_handle_match(file, os_handle_zero()))
|
||||
{
|
||||
good = 1;
|
||||
U64 pos = os_properties_from_file(file).size;
|
||||
os_file_write(file, r1u64(pos, pos+data.size), data.str);
|
||||
os_file_close(file);
|
||||
}
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
internal OS_FileID
|
||||
os_id_from_file_path(String8 path)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
|
||||
OS_FileID id = os_id_from_file(file);
|
||||
os_file_close(file);
|
||||
return id;
|
||||
}
|
||||
|
||||
internal S64
|
||||
os_file_id_compare(OS_FileID a, OS_FileID b)
|
||||
{
|
||||
S64 cmp = MemoryCompare((void*)&a.v[0], (void*)&b.v[0], sizeof(a.v));
|
||||
return cmp;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range)
|
||||
{
|
||||
U64 pre_pos = arena_pos(arena);
|
||||
String8 result;
|
||||
result.size = dim_1u64(range);
|
||||
result.str = push_array_no_zero(arena, U8, result.size);
|
||||
U64 actual_read_size = os_file_read(file, range, result.str);
|
||||
if(actual_read_size < result.size)
|
||||
{
|
||||
arena_pop_to(arena, pre_pos + actual_read_size);
|
||||
result.size = actual_read_size;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: GUID Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal String8
|
||||
os_string_from_guid(Arena *arena, OS_Guid guid)
|
||||
{
|
||||
String8 result = push_str8f(arena, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
guid.data1,
|
||||
guid.data2,
|
||||
guid.data3,
|
||||
guid.data4[0],
|
||||
guid.data4[1],
|
||||
guid.data4[2],
|
||||
guid.data4[3],
|
||||
guid.data4[4],
|
||||
guid.data4[5],
|
||||
guid.data4[6],
|
||||
guid.data4[7]);
|
||||
return result;
|
||||
}
|
||||
|
||||
+339
-380
@@ -1,380 +1,339 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_CORE_H
|
||||
#define OS_CORE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Access Flags
|
||||
|
||||
typedef U32 OS_AccessFlags;
|
||||
enum
|
||||
{
|
||||
OS_AccessFlag_Read = (1<<0),
|
||||
OS_AccessFlag_Write = (1<<1),
|
||||
OS_AccessFlag_Execute = (1<<2),
|
||||
OS_AccessFlag_Append = (1<<3),
|
||||
OS_AccessFlag_ShareRead = (1<<4),
|
||||
OS_AccessFlag_ShareWrite = (1<<5),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ allen: Files
|
||||
|
||||
typedef U32 OS_FileIterFlags;
|
||||
enum
|
||||
{
|
||||
OS_FileIterFlag_SkipFolders = (1 << 0),
|
||||
OS_FileIterFlag_SkipFiles = (1 << 1),
|
||||
OS_FileIterFlag_SkipHiddenFiles = (1 << 2),
|
||||
OS_FileIterFlag_Done = (1 << 31),
|
||||
};
|
||||
|
||||
typedef struct OS_FileIter OS_FileIter;
|
||||
struct OS_FileIter
|
||||
{
|
||||
OS_FileIterFlags flags;
|
||||
U8 memory[800];
|
||||
};
|
||||
|
||||
typedef struct OS_FileInfo OS_FileInfo;
|
||||
struct OS_FileInfo
|
||||
{
|
||||
String8 name;
|
||||
FileProperties props;
|
||||
};
|
||||
|
||||
// nick: on-disk file identifier
|
||||
typedef struct OS_FileID OS_FileID;
|
||||
struct OS_FileID
|
||||
{
|
||||
U64 v[3];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: System Paths
|
||||
|
||||
typedef enum OS_SystemPath
|
||||
{
|
||||
OS_SystemPath_Binary,
|
||||
OS_SystemPath_Initial,
|
||||
OS_SystemPath_Current,
|
||||
OS_SystemPath_UserProgramData,
|
||||
OS_SystemPath_ModuleLoad,
|
||||
}
|
||||
OS_SystemPath;
|
||||
|
||||
typedef enum OS_PathFromUserKind
|
||||
{
|
||||
OS_PathFromUserKind_Save,
|
||||
OS_PathFromUserKind_Load,
|
||||
}
|
||||
OS_PathFromUserKind;
|
||||
|
||||
typedef struct OS_PathFromUser OS_PathFromUser;
|
||||
struct OS_PathFromUser
|
||||
{
|
||||
OS_PathFromUserKind kind;
|
||||
String8 path;
|
||||
U64 filter_count;
|
||||
String8 *filter_extensions;
|
||||
String8 *filter_names;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ allen: Launch Input
|
||||
|
||||
typedef struct OS_LaunchOptions OS_LaunchOptions;
|
||||
struct OS_LaunchOptions
|
||||
{
|
||||
String8List cmd_line;
|
||||
String8 path;
|
||||
String8List env;
|
||||
B32 inherit_env;
|
||||
B32 consoleless;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type
|
||||
|
||||
typedef struct OS_Handle OS_Handle;
|
||||
struct OS_Handle
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
typedef struct OS_HandleNode OS_HandleNode;
|
||||
struct OS_HandleNode
|
||||
{
|
||||
OS_HandleNode *next;
|
||||
OS_Handle v;
|
||||
};
|
||||
|
||||
typedef struct OS_HandleList OS_HandleList;
|
||||
struct OS_HandleList
|
||||
{
|
||||
OS_HandleNode *first;
|
||||
OS_HandleNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct OS_HandleArray OS_HandleArray;
|
||||
struct OS_HandleArray
|
||||
{
|
||||
OS_Handle *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
// Time
|
||||
|
||||
#define OS_UNIX_TIME_MAX max_U32
|
||||
typedef U32 OS_UnixTime;
|
||||
|
||||
////////////////////////////////
|
||||
// Global Unique ID
|
||||
|
||||
typedef struct OS_Guid
|
||||
{
|
||||
U32 data1;
|
||||
U16 data2;
|
||||
U16 data3;
|
||||
U8 data4[8];
|
||||
} OS_Guid;
|
||||
StaticAssert(sizeof(OS_Guid) == 16, os_guid_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Types
|
||||
|
||||
typedef void OS_ThreadFunctionType(void *ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Functions (Helpers, Implemented Once)
|
||||
|
||||
internal OS_Handle os_handle_zero(void);
|
||||
internal B32 os_handle_match(OS_Handle a, OS_Handle b);
|
||||
internal void os_handle_list_push(Arena *arena, OS_HandleList *handles, OS_Handle handle);
|
||||
internal OS_HandleArray os_handle_array_from_list(Arena *arena, OS_HandleList *list);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: System Path Helper (Helper, Implemented Once)
|
||||
|
||||
internal String8 os_string_from_system_path(Arena *arena, OS_SystemPath path);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Command Line Argc/Argv Helper (Helper, Implemented Once)
|
||||
|
||||
internal String8List os_string_list_from_argcv(Arena *arena, int argc, char **argv);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal String8 os_data_from_file_path(Arena *arena, String8 path);
|
||||
internal B32 os_write_data_to_file_path(String8 path, String8 data);
|
||||
internal B32 os_write_data_list_to_file_path(String8 path, String8List list);
|
||||
internal B32 os_append_data_to_file_path(String8 path, String8 data);
|
||||
internal OS_FileID os_id_from_file_path(String8 path);
|
||||
internal S64 os_file_id_compare(OS_FileID a, OS_FileID b);
|
||||
internal String8 os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Synchronization Primitive Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal void os_mutex_take(OS_Handle mutex);
|
||||
internal void os_mutex_drop(OS_Handle mutex);
|
||||
internal void os_rw_mutex_take_r(OS_Handle rw_mutex);
|
||||
internal void os_rw_mutex_drop_r(OS_Handle rw_mutex);
|
||||
internal void os_rw_mutex_take_w(OS_Handle rw_mutex);
|
||||
internal void os_rw_mutex_drop_w(OS_Handle rw_mutex);
|
||||
// returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout
|
||||
internal B32 os_condition_variable_wait(OS_Handle cv, OS_Handle mutex, U64 endt_us);
|
||||
internal B32 os_condition_variable_wait_rw_r(OS_Handle cv, OS_Handle rw_mutex, U64 endt_us);
|
||||
internal B32 os_condition_variable_wait_rw_w(OS_Handle cv, OS_Handle rw_mutex, U64 endt_us);
|
||||
internal void os_condition_variable_signal(OS_Handle cv);
|
||||
internal void os_condition_variable_broadcast(OS_Handle cv);
|
||||
|
||||
#define OS_MutexScope(mutex) DeferLoop(os_mutex_take(mutex), os_mutex_drop(mutex))
|
||||
#define OS_MutexScopeR(mutex) DeferLoop(os_rw_mutex_take_r(mutex), os_rw_mutex_drop_r(mutex))
|
||||
#define OS_MutexScopeW(mutex) DeferLoop(os_rw_mutex_take_w(mutex), os_rw_mutex_drop_w(mutex))
|
||||
#define OS_MutexScopeRWPromote(mutex) DeferLoop((os_rw_mutex_drop_r(mutex), os_rw_mutex_take_w(mutex)), (os_rw_mutex_drop_w(mutex), os_rw_mutex_take_r(mutex)))
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Main Initialization API (Implemented Per-OS)
|
||||
|
||||
internal void os_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
|
||||
|
||||
internal void* os_reserve(U64 size);
|
||||
internal B32 os_commit(void *ptr, U64 size);
|
||||
internal void* os_reserve_large(U64 size);
|
||||
internal B32 os_commit_large(void *ptr, U64 size);
|
||||
internal void os_decommit(void *ptr, U64 size);
|
||||
internal void os_release(void *ptr, U64 size);
|
||||
|
||||
internal B32 os_set_large_pages(B32 flag);
|
||||
internal B32 os_large_pages_enabled(void);
|
||||
internal U64 os_large_page_size(void);
|
||||
|
||||
internal void* os_alloc_ring_buffer(U64 size, U64 *actual_size_out);
|
||||
internal void os_free_ring_buffer(void *ring_buffer, U64 actual_size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks System Info (Implemented Per-OS)
|
||||
|
||||
internal String8 os_machine_name(void);
|
||||
internal U64 os_page_size(void);
|
||||
internal U64 os_allocation_granularity(void);
|
||||
internal U64 os_logical_core_count(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Process & Thread Info (Implemented Per-OS)
|
||||
|
||||
internal S32 os_get_pid(void);
|
||||
internal S32 os_get_tid(void);
|
||||
internal String8List os_get_environment(void);
|
||||
internal U64 os_string_list_from_system_path(Arena *arena, OS_SystemPath path, String8List *out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Thread Names
|
||||
|
||||
internal void os_set_thread_name(String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Process Control (Implemented Per-OS)
|
||||
|
||||
internal void os_exit_process(S32 exit_code);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks File System (Implemented Per-OS)
|
||||
|
||||
//- rjf: files
|
||||
internal OS_Handle os_file_open(OS_AccessFlags flags, String8 path);
|
||||
internal void os_file_close(OS_Handle file);
|
||||
internal U64 os_file_read(OS_Handle file, Rng1U64 rng, void *out_data);
|
||||
internal void os_file_write(OS_Handle file, Rng1U64 rng, void *data);
|
||||
internal B32 os_file_set_times(OS_Handle file, DateTime time);
|
||||
internal FileProperties os_properties_from_file(OS_Handle file);
|
||||
internal OS_FileID os_id_from_file(OS_Handle file);
|
||||
internal B32 os_delete_file_at_path(String8 path);
|
||||
internal B32 os_copy_file_path(String8 dst, String8 src);
|
||||
internal String8 os_full_path_from_path(Arena *arena, String8 path);
|
||||
internal B32 os_file_path_exists(String8 path);
|
||||
internal FileProperties os_properties_from_file_path(String8 path);
|
||||
|
||||
//- rjf: file maps
|
||||
internal OS_Handle os_file_map_open(OS_AccessFlags flags, OS_Handle file);
|
||||
internal void os_file_map_close(OS_Handle map);
|
||||
internal void * os_file_map_view_open(OS_Handle map, OS_AccessFlags flags, Rng1U64 range);
|
||||
internal void os_file_map_view_close(OS_Handle map, void *ptr);
|
||||
|
||||
//- rjf: directory iteration
|
||||
internal OS_FileIter *os_file_iter_begin(Arena *arena, String8 path, OS_FileIterFlags flags);
|
||||
internal B32 os_file_iter_next(Arena *arena, OS_FileIter *iter, OS_FileInfo *info_out);
|
||||
internal void os_file_iter_end(OS_FileIter *iter);
|
||||
|
||||
//- rjf: directory creation
|
||||
internal B32 os_make_directory(String8 path);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shared Memory (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_shared_memory_alloc(U64 size, String8 name);
|
||||
internal OS_Handle os_shared_memory_open(String8 name);
|
||||
internal void os_shared_memory_close(OS_Handle handle);
|
||||
internal void * os_shared_memory_view_open(OS_Handle handle, Rng1U64 range);
|
||||
internal void os_shared_memory_view_close(OS_Handle handle, void *ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Time (Implemented Per-OS)
|
||||
|
||||
internal OS_UnixTime os_now_unix(void);
|
||||
internal DateTime os_now_universal_time(void);
|
||||
internal DateTime os_universal_time_from_local_time(DateTime *local_time);
|
||||
internal DateTime os_local_time_from_universal_time(DateTime *universal_time);
|
||||
internal U64 os_now_microseconds(void);
|
||||
internal void os_sleep_milliseconds(U32 msec);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Child Processes (Implemented Per-OS)
|
||||
|
||||
internal B32 os_launch_process(OS_LaunchOptions *options, OS_Handle *handle_out);
|
||||
internal B32 os_process_wait(OS_Handle handle, U64 endt_us);
|
||||
internal void os_process_release_handle(OS_Handle handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Threads (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_launch_thread(OS_ThreadFunctionType *func, void *ptr, void *params);
|
||||
internal B32 os_thread_wait(OS_Handle handle, U64 endt_us);
|
||||
internal void os_release_thread_handle(OS_Handle thread);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Synchronization Primitives (Implemented Per-OS)
|
||||
|
||||
// NOTE(allen): Mutexes are recursive - support counted acquire/release nesting
|
||||
// on a single thread
|
||||
|
||||
//- rjf: recursive mutexes
|
||||
internal OS_Handle os_mutex_alloc(void);
|
||||
internal void os_mutex_release(OS_Handle mutex);
|
||||
internal void os_mutex_take_(OS_Handle mutex);
|
||||
internal void os_mutex_drop_(OS_Handle mutex);
|
||||
|
||||
//- rjf: reader/writer mutexes
|
||||
internal OS_Handle os_rw_mutex_alloc(void);
|
||||
internal void os_rw_mutex_release(OS_Handle rw_mutex);
|
||||
internal void os_rw_mutex_take_r_(OS_Handle mutex);
|
||||
internal void os_rw_mutex_drop_r_(OS_Handle mutex);
|
||||
internal void os_rw_mutex_take_w_(OS_Handle mutex);
|
||||
internal void os_rw_mutex_drop_w_(OS_Handle mutex);
|
||||
|
||||
//- rjf: condition variables
|
||||
internal OS_Handle os_condition_variable_alloc(void);
|
||||
internal void os_condition_variable_release(OS_Handle cv);
|
||||
// returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout
|
||||
internal B32 os_condition_variable_wait_(OS_Handle cv, OS_Handle mutex, U64 endt_us);
|
||||
internal B32 os_condition_variable_wait_rw_r_(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us);
|
||||
internal B32 os_condition_variable_wait_rw_w_(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us);
|
||||
internal void os_condition_variable_signal_(OS_Handle cv);
|
||||
internal void os_condition_variable_broadcast_(OS_Handle cv);
|
||||
|
||||
//- rjf: cross-process semaphores
|
||||
internal OS_Handle os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name);
|
||||
internal void os_semaphore_release(OS_Handle semaphore);
|
||||
internal OS_Handle os_semaphore_open(String8 name);
|
||||
internal void os_semaphore_close(OS_Handle semaphore);
|
||||
internal B32 os_semaphore_take(OS_Handle semaphore, U64 endt_us);
|
||||
internal void os_semaphore_drop(OS_Handle semaphore);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_library_open(String8 path);
|
||||
internal VoidProc *os_library_load_proc(OS_Handle lib, String8 name);
|
||||
internal void os_library_close(OS_Handle lib);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Safe Calls (Implemented Per-OS)
|
||||
|
||||
internal void os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, void *ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks GUIDs (Implemented Per-OS)
|
||||
|
||||
internal OS_Guid os_make_guid(void);
|
||||
internal String8 os_string_from_guid(Arena *arena, OS_Guid guid);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Entry Points (Implemented Per-OS)
|
||||
|
||||
// NOTE(rjf): The implementation of `os_core` will define low-level entry
|
||||
// points if BUILD_ENTRY_DEFINING_UNIT is defined to 1. These will call
|
||||
// into the standard codebase program entry points, named "entry_point".
|
||||
|
||||
#if BUILD_ENTRY_DEFINING_UNIT
|
||||
internal void entry_point(CmdLine *cmdline);
|
||||
#endif
|
||||
|
||||
#endif // OS_CORE_H
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_CORE_H
|
||||
#define OS_CORE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: System Info
|
||||
|
||||
typedef struct OS_SystemInfo OS_SystemInfo;
|
||||
struct OS_SystemInfo
|
||||
{
|
||||
U32 logical_processor_count;
|
||||
U64 page_size;
|
||||
U64 large_page_size;
|
||||
U64 allocation_granularity;
|
||||
U64 microsecond_resolution;
|
||||
String8 machine_name;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Info
|
||||
|
||||
typedef struct OS_ProcessInfo OS_ProcessInfo;
|
||||
struct OS_ProcessInfo
|
||||
{
|
||||
U32 pid;
|
||||
String8 binary_path;
|
||||
String8 initial_path;
|
||||
String8 user_program_data_path;
|
||||
String8List module_load_paths;
|
||||
String8List environment;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Access Flags
|
||||
|
||||
typedef U32 OS_AccessFlags;
|
||||
enum
|
||||
{
|
||||
OS_AccessFlag_Read = (1<<0),
|
||||
OS_AccessFlag_Write = (1<<1),
|
||||
OS_AccessFlag_Execute = (1<<2),
|
||||
OS_AccessFlag_Append = (1<<3),
|
||||
OS_AccessFlag_ShareRead = (1<<4),
|
||||
OS_AccessFlag_ShareWrite = (1<<5),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Files
|
||||
|
||||
typedef U32 OS_FileIterFlags;
|
||||
enum
|
||||
{
|
||||
OS_FileIterFlag_SkipFolders = (1 << 0),
|
||||
OS_FileIterFlag_SkipFiles = (1 << 1),
|
||||
OS_FileIterFlag_SkipHiddenFiles = (1 << 2),
|
||||
OS_FileIterFlag_Done = (1 << 31),
|
||||
};
|
||||
|
||||
typedef struct OS_FileIter OS_FileIter;
|
||||
struct OS_FileIter
|
||||
{
|
||||
OS_FileIterFlags flags;
|
||||
U8 memory[800];
|
||||
};
|
||||
|
||||
typedef struct OS_FileInfo OS_FileInfo;
|
||||
struct OS_FileInfo
|
||||
{
|
||||
String8 name;
|
||||
FileProperties props;
|
||||
};
|
||||
|
||||
// nick: on-disk file identifier
|
||||
typedef struct OS_FileID OS_FileID;
|
||||
struct OS_FileID
|
||||
{
|
||||
U64 v[3];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Launch Parameters
|
||||
|
||||
typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams;
|
||||
struct OS_ProcessLaunchParams
|
||||
{
|
||||
String8List cmd_line;
|
||||
String8 path;
|
||||
String8List env;
|
||||
B32 inherit_env;
|
||||
B32 consoleless;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type
|
||||
|
||||
typedef struct OS_Handle OS_Handle;
|
||||
struct OS_Handle
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
typedef struct OS_HandleNode OS_HandleNode;
|
||||
struct OS_HandleNode
|
||||
{
|
||||
OS_HandleNode *next;
|
||||
OS_Handle v;
|
||||
};
|
||||
|
||||
typedef struct OS_HandleList OS_HandleList;
|
||||
struct OS_HandleList
|
||||
{
|
||||
OS_HandleNode *first;
|
||||
OS_HandleNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct OS_HandleArray OS_HandleArray;
|
||||
struct OS_HandleArray
|
||||
{
|
||||
OS_Handle *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globally Unique IDs
|
||||
|
||||
typedef struct OS_Guid OS_Guid;
|
||||
struct OS_Guid
|
||||
{
|
||||
U32 data1;
|
||||
U16 data2;
|
||||
U16 data3;
|
||||
U8 data4[8];
|
||||
};
|
||||
StaticAssert(sizeof(OS_Guid) == 16, os_guid_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Types
|
||||
|
||||
typedef void OS_ThreadFunctionType(void *ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Functions (Helpers, Implemented Once)
|
||||
|
||||
internal OS_Handle os_handle_zero(void);
|
||||
internal B32 os_handle_match(OS_Handle a, OS_Handle b);
|
||||
internal void os_handle_list_push(Arena *arena, OS_HandleList *handles, OS_Handle handle);
|
||||
internal OS_HandleArray os_handle_array_from_list(Arena *arena, OS_HandleList *list);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Command Line Argc/Argv Helper (Helper, Implemented Once)
|
||||
|
||||
internal String8List os_string_list_from_argcv(Arena *arena, int argc, char **argv);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal String8 os_data_from_file_path(Arena *arena, String8 path);
|
||||
internal B32 os_write_data_to_file_path(String8 path, String8 data);
|
||||
internal B32 os_write_data_list_to_file_path(String8 path, String8List list);
|
||||
internal B32 os_append_data_to_file_path(String8 path, String8 data);
|
||||
internal OS_FileID os_id_from_file_path(String8 path);
|
||||
internal S64 os_file_id_compare(OS_FileID a, OS_FileID b);
|
||||
internal String8 os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: GUID Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal String8 os_string_from_guid(Arena *arena, OS_Guid guid);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
|
||||
|
||||
internal OS_SystemInfo *os_get_system_info(void);
|
||||
internal OS_ProcessInfo *os_get_process_info(void);
|
||||
internal String8 os_get_current_path(Arena *arena);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
|
||||
|
||||
//- rjf: basic
|
||||
internal void *os_reserve(U64 size);
|
||||
internal B32 os_commit(void *ptr, U64 size);
|
||||
internal void os_decommit(void *ptr, U64 size);
|
||||
internal void os_release(void *ptr, U64 size);
|
||||
|
||||
//- rjf: large pages
|
||||
internal B32 os_set_large_pages_enabled(B32 flag);
|
||||
internal B32 os_large_pages_enabled(void);
|
||||
internal void *os_reserve_large(U64 size);
|
||||
internal B32 os_commit_large(void *ptr, U64 size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Thread Info (Implemented Per-OS)
|
||||
|
||||
internal U32 os_tid(void);
|
||||
internal void os_set_thread_name(String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Aborting (Implemented Per-OS)
|
||||
|
||||
internal void os_abort(S32 exit_code);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks File System (Implemented Per-OS)
|
||||
|
||||
//- rjf: files
|
||||
internal OS_Handle os_file_open(OS_AccessFlags flags, String8 path);
|
||||
internal void os_file_close(OS_Handle file);
|
||||
internal U64 os_file_read(OS_Handle file, Rng1U64 rng, void *out_data);
|
||||
internal void os_file_write(OS_Handle file, Rng1U64 rng, void *data);
|
||||
internal B32 os_file_set_times(OS_Handle file, DateTime time);
|
||||
internal FileProperties os_properties_from_file(OS_Handle file);
|
||||
internal OS_FileID os_id_from_file(OS_Handle file);
|
||||
internal B32 os_delete_file_at_path(String8 path);
|
||||
internal B32 os_copy_file_path(String8 dst, String8 src);
|
||||
internal String8 os_full_path_from_path(Arena *arena, String8 path);
|
||||
internal B32 os_file_path_exists(String8 path);
|
||||
internal FileProperties os_properties_from_file_path(String8 path);
|
||||
|
||||
//- rjf: file maps
|
||||
internal OS_Handle os_file_map_open(OS_AccessFlags flags, OS_Handle file);
|
||||
internal void os_file_map_close(OS_Handle map);
|
||||
internal void * os_file_map_view_open(OS_Handle map, OS_AccessFlags flags, Rng1U64 range);
|
||||
internal void os_file_map_view_close(OS_Handle map, void *ptr);
|
||||
|
||||
//- rjf: directory iteration
|
||||
internal OS_FileIter *os_file_iter_begin(Arena *arena, String8 path, OS_FileIterFlags flags);
|
||||
internal B32 os_file_iter_next(Arena *arena, OS_FileIter *iter, OS_FileInfo *info_out);
|
||||
internal void os_file_iter_end(OS_FileIter *iter);
|
||||
|
||||
//- rjf: directory creation
|
||||
internal B32 os_make_directory(String8 path);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shared Memory (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_shared_memory_alloc(U64 size, String8 name);
|
||||
internal OS_Handle os_shared_memory_open(String8 name);
|
||||
internal void os_shared_memory_close(OS_Handle handle);
|
||||
internal void * os_shared_memory_view_open(OS_Handle handle, Rng1U64 range);
|
||||
internal void os_shared_memory_view_close(OS_Handle handle, void *ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Time (Implemented Per-OS)
|
||||
|
||||
internal U64 os_now_microseconds(void);
|
||||
internal U32 os_now_unix(void);
|
||||
internal DateTime os_now_universal_time(void);
|
||||
internal DateTime os_universal_time_from_local(DateTime *local_time);
|
||||
internal DateTime os_local_time_from_universal(DateTime *universal_time);
|
||||
internal void os_sleep_milliseconds(U32 msec);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Child Processes (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_process_launch(OS_ProcessLaunchParams *params);
|
||||
internal B32 os_process_join(OS_Handle handle, U64 endt_us);
|
||||
internal void os_process_detach(OS_Handle handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Threads (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_thread_launch(OS_ThreadFunctionType *func, void *ptr, void *params);
|
||||
internal B32 os_thread_join(OS_Handle handle, U64 endt_us);
|
||||
internal void os_thread_detach(OS_Handle handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Synchronization Primitives (Implemented Per-OS)
|
||||
|
||||
//- rjf: recursive mutexes
|
||||
internal OS_Handle os_mutex_alloc(void);
|
||||
internal void os_mutex_release(OS_Handle mutex);
|
||||
internal void os_mutex_take(OS_Handle mutex);
|
||||
internal void os_mutex_drop(OS_Handle mutex);
|
||||
|
||||
//- rjf: reader/writer mutexes
|
||||
internal OS_Handle os_rw_mutex_alloc(void);
|
||||
internal void os_rw_mutex_release(OS_Handle rw_mutex);
|
||||
internal void os_rw_mutex_take_r(OS_Handle mutex);
|
||||
internal void os_rw_mutex_drop_r(OS_Handle mutex);
|
||||
internal void os_rw_mutex_take_w(OS_Handle mutex);
|
||||
internal void os_rw_mutex_drop_w(OS_Handle mutex);
|
||||
|
||||
//- rjf: condition variables
|
||||
internal OS_Handle os_condition_variable_alloc(void);
|
||||
internal void os_condition_variable_release(OS_Handle cv);
|
||||
// returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout
|
||||
internal B32 os_condition_variable_wait(OS_Handle cv, OS_Handle mutex, U64 endt_us);
|
||||
internal B32 os_condition_variable_wait_rw_r(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us);
|
||||
internal B32 os_condition_variable_wait_rw_w(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us);
|
||||
internal void os_condition_variable_signal(OS_Handle cv);
|
||||
internal void os_condition_variable_broadcast(OS_Handle cv);
|
||||
|
||||
//- rjf: cross-process semaphores
|
||||
internal OS_Handle os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name);
|
||||
internal void os_semaphore_release(OS_Handle semaphore);
|
||||
internal OS_Handle os_semaphore_open(String8 name);
|
||||
internal void os_semaphore_close(OS_Handle semaphore);
|
||||
internal B32 os_semaphore_take(OS_Handle semaphore, U64 endt_us);
|
||||
internal void os_semaphore_drop(OS_Handle semaphore);
|
||||
|
||||
//- rjf: scope macros
|
||||
#define OS_MutexScope(mutex) DeferLoop(os_mutex_take(mutex), os_mutex_drop(mutex))
|
||||
#define OS_MutexScopeR(mutex) DeferLoop(os_rw_mutex_take_r(mutex), os_rw_mutex_drop_r(mutex))
|
||||
#define OS_MutexScopeW(mutex) DeferLoop(os_rw_mutex_take_w(mutex), os_rw_mutex_drop_w(mutex))
|
||||
#define OS_MutexScopeRWPromote(mutex) DeferLoop((os_rw_mutex_drop_r(mutex), os_rw_mutex_take_w(mutex)), (os_rw_mutex_drop_w(mutex), os_rw_mutex_take_r(mutex)))
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_library_open(String8 path);
|
||||
internal void os_library_close(OS_Handle lib);
|
||||
internal VoidProc *os_library_load_proc(OS_Handle lib, String8 name);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Safe Calls (Implemented Per-OS)
|
||||
|
||||
internal void os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, void *ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks GUIDs (Implemented Per-OS)
|
||||
|
||||
internal OS_Guid os_make_guid(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Entry Points (Implemented Per-OS)
|
||||
|
||||
// NOTE(rjf): The implementation of `os_core` will define low-level entry
|
||||
// points if BUILD_ENTRY_DEFINING_UNIT is defined to 1. These will call
|
||||
// into the standard codebase program entry points, named "entry_point".
|
||||
|
||||
#if BUILD_ENTRY_DEFINING_UNIT
|
||||
internal void entry_point(CmdLine *cmdline);
|
||||
#endif
|
||||
|
||||
#endif // OS_CORE_H
|
||||
|
||||
+1669
-1856
File diff suppressed because it is too large
Load Diff
@@ -1,84 +1,124 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef WIN32_H
|
||||
#define WIN32_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Negotiate the windows header include order
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <timeapi.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <Shlobj.h>
|
||||
#include <processthreadsapi.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): File Iterator
|
||||
|
||||
typedef struct W32_FileIter W32_FileIter;
|
||||
struct W32_FileIter
|
||||
{
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAW find_data;
|
||||
B32 is_volume_iter;
|
||||
String8Array drive_strings;
|
||||
U64 drive_strings_iter_idx;
|
||||
};
|
||||
StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(W32_FileIter), file_iter_memory_size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Threading Entities
|
||||
|
||||
typedef enum W32_EntityKind
|
||||
{
|
||||
W32_EntityKind_Null,
|
||||
W32_EntityKind_Thread,
|
||||
W32_EntityKind_Mutex,
|
||||
W32_EntityKind_RWMutex,
|
||||
W32_EntityKind_ConditionVariable,
|
||||
}
|
||||
W32_EntityKind;
|
||||
|
||||
typedef struct W32_Entity W32_Entity;
|
||||
struct W32_Entity
|
||||
{
|
||||
W32_Entity *next;
|
||||
W32_EntityKind kind;
|
||||
volatile U32 reference_mask;
|
||||
union{
|
||||
struct{
|
||||
OS_ThreadFunctionType *func;
|
||||
void *ptr;
|
||||
HANDLE handle;
|
||||
DWORD tid;
|
||||
} thread;
|
||||
CRITICAL_SECTION mutex;
|
||||
SRWLOCK rw_mutex;
|
||||
CONDITION_VARIABLE cv;
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
//- rjf: files
|
||||
internal FilePropertyFlags w32_file_property_flags_from_dwFileAttributes(DWORD dwFileAttributes);
|
||||
internal void w32_file_properties_from_attributes(FileProperties *properties, WIN32_FILE_ATTRIBUTE_DATA *attributes);
|
||||
|
||||
//- rjf: time
|
||||
internal void w32_date_time_from_system_time(DateTime *out, SYSTEMTIME *in);
|
||||
internal void w32_system_time_from_date_time(SYSTEMTIME *out, DateTime *in);
|
||||
internal void w32_dense_time_from_file_time(DenseTime *out, FILETIME *in);
|
||||
internal U32 w32_sleep_ms_from_endt_us(U64 endt_us);
|
||||
|
||||
//- rjf: entities
|
||||
internal W32_Entity* w32_alloc_entity(W32_EntityKind kind);
|
||||
internal void w32_free_entity(W32_Entity *entity);
|
||||
|
||||
//- rjf: threads
|
||||
internal DWORD w32_thread_base(void *ptr);
|
||||
|
||||
#endif //WIN32_H
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_CORE_WIN32_H
|
||||
#define OS_CORE_WIN32_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes / Libraries
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <timeapi.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <Shlobj.h>
|
||||
#include <processthreadsapi.h>
|
||||
#pragma comment(lib, "user32")
|
||||
#pragma comment(lib, "winmm")
|
||||
#pragma comment(lib, "shell32")
|
||||
#pragma comment(lib, "advapi32")
|
||||
#pragma comment(lib, "rpcrt4")
|
||||
#pragma comment(lib, "shlwapi")
|
||||
#pragma comment(lib, "comctl32")
|
||||
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") // this is required for loading correct comctl32 dll file
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: File Iterator Types
|
||||
|
||||
typedef struct OS_W32_FileIter OS_W32_FileIter;
|
||||
struct OS_W32_FileIter
|
||||
{
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAW find_data;
|
||||
B32 is_volume_iter;
|
||||
String8Array drive_strings;
|
||||
U64 drive_strings_iter_idx;
|
||||
};
|
||||
StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(OS_W32_FileIter), file_iter_memory_size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Types
|
||||
|
||||
typedef enum OS_W32_EntityKind
|
||||
{
|
||||
OS_W32_EntityKind_Null,
|
||||
OS_W32_EntityKind_Thread,
|
||||
OS_W32_EntityKind_Mutex,
|
||||
OS_W32_EntityKind_RWMutex,
|
||||
OS_W32_EntityKind_ConditionVariable,
|
||||
}
|
||||
OS_W32_EntityKind;
|
||||
|
||||
typedef struct OS_W32_Entity OS_W32_Entity;
|
||||
struct OS_W32_Entity
|
||||
{
|
||||
OS_W32_Entity *next;
|
||||
OS_W32_EntityKind kind;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
OS_ThreadFunctionType *func;
|
||||
void *ptr;
|
||||
HANDLE handle;
|
||||
DWORD tid;
|
||||
} thread;
|
||||
CRITICAL_SECTION mutex;
|
||||
SRWLOCK rw_mutex;
|
||||
CONDITION_VARIABLE cv;
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: State
|
||||
|
||||
typedef struct OS_W32_State OS_W32_State;
|
||||
struct OS_W32_State
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: info
|
||||
OS_SystemInfo system_info;
|
||||
OS_ProcessInfo process_info;
|
||||
|
||||
// rjf: large pages
|
||||
B32 large_pages_enabled;
|
||||
|
||||
// rjf: entity storage
|
||||
CRITICAL_SECTION entity_mutex;
|
||||
Arena *entity_arena;
|
||||
OS_W32_Entity *entity_free;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global OS_W32_State os_w32_state = {0};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: File Info Conversion Helpers
|
||||
|
||||
internal FilePropertyFlags os_w32_file_property_flags_from_dwFileAttributes(DWORD dwFileAttributes);
|
||||
internal void os_w32_file_properties_from_attribute_data(FileProperties *properties, WIN32_FILE_ATTRIBUTE_DATA *attributes);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Time Conversion Helpers
|
||||
|
||||
internal void os_w32_date_time_from_system_time(DateTime *out, SYSTEMTIME *in);
|
||||
internal void os_w32_system_time_from_date_time(SYSTEMTIME *out, DateTime *in);
|
||||
internal void os_w32_dense_time_from_file_time(DenseTime *out, FILETIME *in);
|
||||
internal U32 os_w32_sleep_ms_from_endt_us(U64 endt_us);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Functions
|
||||
|
||||
internal OS_W32_Entity *os_w32_entity_alloc(OS_W32_EntityKind kind);
|
||||
internal void os_w32_entity_release(OS_W32_Entity *entity);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Entry Point
|
||||
|
||||
internal DWORD os_w32_thread_entry_point(void *ptr);
|
||||
|
||||
#endif // OS_CORE_WIN32_H
|
||||
|
||||
+191
-182
@@ -1,182 +1,191 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GRAPHICAL_H
|
||||
#define OS_GRAPHICAL_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Window Types
|
||||
|
||||
typedef U32 OS_WindowFlags;
|
||||
enum
|
||||
{
|
||||
OS_WindowFlag_CustomBorder = (1<<0),
|
||||
};
|
||||
|
||||
typedef void OS_WindowRepaintFunctionType(OS_Handle window, void *user_data);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cursor Types
|
||||
|
||||
typedef enum OS_Cursor
|
||||
{
|
||||
OS_Cursor_Pointer,
|
||||
OS_Cursor_IBar,
|
||||
OS_Cursor_LeftRight,
|
||||
OS_Cursor_UpDown,
|
||||
OS_Cursor_DownRight,
|
||||
OS_Cursor_UpRight,
|
||||
OS_Cursor_UpDownLeftRight,
|
||||
OS_Cursor_HandPoint,
|
||||
OS_Cursor_Disabled,
|
||||
OS_Cursor_COUNT,
|
||||
}
|
||||
OS_Cursor;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generated Code
|
||||
|
||||
#include "os/gfx/generated/os_gfx.meta.h"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Types
|
||||
|
||||
typedef enum OS_EventKind
|
||||
{
|
||||
OS_EventKind_Null,
|
||||
OS_EventKind_Press,
|
||||
OS_EventKind_Release,
|
||||
OS_EventKind_MouseMove,
|
||||
OS_EventKind_Text,
|
||||
OS_EventKind_Scroll,
|
||||
OS_EventKind_WindowLoseFocus,
|
||||
OS_EventKind_WindowClose,
|
||||
OS_EventKind_FileDrop,
|
||||
OS_EventKind_Wakeup,
|
||||
OS_EventKind_COUNT
|
||||
}
|
||||
OS_EventKind;
|
||||
|
||||
typedef U32 OS_EventFlags;
|
||||
enum
|
||||
{
|
||||
OS_EventFlag_Ctrl = (1<<0),
|
||||
OS_EventFlag_Shift = (1<<1),
|
||||
OS_EventFlag_Alt = (1<<2),
|
||||
};
|
||||
|
||||
typedef struct OS_Event OS_Event;
|
||||
struct OS_Event
|
||||
{
|
||||
OS_Event *next;
|
||||
OS_Event *prev;
|
||||
U64 timestamp_us;
|
||||
OS_Handle window;
|
||||
OS_EventKind kind;
|
||||
OS_EventFlags flags;
|
||||
OS_Key key;
|
||||
B32 is_repeat;
|
||||
B32 right_sided;
|
||||
U32 character;
|
||||
U32 repeat_count;
|
||||
Vec2F32 pos;
|
||||
Vec2F32 delta;
|
||||
String8List strings;
|
||||
};
|
||||
|
||||
typedef struct OS_EventList OS_EventList;
|
||||
struct OS_EventList
|
||||
{
|
||||
U64 count;
|
||||
OS_Event *first;
|
||||
OS_Event *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Functions (Helpers, Implemented Once)
|
||||
|
||||
internal String8List os_string_list_from_event_flags(Arena *arena, OS_EventFlags flags);
|
||||
internal U32 os_codepoint_from_event_flags_and_key(OS_EventFlags flags, OS_Key key);
|
||||
internal void os_eat_event(OS_EventList *events, OS_Event *event);
|
||||
internal B32 os_key_press(OS_EventList *events, OS_Handle window, OS_EventFlags flags, OS_Key key);
|
||||
internal B32 os_key_release(OS_EventList *events, OS_Handle window, OS_EventFlags flags, OS_Key key);
|
||||
internal B32 os_text(OS_EventList *events, OS_Handle window, U32 character);
|
||||
internal OS_EventList os_event_list_copy(Arena *arena, OS_EventList *src);
|
||||
internal void os_event_list_concat_in_place(OS_EventList *dst, OS_EventList *to_push);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Main Initialization API (Implemented Per-OS)
|
||||
|
||||
internal void os_graphical_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Clipboards (Implemented Per-OS)
|
||||
|
||||
internal void os_set_clipboard_text(String8 string);
|
||||
internal String8 os_get_clipboard_text(Arena *arena);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title);
|
||||
internal void os_window_close(OS_Handle window);
|
||||
internal void os_window_first_paint(OS_Handle window);
|
||||
internal void os_window_equip_repaint(OS_Handle window, OS_WindowRepaintFunctionType *repaint, void *user_data);
|
||||
internal void os_window_focus(OS_Handle window);
|
||||
internal B32 os_window_is_focused(OS_Handle window);
|
||||
internal B32 os_window_is_fullscreen(OS_Handle window);
|
||||
internal void os_window_set_fullscreen(OS_Handle window, B32 fullscreen);
|
||||
internal B32 os_window_is_maximized(OS_Handle window);
|
||||
internal void os_window_set_maximized(OS_Handle window, B32 maximized);
|
||||
internal void os_window_minimize(OS_Handle window);
|
||||
internal void os_window_bring_to_front(OS_Handle window);
|
||||
internal void os_window_set_monitor(OS_Handle window, OS_Handle monitor);
|
||||
internal void os_window_clear_custom_border_data(OS_Handle handle);
|
||||
internal void os_window_push_custom_title_bar(OS_Handle handle, F32 thickness);
|
||||
internal void os_window_push_custom_edges(OS_Handle handle, F32 thickness);
|
||||
internal void os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect);
|
||||
internal Rng2F32 os_rect_from_window(OS_Handle window);
|
||||
internal Rng2F32 os_client_rect_from_window(OS_Handle window);
|
||||
internal F32 os_dpi_from_window(OS_Handle window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||
|
||||
internal OS_HandleArray os_push_monitors_array(Arena *arena);
|
||||
internal OS_Handle os_primary_monitor(void);
|
||||
internal OS_Handle os_monitor_from_window(OS_Handle window);
|
||||
internal String8 os_name_from_monitor(Arena *arena, OS_Handle monitor);
|
||||
internal Vec2F32 os_dim_from_monitor(OS_Handle monitor);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Events (Implemented Per-OS)
|
||||
|
||||
internal void os_send_wakeup_event(void);
|
||||
internal OS_EventList os_get_events(Arena *arena, B32 wait);
|
||||
internal OS_EventFlags os_get_event_flags(void);
|
||||
internal B32 os_key_is_down(OS_Key key);
|
||||
internal Vec2F32 os_mouse_from_window(OS_Handle window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
|
||||
|
||||
internal void os_set_cursor(OS_Cursor cursor);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks System Properties (Implemented Per-OS)
|
||||
|
||||
internal F32 os_double_click_time(void);
|
||||
internal F32 os_caret_blink_time(void);
|
||||
internal F32 os_default_refresh_rate(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Native User-Facing Graphical Messages (Implemented Per-OS)
|
||||
|
||||
internal void os_graphical_message(B32 error, String8 title, String8 message);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shell Operations
|
||||
|
||||
internal void os_show_in_filesystem_ui(String8 path);
|
||||
|
||||
#endif // OS_GRAPHICAL_H
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GRAPHICAL_H
|
||||
#define OS_GRAPHICAL_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Graphics System Info
|
||||
|
||||
typedef struct OS_GfxInfo OS_GfxInfo;
|
||||
struct OS_GfxInfo
|
||||
{
|
||||
F32 double_click_time;
|
||||
F32 caret_blink_time;
|
||||
F32 default_refresh_rate;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Window Types
|
||||
|
||||
typedef U32 OS_WindowFlags;
|
||||
enum
|
||||
{
|
||||
OS_WindowFlag_CustomBorder = (1<<0),
|
||||
};
|
||||
|
||||
typedef void OS_WindowRepaintFunctionType(OS_Handle window, void *user_data);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cursor Types
|
||||
|
||||
typedef enum OS_Cursor
|
||||
{
|
||||
OS_Cursor_Pointer,
|
||||
OS_Cursor_IBar,
|
||||
OS_Cursor_LeftRight,
|
||||
OS_Cursor_UpDown,
|
||||
OS_Cursor_DownRight,
|
||||
OS_Cursor_UpRight,
|
||||
OS_Cursor_UpDownLeftRight,
|
||||
OS_Cursor_HandPoint,
|
||||
OS_Cursor_Disabled,
|
||||
OS_Cursor_COUNT,
|
||||
}
|
||||
OS_Cursor;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generated Code
|
||||
|
||||
#include "os/gfx/generated/os_gfx.meta.h"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Types
|
||||
|
||||
typedef enum OS_EventKind
|
||||
{
|
||||
OS_EventKind_Null,
|
||||
OS_EventKind_Press,
|
||||
OS_EventKind_Release,
|
||||
OS_EventKind_MouseMove,
|
||||
OS_EventKind_Text,
|
||||
OS_EventKind_Scroll,
|
||||
OS_EventKind_WindowLoseFocus,
|
||||
OS_EventKind_WindowClose,
|
||||
OS_EventKind_FileDrop,
|
||||
OS_EventKind_Wakeup,
|
||||
OS_EventKind_COUNT
|
||||
}
|
||||
OS_EventKind;
|
||||
|
||||
typedef U32 OS_EventFlags;
|
||||
enum
|
||||
{
|
||||
OS_EventFlag_Ctrl = (1<<0),
|
||||
OS_EventFlag_Shift = (1<<1),
|
||||
OS_EventFlag_Alt = (1<<2),
|
||||
};
|
||||
|
||||
typedef struct OS_Event OS_Event;
|
||||
struct OS_Event
|
||||
{
|
||||
OS_Event *next;
|
||||
OS_Event *prev;
|
||||
U64 timestamp_us;
|
||||
OS_Handle window;
|
||||
OS_EventKind kind;
|
||||
OS_EventFlags flags;
|
||||
OS_Key key;
|
||||
B32 is_repeat;
|
||||
B32 right_sided;
|
||||
U32 character;
|
||||
U32 repeat_count;
|
||||
Vec2F32 pos;
|
||||
Vec2F32 delta;
|
||||
String8List strings;
|
||||
};
|
||||
|
||||
typedef struct OS_EventList OS_EventList;
|
||||
struct OS_EventList
|
||||
{
|
||||
U64 count;
|
||||
OS_Event *first;
|
||||
OS_Event *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Functions (Helpers, Implemented Once)
|
||||
|
||||
internal String8List os_string_list_from_event_flags(Arena *arena, OS_EventFlags flags);
|
||||
internal U32 os_codepoint_from_event_flags_and_key(OS_EventFlags flags, OS_Key key);
|
||||
internal void os_eat_event(OS_EventList *events, OS_Event *event);
|
||||
internal B32 os_key_press(OS_EventList *events, OS_Handle window, OS_EventFlags flags, OS_Key key);
|
||||
internal B32 os_key_release(OS_EventList *events, OS_Handle window, OS_EventFlags flags, OS_Key key);
|
||||
internal B32 os_text(OS_EventList *events, OS_Handle window, U32 character);
|
||||
internal OS_EventList os_event_list_copy(Arena *arena, OS_EventList *src);
|
||||
internal void os_event_list_concat_in_place(OS_EventList *dst, OS_EventList *to_push);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Main Initialization API (Implemented Per-OS)
|
||||
|
||||
internal void os_gfx_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Graphics System Info (Implemented Per-OS)
|
||||
|
||||
internal OS_GfxInfo *os_get_gfx_info(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Clipboards (Implemented Per-OS)
|
||||
|
||||
internal void os_set_clipboard_text(String8 string);
|
||||
internal String8 os_get_clipboard_text(Arena *arena);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title);
|
||||
internal void os_window_close(OS_Handle window);
|
||||
internal void os_window_first_paint(OS_Handle window);
|
||||
internal void os_window_equip_repaint(OS_Handle window, OS_WindowRepaintFunctionType *repaint, void *user_data);
|
||||
internal void os_window_focus(OS_Handle window);
|
||||
internal B32 os_window_is_focused(OS_Handle window);
|
||||
internal B32 os_window_is_fullscreen(OS_Handle window);
|
||||
internal void os_window_set_fullscreen(OS_Handle window, B32 fullscreen);
|
||||
internal B32 os_window_is_maximized(OS_Handle window);
|
||||
internal void os_window_set_maximized(OS_Handle window, B32 maximized);
|
||||
internal void os_window_minimize(OS_Handle window);
|
||||
internal void os_window_bring_to_front(OS_Handle window);
|
||||
internal void os_window_set_monitor(OS_Handle window, OS_Handle monitor);
|
||||
internal void os_window_clear_custom_border_data(OS_Handle handle);
|
||||
internal void os_window_push_custom_title_bar(OS_Handle handle, F32 thickness);
|
||||
internal void os_window_push_custom_edges(OS_Handle handle, F32 thickness);
|
||||
internal void os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect);
|
||||
internal Rng2F32 os_rect_from_window(OS_Handle window);
|
||||
internal Rng2F32 os_client_rect_from_window(OS_Handle window);
|
||||
internal F32 os_dpi_from_window(OS_Handle window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||
|
||||
internal OS_HandleArray os_push_monitors_array(Arena *arena);
|
||||
internal OS_Handle os_primary_monitor(void);
|
||||
internal OS_Handle os_monitor_from_window(OS_Handle window);
|
||||
internal String8 os_name_from_monitor(Arena *arena, OS_Handle monitor);
|
||||
internal Vec2F32 os_dim_from_monitor(OS_Handle monitor);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Events (Implemented Per-OS)
|
||||
|
||||
internal void os_send_wakeup_event(void);
|
||||
internal OS_EventList os_get_events(Arena *arena, B32 wait);
|
||||
internal OS_EventFlags os_get_event_flags(void);
|
||||
internal B32 os_key_is_down(OS_Key key);
|
||||
internal Vec2F32 os_mouse_from_window(OS_Handle window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
|
||||
|
||||
internal void os_set_cursor(OS_Cursor cursor);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Native User-Facing Graphical Messages (Implemented Per-OS)
|
||||
|
||||
internal void os_graphical_message(B32 error, String8 title, String8 message);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shell Operations
|
||||
|
||||
internal void os_show_in_filesystem_ui(String8 path);
|
||||
|
||||
#endif // OS_GRAPHICAL_H
|
||||
|
||||
+229
-256
@@ -1,256 +1,229 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Main Initialization API (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_graphical_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Clipboards (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_set_clipboard_text(String8 string)
|
||||
{
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_get_clipboard_text(Arena *arena)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle
|
||||
os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_close(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_first_paint(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_equip_repaint(OS_Handle window, OS_WindowRepaintFunctionType *repaint, void *user_data)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_focus(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_focused(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_fullscreen(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_fullscreen(OS_Handle window, B32 fullscreen)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_maximized(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_maximized(OS_Handle window, B32 maximized)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_minimize(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_bring_to_front(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_monitor(OS_Handle window, OS_Handle monitor)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_clear_custom_border_data(OS_Handle handle)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_title_bar(OS_Handle handle, F32 thickness)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_edges(OS_Handle handle, F32 thickness)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect)
|
||||
{
|
||||
}
|
||||
|
||||
internal Rng2F32
|
||||
os_rect_from_window(OS_Handle window)
|
||||
{
|
||||
Rng2F32 rect = r2f32(v2f32(0, 0), v2f32(500, 500));
|
||||
return rect;
|
||||
}
|
||||
|
||||
internal Rng2F32
|
||||
os_client_rect_from_window(OS_Handle window)
|
||||
{
|
||||
Rng2F32 rect = r2f32(v2f32(0, 0), v2f32(500, 500));
|
||||
return rect;
|
||||
}
|
||||
|
||||
internal F32
|
||||
os_dpi_from_window(OS_Handle window)
|
||||
{
|
||||
return 96.f;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||
|
||||
internal OS_HandleArray
|
||||
os_push_monitors_array(Arena *arena)
|
||||
{
|
||||
OS_HandleArray arr = {0};
|
||||
return arr;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_primary_monitor(void)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_monitor_from_window(OS_Handle window)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_name_from_monitor(Arena *arena, OS_Handle monitor)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
os_dim_from_monitor(OS_Handle monitor)
|
||||
{
|
||||
Vec2F32 v = v2f32(1000, 1000);
|
||||
return v;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Events (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_send_wakeup_event(void)
|
||||
{
|
||||
}
|
||||
|
||||
internal OS_EventList
|
||||
os_get_events(Arena *arena, B32 wait)
|
||||
{
|
||||
OS_EventList evts = {0};
|
||||
return evts;
|
||||
}
|
||||
|
||||
internal OS_EventFlags
|
||||
os_get_event_flags(void)
|
||||
{
|
||||
OS_EventFlags f = 0;
|
||||
return f;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_key_is_down(OS_Key key)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
os_mouse_from_window(OS_Handle window)
|
||||
{
|
||||
return v2f32(0, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_set_cursor(OS_Cursor cursor)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks System Properties (Implemented Per-OS)
|
||||
|
||||
internal F32
|
||||
os_double_click_time(void)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
internal F32
|
||||
os_caret_blink_time(void)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
internal F32
|
||||
os_default_refresh_rate(void)
|
||||
{
|
||||
return 60.f;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_granular_sleep_enabled(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Native User-Facing Graphical Messages (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_graphical_message(B32 error, String8 title, String8 message)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shell Operations
|
||||
|
||||
internal void
|
||||
os_show_in_filesystem_ui(String8 path)
|
||||
{
|
||||
}
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Main Initialization API (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_gfx_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Clipboards (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_set_clipboard_text(String8 string)
|
||||
{
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_get_clipboard_text(Arena *arena)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle
|
||||
os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_close(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_first_paint(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_equip_repaint(OS_Handle window, OS_WindowRepaintFunctionType *repaint, void *user_data)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_focus(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_focused(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_fullscreen(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_fullscreen(OS_Handle window, B32 fullscreen)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_maximized(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_maximized(OS_Handle window, B32 maximized)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_minimize(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_bring_to_front(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_monitor(OS_Handle window, OS_Handle monitor)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_clear_custom_border_data(OS_Handle handle)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_title_bar(OS_Handle handle, F32 thickness)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_edges(OS_Handle handle, F32 thickness)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect)
|
||||
{
|
||||
}
|
||||
|
||||
internal Rng2F32
|
||||
os_rect_from_window(OS_Handle window)
|
||||
{
|
||||
Rng2F32 rect = r2f32(v2f32(0, 0), v2f32(500, 500));
|
||||
return rect;
|
||||
}
|
||||
|
||||
internal Rng2F32
|
||||
os_client_rect_from_window(OS_Handle window)
|
||||
{
|
||||
Rng2F32 rect = r2f32(v2f32(0, 0), v2f32(500, 500));
|
||||
return rect;
|
||||
}
|
||||
|
||||
internal F32
|
||||
os_dpi_from_window(OS_Handle window)
|
||||
{
|
||||
return 96.f;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||
|
||||
internal OS_HandleArray
|
||||
os_push_monitors_array(Arena *arena)
|
||||
{
|
||||
OS_HandleArray arr = {0};
|
||||
return arr;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_primary_monitor(void)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_monitor_from_window(OS_Handle window)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_name_from_monitor(Arena *arena, OS_Handle monitor)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
os_dim_from_monitor(OS_Handle monitor)
|
||||
{
|
||||
Vec2F32 v = v2f32(1000, 1000);
|
||||
return v;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Events (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_send_wakeup_event(void)
|
||||
{
|
||||
}
|
||||
|
||||
internal OS_EventList
|
||||
os_get_events(Arena *arena, B32 wait)
|
||||
{
|
||||
OS_EventList evts = {0};
|
||||
return evts;
|
||||
}
|
||||
|
||||
internal OS_EventFlags
|
||||
os_get_event_flags(void)
|
||||
{
|
||||
OS_EventFlags f = 0;
|
||||
return f;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_key_is_down(OS_Key key)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
os_mouse_from_window(OS_Handle window)
|
||||
{
|
||||
return v2f32(0, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_set_cursor(OS_Cursor cursor)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Native User-Facing Graphical Messages (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_graphical_message(B32 error, String8 title, String8 message)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shell Operations
|
||||
|
||||
internal void
|
||||
os_show_in_filesystem_ui(String8 path)
|
||||
{
|
||||
}
|
||||
|
||||
+1525
-1461
File diff suppressed because it is too large
Load Diff
+115
-82
@@ -1,82 +1,115 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef WIN32_GRAPHICAL_H
|
||||
#define WIN32_GRAPHICAL_H
|
||||
|
||||
#pragma comment(lib, "user32")
|
||||
#pragma comment(lib, "gdi32")
|
||||
|
||||
#ifndef WM_NCUAHDRAWCAPTION
|
||||
#define WM_NCUAHDRAWCAPTION (0x00AE)
|
||||
#endif
|
||||
#ifndef WM_NCUAHDRAWFRAME
|
||||
#define WM_NCUAHDRAWFRAME (0x00AF)
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows
|
||||
|
||||
typedef struct W32_TitleBarClientArea W32_TitleBarClientArea;
|
||||
struct W32_TitleBarClientArea
|
||||
{
|
||||
W32_TitleBarClientArea *next;
|
||||
Rng2F32 rect;
|
||||
};
|
||||
|
||||
typedef struct W32_Window W32_Window;
|
||||
struct W32_Window
|
||||
{
|
||||
W32_Window *next;
|
||||
W32_Window *prev;
|
||||
HWND hwnd;
|
||||
WINDOWPLACEMENT last_window_placement;
|
||||
OS_WindowRepaintFunctionType *repaint;
|
||||
void *repaint_user_data;
|
||||
F32 dpi;
|
||||
B32 first_paint_done;
|
||||
B32 maximized;
|
||||
B32 custom_border;
|
||||
F32 custom_border_title_thickness;
|
||||
F32 custom_border_edge_thickness;
|
||||
B32 custom_border_composition_enabled;
|
||||
Arena *paint_arena;
|
||||
W32_TitleBarClientArea *first_title_bar_client_area;
|
||||
W32_TitleBarClientArea *last_title_bar_client_area;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitor Gathering Bundle
|
||||
|
||||
typedef struct W32_MonitorGatherBundle W32_MonitorGatherBundle;
|
||||
struct W32_MonitorGatherBundle
|
||||
{
|
||||
Arena *arena;
|
||||
OS_HandleList *list;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal Rng2F32 w32_base_rect_from_win32_rect(RECT rect);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows
|
||||
|
||||
internal OS_Handle os_window_from_w32_window(W32_Window *window);
|
||||
internal W32_Window * w32_window_from_os_window(OS_Handle window);
|
||||
internal W32_Window * w32_window_from_hwnd(HWND hwnd);
|
||||
internal HWND w32_hwnd_from_window(W32_Window *window);
|
||||
internal W32_Window * w32_allocate_window(void);
|
||||
internal void w32_free_window(W32_Window *window);
|
||||
internal OS_Event * w32_push_event(OS_EventKind kind, W32_Window *window);
|
||||
internal OS_Key w32_os_key_from_vkey(WPARAM vkey);
|
||||
internal WPARAM w32_vkey_from_os_key(OS_Key key);
|
||||
internal LRESULT w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitors
|
||||
|
||||
internal BOOL w32_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr);
|
||||
|
||||
#endif // WIN32_GRAPHICAL_H
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GFX_WIN32_H
|
||||
#define OS_GFX_WIN32_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes / Libraries
|
||||
|
||||
#include <uxtheme.h>
|
||||
#include <dwmapi.h>
|
||||
#include <shellscalingapi.h>
|
||||
#pragma comment(lib, "gdi32")
|
||||
#pragma comment(lib, "dwmapi")
|
||||
#pragma comment(lib, "UxTheme")
|
||||
#pragma comment(lib, "ole32")
|
||||
#pragma comment(lib, "user32")
|
||||
#ifndef WM_NCUAHDRAWCAPTION
|
||||
#define WM_NCUAHDRAWCAPTION (0x00AE)
|
||||
#endif
|
||||
#ifndef WM_NCUAHDRAWFRAME
|
||||
#define WM_NCUAHDRAWFRAME (0x00AF)
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows
|
||||
|
||||
typedef struct OS_W32_TitleBarClientArea OS_W32_TitleBarClientArea;
|
||||
struct OS_W32_TitleBarClientArea
|
||||
{
|
||||
OS_W32_TitleBarClientArea *next;
|
||||
Rng2F32 rect;
|
||||
};
|
||||
|
||||
typedef struct OS_W32_Window OS_W32_Window;
|
||||
struct OS_W32_Window
|
||||
{
|
||||
OS_W32_Window *next;
|
||||
OS_W32_Window *prev;
|
||||
HWND hwnd;
|
||||
WINDOWPLACEMENT last_window_placement;
|
||||
OS_WindowRepaintFunctionType *repaint;
|
||||
void *repaint_user_data;
|
||||
F32 dpi;
|
||||
B32 first_paint_done;
|
||||
B32 maximized;
|
||||
B32 custom_border;
|
||||
F32 custom_border_title_thickness;
|
||||
F32 custom_border_edge_thickness;
|
||||
B32 custom_border_composition_enabled;
|
||||
Arena *paint_arena;
|
||||
OS_W32_TitleBarClientArea *first_title_bar_client_area;
|
||||
OS_W32_TitleBarClientArea *last_title_bar_client_area;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitor Gathering Bundle
|
||||
|
||||
typedef struct OS_W32_MonitorGatherBundle OS_W32_MonitorGatherBundle;
|
||||
struct OS_W32_MonitorGatherBundle
|
||||
{
|
||||
Arena *arena;
|
||||
OS_HandleList *list;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Global State
|
||||
|
||||
typedef struct OS_W32_GfxState OS_W32_GfxState;
|
||||
struct OS_W32_GfxState
|
||||
{
|
||||
Arena *arena;
|
||||
U32 gfx_thread_tid;
|
||||
HINSTANCE hInstance;
|
||||
HCURSOR hCursor;
|
||||
OS_GfxInfo gfx_info;
|
||||
OS_W32_Window *first_window;
|
||||
OS_W32_Window *last_window;
|
||||
OS_W32_Window *free_window;
|
||||
OS_Key key_from_vkey_table[256];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global OS_W32_GfxState *os_w32_gfx_state = 0;
|
||||
global OS_EventList os_w32_event_list = {0};
|
||||
global Arena *os_w32_event_arena = 0;
|
||||
B32 os_w32_resizing = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal Rng2F32 os_w32_rng2f32_from_rect(RECT rect);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows
|
||||
|
||||
internal OS_Handle os_w32_handle_from_window(OS_W32_Window *window);
|
||||
internal OS_W32_Window * os_w32_window_from_handle(OS_Handle window);
|
||||
internal OS_W32_Window * os_w32_window_from_hwnd(HWND hwnd);
|
||||
internal HWND os_w32_hwnd_from_window(OS_W32_Window *window);
|
||||
internal OS_W32_Window * os_w32_window_alloc(void);
|
||||
internal void os_w32_window_release(OS_W32_Window *window);
|
||||
internal OS_Event * os_w32_push_event(OS_EventKind kind, OS_W32_Window *window);
|
||||
internal OS_Key os_w32_os_key_from_vkey(WPARAM vkey);
|
||||
internal WPARAM os_w32_vkey_from_os_key(OS_Key key);
|
||||
internal LRESULT os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitors
|
||||
|
||||
internal BOOL os_w32_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr);
|
||||
|
||||
#endif // OS_GFX_WIN32_H
|
||||
|
||||
+27
-33
@@ -1,33 +1,27 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Include OS features for extra features and target OS
|
||||
|
||||
#include "core/os_core.c"
|
||||
|
||||
#if OS_FEATURE_SOCKET
|
||||
#include "socket/os_socket.c"
|
||||
#endif
|
||||
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
#include "gfx/os_gfx.c"
|
||||
#endif
|
||||
|
||||
#if OS_WINDOWS
|
||||
# include "core/win32/os_core_win32.c"
|
||||
# if OS_FEATURE_SOCKET
|
||||
# include "socket/win32/os_socket_win32.c"
|
||||
# endif
|
||||
# if OS_FEATURE_GRAPHICAL && !OS_GFX_STUB
|
||||
# include "gfx/win32/os_gfx_win32.c"
|
||||
# endif
|
||||
#elif OS_LINUX
|
||||
# include "core/linux/os_core_linux.c"
|
||||
#else
|
||||
# error no OS layer setup
|
||||
#endif
|
||||
|
||||
#if OS_GFX_STUB
|
||||
#include "gfx/stub/os_gfx_stub.c"
|
||||
#endif
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#include "os/core/os_core.c"
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
# include "os/gfx/os_gfx.c"
|
||||
#endif
|
||||
|
||||
#if OS_WINDOWS
|
||||
# include "os/core/win32/os_core_win32.c"
|
||||
#elif OS_LINUX
|
||||
# include "os/core/linux/os_core_linux.c"
|
||||
#else
|
||||
# error OS core layer not implemented for this operating system.
|
||||
#endif
|
||||
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
# if OS_GFX_STUB
|
||||
# include "os/gfx/stub/os_gfx_stub.c"
|
||||
# elif OS_WINDOWS
|
||||
# include "os/gfx/win32/os_gfx_win32.c"
|
||||
# elif OS_LINUX
|
||||
# include "os/gfx/linux/os_gfx_linux.c"
|
||||
# else
|
||||
# error OS graphical layer not implemented for this operating system.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+40
-47
@@ -1,47 +1,40 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_INC_H
|
||||
#define OS_INC_H
|
||||
|
||||
#if !defined(OS_FEATURE_SOCKET)
|
||||
# define OS_FEATURE_SOCKET 0
|
||||
#endif
|
||||
|
||||
#if !defined(OS_FEATURE_GRAPHICAL)
|
||||
# define OS_FEATURE_GRAPHICAL 0
|
||||
#endif
|
||||
|
||||
#if !defined(OS_GFX_STUB)
|
||||
# define OS_GFX_STUB 0
|
||||
#endif
|
||||
|
||||
#include "core/os_core.h"
|
||||
|
||||
#if OS_FEATURE_SOCKET
|
||||
#include "socket/os_socket.h"
|
||||
#endif
|
||||
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
#include "gfx/os_gfx.h"
|
||||
#endif
|
||||
|
||||
#if OS_WINDOWS
|
||||
# include "core/win32/os_core_win32.h"
|
||||
# if OS_FEATURE_SOCKET
|
||||
# include "socket/win32/os_socket_win32.h"
|
||||
# endif
|
||||
# if OS_FEATURE_GRAPHICAL && !OS_GFX_STUB
|
||||
# include "gfx/win32/os_gfx_win32.h"
|
||||
# endif
|
||||
#elif OS_LINUX
|
||||
# include "core/linux/os_core_linux.h"
|
||||
#else
|
||||
# error no OS layer setup
|
||||
#endif
|
||||
|
||||
#if OS_GFX_STUB
|
||||
#include "gfx/stub/os_gfx_stub.h"
|
||||
#endif
|
||||
|
||||
#endif //OS_SWITCH_H
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_INC_H
|
||||
#define OS_INC_H
|
||||
|
||||
#if !defined(OS_FEATURE_GRAPHICAL)
|
||||
# define OS_FEATURE_GRAPHICAL 0
|
||||
#endif
|
||||
|
||||
#if !defined(OS_GFX_STUB)
|
||||
# define OS_GFX_STUB 0
|
||||
#endif
|
||||
|
||||
#include "os/core/os_core.h"
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
# include "os/gfx/os_gfx.h"
|
||||
#endif
|
||||
|
||||
#if OS_WINDOWS
|
||||
# include "os/core/win32/os_core_win32.h"
|
||||
#elif OS_LINUX
|
||||
# include "os/core/linux/os_core_linux.h"
|
||||
#else
|
||||
# error OS core layer not implemented for this operating system.
|
||||
#endif
|
||||
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
# if OS_GFX_STUB
|
||||
# include "os/gfx/stub/os_gfx_stub.h"
|
||||
# elif OS_WINDOWS
|
||||
# include "os/gfx/win32/os_gfx_win32.h"
|
||||
# elif OS_LINUX
|
||||
# include "os/gfx/linux/os_gfx_linux.h"
|
||||
# else
|
||||
# error OS graphical layer not implemented for this operating system.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // OS_INC_H
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Helper
|
||||
|
||||
internal B32
|
||||
os_socket_write(OS_Socket *socket, String8 data){
|
||||
String8Node node = {0};
|
||||
String8List list = {0};
|
||||
str8_list_push(&list, &node, data);
|
||||
B32 result = os_socket_write(socket, list);
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_SOCKET_H
|
||||
#define OS_SOCKET_H
|
||||
|
||||
enum OS_SocketStatus{
|
||||
OS_SocketStatus_Uninitialized,
|
||||
OS_SocketStatus_Connected,
|
||||
OS_SocketStatus_GracefullyClosed,
|
||||
OS_SocketStatus_Error,
|
||||
};
|
||||
|
||||
typedef U16 OS_SocketError;
|
||||
enum{
|
||||
OS_SocketError_None,
|
||||
OS_SocketError_SocketSystemNotInitialized,
|
||||
OS_SocketError_BadPortArgument,
|
||||
OS_SocketError_BadIPArgument,
|
||||
OS_SocketError_WSAError,
|
||||
};
|
||||
|
||||
struct OS_Socket{
|
||||
U8 memory[32];
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Implemented Per Operating System
|
||||
|
||||
internal void os_socket_init(void);
|
||||
|
||||
internal void os_socket_listen(OS_Socket *socket, String8 port);
|
||||
internal void os_socket_connect(OS_Socket *socket, String8 ip, String8 port);
|
||||
internal void os_socket_close(OS_Socket *socket);
|
||||
|
||||
internal String8 os_socket_read(Arena *arena, OS_Socket *socket);
|
||||
internal B32 os_socket_write(OS_Socket *socket, String8List list);
|
||||
|
||||
internal B32 os_socket_status(OS_Socket *socket, OS_SocketStatus status);
|
||||
internal String8 os_socket_error_string(Arena *arena, OS_Socket *socket);
|
||||
internal void os_socket_assert_on_error(OS_Socket *socket, B32 assert_on_error);
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Helpers - Portable Implementation
|
||||
|
||||
internal B32 os_socket_write(OS_Socket *socket, String8 data);
|
||||
|
||||
#endif //OS_SOCKET_H
|
||||
@@ -1,353 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal void
|
||||
w32_socket_set_error(W32_Socket *socket, OS_SocketError error){
|
||||
socket->error = error;
|
||||
// NOTE(allen): This flag was set earlier so that the socket would assert
|
||||
// when an error occurs. The "bug" or issue is whatever caused this error
|
||||
// not the fact the flag is set. Unless the flag wasn't supposed to be set!
|
||||
Assert(!(socket->flags & W32_SocketFlag_AssertOnError));
|
||||
}
|
||||
|
||||
internal void
|
||||
w32_socket_set_error_wsa(W32_Socket *socket, int wsa_error){
|
||||
switch (wsa_error){
|
||||
default:
|
||||
{
|
||||
socket->wsa_error = wsa_error;
|
||||
w32_socket_set_error(socket, OS_SocketError_WSAError);
|
||||
}break;
|
||||
case WSANOTINITIALISED:
|
||||
{
|
||||
w32_socket_set_error(socket, OS_SocketError_SocketSystemNotInitialized);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
internal B32
|
||||
w32_socket_read_looped(W32_Socket *w32_socket, void *buffer, U32 size){
|
||||
U32 p = 0;
|
||||
CHAR *ptr = (CHAR*)buffer;
|
||||
for (;p < size;){
|
||||
DWORD amt = (DWORD)(size - p);
|
||||
WSABUF wsabuf = {amt, ptr};
|
||||
// NOTE(allen): The flags pointer is _NOT_ optional but we can ignore it.
|
||||
// We have to zero it because it's an in/out pointer.
|
||||
DWORD ignore = 0;
|
||||
if (WSARecv(w32_socket->socket, &wsabuf, 1, &amt, &ignore, 0, 0) != 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
break;
|
||||
}
|
||||
if (amt == 0){
|
||||
w32_socket->flags |= W32_SocketFlag_Closed;
|
||||
break;
|
||||
}
|
||||
p += amt;
|
||||
ptr += amt;
|
||||
}
|
||||
B32 result = (p == size);
|
||||
return(result);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Per-OS Hook Implementations
|
||||
|
||||
internal void
|
||||
os_socket_init(void){
|
||||
WSADATA wsaData;
|
||||
WORD vreq = MAKEWORD(2,2);
|
||||
WSAStartup(vreq, &wsaData);
|
||||
}
|
||||
|
||||
internal void
|
||||
os_socket_listen(OS_Socket *s, String8 port){
|
||||
W32_Socket *w32_socket = (W32_Socket*)s->memory;
|
||||
|
||||
// NOTE(allen): check port string
|
||||
char port_buffer[6];
|
||||
if (port.size == 0 || port.size >= sizeof(port_buffer)){
|
||||
w32_socket_set_error(w32_socket, OS_SocketError_BadPortArgument);
|
||||
return;
|
||||
}
|
||||
MemoryCopy(port_buffer, port.str, port.size);
|
||||
port_buffer[port.size] = 0;
|
||||
|
||||
// NOTE(allen): listen socket addrinfo
|
||||
addrinfo listen_hint = {0};
|
||||
listen_hint.ai_flags = AI_PASSIVE|AI_NUMERICSERV;
|
||||
listen_hint.ai_family = AF_UNSPEC;
|
||||
listen_hint.ai_socktype = SOCK_STREAM;
|
||||
listen_hint.ai_protocol = AF_UNSPEC;
|
||||
|
||||
addrinfo *addr = {0};
|
||||
INT error = getaddrinfo(0, port_buffer, &listen_hint, &addr);
|
||||
if (error != 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(allen): init listen socket
|
||||
SOCKET socket_listener = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
W32_SocketCloser listener_closer(&socket_listener);
|
||||
|
||||
// NOTE(allen): reuseraddr
|
||||
{
|
||||
union { B32 b; char c[1]; } enable;
|
||||
enable.b = true;
|
||||
if (setsockopt(socket_listener, SOL_SOCKET, SO_REUSEADDR, enable.c, sizeof(enable)) < 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): bind
|
||||
if (bind(socket_listener, addr->ai_addr, (int)addr->ai_addrlen) < 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(allen): listen
|
||||
if (listen(socket_listener, 1) < 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(allen): accept
|
||||
SOCKET client_socket = accept(socket_listener, 0, 0);
|
||||
W32_SocketCloser client_closer(&client_socket);
|
||||
|
||||
// NOTE(allen): TCP_NODELAY
|
||||
{
|
||||
union { B32 b; char c[1]; } enable;
|
||||
enable.b = true;
|
||||
if (setsockopt(client_socket, IPPROTO_TCP, TCP_NODELAY, enable.c, sizeof(enable)) < 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): success
|
||||
w32_socket->flags |= W32_SocketFlag_Connected;
|
||||
w32_socket->socket = client_socket;
|
||||
w32_socket->error = OS_SocketError_None;
|
||||
client_closer.do_not_close();
|
||||
}
|
||||
|
||||
internal void
|
||||
os_socket_connect(OS_Socket *s, String8 ip, String8 port){
|
||||
W32_Socket *w32_socket = (W32_Socket*)s->memory;
|
||||
|
||||
// NOTE(allen): check port string
|
||||
char port_buffer[6];
|
||||
if (port.size == 0 || port.size >= sizeof(port_buffer)){
|
||||
w32_socket_set_error(w32_socket, OS_SocketError_BadPortArgument);
|
||||
return;
|
||||
}
|
||||
MemoryCopy(port_buffer, port.str, port.size);
|
||||
port_buffer[port.size] = 0;
|
||||
|
||||
// NOTE(allen): check ip string
|
||||
if (ip.size == 0){
|
||||
ip = str8_lit("localhost");
|
||||
}
|
||||
char ip_buffer[KB(1)];
|
||||
if (ip.size >= sizeof(ip_buffer)){
|
||||
w32_socket_set_error(w32_socket, OS_SocketError_BadIPArgument);
|
||||
return;
|
||||
}
|
||||
MemoryCopy(ip_buffer, ip.str, ip.size);
|
||||
ip_buffer[ip.size] = 0;
|
||||
|
||||
// NOTE(allen): socket addrinfo
|
||||
addrinfo hint = {0};
|
||||
hint.ai_flags = AI_PASSIVE|AI_NUMERICSERV;
|
||||
hint.ai_family = AF_UNSPEC;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
hint.ai_protocol = AF_UNSPEC;
|
||||
|
||||
addrinfo *addr = {0};
|
||||
INT error = getaddrinfo(ip_buffer, port_buffer, &hint, &addr);
|
||||
if (error != 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(allen): init socket
|
||||
SOCKET socket_server = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
W32_SocketCloser closer(&socket_server);
|
||||
|
||||
// NOTE(allen): TCP_NODELAY
|
||||
{
|
||||
union { B32 b; char c[1]; } enable;
|
||||
enable.b = true;
|
||||
if (setsockopt(socket_server, IPPROTO_TCP, TCP_NODELAY, enable.c, sizeof(enable)) < 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): connect
|
||||
if (connect(socket_server, addr->ai_addr, (int)addr->ai_addrlen) < 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(allen): success
|
||||
w32_socket->flags |= W32_SocketFlag_Connected;
|
||||
w32_socket->socket = socket_server;
|
||||
w32_socket->error = OS_SocketError_None;
|
||||
closer.do_not_close();
|
||||
}
|
||||
|
||||
internal void
|
||||
os_socket_close(OS_Socket *socket){
|
||||
W32_Socket *w32_socket = (W32_Socket*)socket->memory;
|
||||
closesocket(w32_socket->socket);
|
||||
MemoryZeroStruct(w32_socket);
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_socket_read(Arena *arena, OS_Socket *socket){
|
||||
W32_Socket *w32_socket = (W32_Socket*)socket->memory;
|
||||
String8 result = {0};
|
||||
U32 size = 0;
|
||||
if (w32_socket_read_looped(w32_socket, &size, sizeof(size))){
|
||||
Temp restore = temp_begin(arena);
|
||||
result.str = push_array_no_zero(arena, U8, size);
|
||||
if (w32_socket_read_looped(w32_socket, result.str, size)){
|
||||
result.size = size;
|
||||
}
|
||||
else{
|
||||
temp_end(restore);
|
||||
result.str = 0;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_socket_write(OS_Socket *socket, String8List list){
|
||||
U32 size = (U32)list.total_size;
|
||||
String8Node node = {0};
|
||||
str8_list_push_front(&list, &node, str8_struct(&size));
|
||||
|
||||
W32_Socket *w32_socket = (W32_Socket*)socket->memory;
|
||||
|
||||
WSABUF wsabuf[64];
|
||||
Assert(list.node_count <= ArrayCount(wsabuf));
|
||||
|
||||
U64 wsabuf_count = 0;
|
||||
for (String8Node *node = list.first;
|
||||
node != 0;
|
||||
node = node->next){
|
||||
wsabuf[wsabuf_count].len = (U32)node->string.size;
|
||||
wsabuf[wsabuf_count].buf = (CHAR*)node->string.str;
|
||||
wsabuf_count += 1;
|
||||
}
|
||||
|
||||
B32 result = false;
|
||||
DWORD amt = 0;
|
||||
if (WSASend(w32_socket->socket, wsabuf, wsabuf_count, &amt, 0, 0, 0) != 0){
|
||||
w32_socket_set_error_wsa(w32_socket, WSAGetLastError());
|
||||
}
|
||||
else if (amt == 0){
|
||||
w32_socket->flags |= W32_SocketFlag_Connected;
|
||||
}
|
||||
else{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_socket_status(OS_Socket *socket, OS_SocketStatus status){
|
||||
W32_Socket *w32_socket = (W32_Socket*)socket;
|
||||
B32 result = false;
|
||||
switch (status){
|
||||
case OS_SocketStatus_Uninitialized:
|
||||
{
|
||||
result = (((w32_socket->flags & (W32_SocketFlag_Connected|W32_SocketFlag_Closed)) == 0) &&
|
||||
(w32_socket->error == 0));
|
||||
}break;
|
||||
|
||||
case OS_SocketStatus_Connected:
|
||||
{
|
||||
result = (((w32_socket->flags & (W32_SocketFlag_Connected|W32_SocketFlag_Closed)) == W32_SocketFlag_Connected) &&
|
||||
(w32_socket->error == 0));
|
||||
}break;
|
||||
|
||||
case OS_SocketStatus_GracefullyClosed:
|
||||
{
|
||||
result = (((w32_socket->flags & W32_SocketFlag_Closed) == W32_SocketFlag_Closed) && (w32_socket->error == 0));
|
||||
}break;
|
||||
|
||||
case OS_SocketStatus_Error:
|
||||
{
|
||||
result = (w32_socket->error != 0);
|
||||
}break;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_socket_error_string(Arena *arena, OS_Socket *socket){
|
||||
String8 result = str8_lit("no error");
|
||||
|
||||
W32_Socket *w32_socket = (W32_Socket*)socket;
|
||||
switch (w32_socket->error){
|
||||
default:
|
||||
{
|
||||
result = str8_lit("Bad error code");
|
||||
}break;
|
||||
|
||||
case OS_SocketError_None:break;
|
||||
|
||||
case OS_SocketError_SocketSystemNotInitialized:
|
||||
{
|
||||
result = str8_lit("Missing call to os_socket_init");
|
||||
}break;
|
||||
|
||||
case OS_SocketError_BadPortArgument:
|
||||
{
|
||||
result = str8_lit("Invalid port argument to socket API");
|
||||
}break;
|
||||
|
||||
case OS_SocketError_BadIPArgument:
|
||||
{
|
||||
result = str8_lit("Invalid ip argument to socket API");
|
||||
}break;
|
||||
|
||||
case OS_SocketError_WSAError:
|
||||
{
|
||||
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_FROM_SYSTEM;
|
||||
CHAR *message = 0;
|
||||
DWORD size = FormatMessageA(flags, 0, w32_socket->wsa_error, 0, (CHAR*)&message, 0, 0);
|
||||
if (size == 0){
|
||||
result = str8_lit("Unknown WSA error");
|
||||
}
|
||||
else{
|
||||
String8 string = str8_skip_chop_whitespace(str8((U8*)message, size));
|
||||
result = push_str8_copy(arena, string);
|
||||
LocalFree(message);
|
||||
}
|
||||
}break;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
os_socket_assert_on_error(OS_Socket *socket, B32 assert_on_error){
|
||||
W32_Socket *w32_socket = (W32_Socket*)socket;
|
||||
if (assert_on_error){
|
||||
w32_socket->flags |= W32_SocketFlag_AssertOnError;
|
||||
}
|
||||
else{
|
||||
w32_socket->flags &= ~W32_SocketFlag_AssertOnError;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef WIN32_SOCKET_H
|
||||
#define WIN32_SOCKET_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Types
|
||||
|
||||
typedef U16 W32_SocketFlags;
|
||||
enum{
|
||||
W32_SocketFlag_Connected = (1 << 0),
|
||||
W32_SocketFlag_Closed = (1 << 1),
|
||||
W32_SocketFlag_AssertOnError = (1 << 2),
|
||||
};
|
||||
|
||||
struct W32_Socket{
|
||||
W32_SocketFlags flags;
|
||||
OS_SocketError error;
|
||||
int wsa_error;
|
||||
SOCKET socket;
|
||||
};
|
||||
|
||||
struct W32_SocketCloser{
|
||||
B32 need_to_close;
|
||||
SOCKET *socket;
|
||||
W32_SocketCloser(SOCKET *s){
|
||||
this->need_to_close = true;
|
||||
this->socket = s;
|
||||
}
|
||||
~W32_SocketCloser(){
|
||||
this->close_now();
|
||||
}
|
||||
void close_now(){
|
||||
if (this->need_to_close){
|
||||
closesocket(*this->socket);
|
||||
this->need_to_close = false;
|
||||
}
|
||||
}
|
||||
void do_not_close(){
|
||||
this->need_to_close = false;
|
||||
}
|
||||
};
|
||||
|
||||
StaticAssert(sizeof(Member(OS_Socket, memory)) >= sizeof(W32_Socket), socket_memory_size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal void w32_socket_set_error(W32_Socket *socket, OS_SocketError error);
|
||||
internal void w32_socket_set_error_wsa(W32_Socket *socket, int wsa_error);
|
||||
internal B32 w32_socket_read_looped(W32_Socket *w32_socket, void *buffer, U32 size);
|
||||
|
||||
#endif // WIN32_SOCKET_H
|
||||
Reference in New Issue
Block a user