power_play/src/sys.h

538 lines
13 KiB
C

#ifndef SYS_H
#define SYS_H
struct snc_counter;
/* ========================== *
* Wait
* ========================== */
/* Futex-like wait & wake */
void sys_wait(volatile void *addr, void *cmp, u32 size, i64 timeout_ns);
void sys_wake(void *addr, i32 count);
/* ========================== *
* Fiber
* ========================== */
#define SYS_MAX_FIBERS 4096
i16 sys_current_fiber_id(void);
/* ========================== *
* Job
* ========================== */
/* Work pools contain their own worker threads with their own thread priority/affinity based on the intended context of the pool. */
enum sys_pool {
SYS_POOL_INHERIT = -1,
/* The floating pool contains a large number of lower priority threads that have affinity over the entire CPU.
* Other pools should push jobs that only block and do no work here so that they can yield on the blocking job rather than blocking themselves. */
SYS_POOL_FLOATING = 0,
SYS_POOL_BACKGROUND = 1,
SYS_POOL_AUDIO = 2,
SYS_POOL_USER = 3,
SYS_POOL_SIM = 4,
NUM_SYS_POOLS
};
/* Job execution order within a pool is based on priority. */
enum sys_priority {
SYS_PRIORITY_INHERIT = -1,
SYS_PRIORITY_HIGH = 0,
SYS_PRIORITY_NORMAL = 1,
SYS_PRIORITY_LOW = 2,
NUM_SYS_PRIORITIES
};
struct sys_job_data {
i32 id;
void *sig;
};
#define SYS_JOB_DEF(job_name, arg_name) void job_name(struct sys_job_data arg_name)
typedef SYS_JOB_DEF(sys_job_func, job_data);
void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind, enum sys_priority priority, struct snc_counter *counter);
/* ========================== *
* Scratch context
* ========================== */
#define SYS_SCRATCH_ARENAS_PER_CTX 2
struct sys_scratch_ctx {
struct arena *arenas[SYS_SCRATCH_ARENAS_PER_CTX];
};
struct sys_scratch_ctx *sys_scratch_ctx_from_fiber_id(i16 fiber_id);
/* ========================== *
* Memory
* ========================== */
/* Reserve a continuous block of virtual address space. Shouldn't be
* read / written to until memory is committed.
* NOTE: Guaranteed to be 16 byte aligned. */
void *sys_memory_reserve(u64 size);
/* Release a continuous block of virtual address space. Before releasing,
* decommit any committed memory within the reserved space to be safe. */
void sys_memory_release(void *address);
/* Commit a region of reserved address space to make it readable / writable */
void *sys_memory_commit(void *address, u64 size);
/* Decommit a region of committed memory (does not release the reserved
* address space) */
void sys_memory_decommit(void *address, u64 size);
/* Mark committed pages as readonly */
void sys_memory_set_committed_readonly(void *address, u64 size);
/* Mark committed pages as readable & writeable (default for committed memory) */
void sys_memory_set_committed_readwrite(void *address, u64 size);
/* ========================== *
* Time
* ========================== */
struct sys_datetime {
u32 year;
u32 month;
u32 day_of_week;
u32 day;
u32 hour;
u32 minute;
u32 second;
u32 milliseconds;
};
struct sys_datetime sys_local_time(void);
i64 sys_time_ns(void);
/* ========================== *
* File system
*
* NOTE: File paths use forward slash '/' as delimiter
* ========================== */
struct sys_file {
u64 handle;
b32 valid;
};
struct sys_file_time {
struct sys_datetime created;
struct sys_datetime accessed;
struct sys_datetime modified;
};
struct string sys_get_write_path(struct arena *arena);
b32 sys_is_file(struct string path);
b32 sys_is_dir(struct string path);
void sys_mkdir(struct string path);
struct sys_file sys_file_open_read(struct string path);
struct sys_file sys_file_open_read_wait(struct string path); /* Waits until file is not being used by another program */
struct sys_file sys_file_open_write(struct string path);
struct sys_file sys_file_open_append(struct string path);
void sys_file_close(struct sys_file file);
struct string sys_file_read_all(struct arena *arena, struct sys_file file);
void sys_file_write(struct sys_file file, struct string data);
u64 sys_file_get_size(struct sys_file file);
struct sys_file_time sys_file_get_time(struct sys_file file);
/* ========================== *
* File map
* ========================== */
struct sys_file_map {
struct string mapped_memory;
u64 handle;
b32 valid;
};
struct sys_file_map sys_file_map_open_read(struct sys_file file);
void sys_file_map_close(struct sys_file_map map);
struct string sys_file_map_data(struct sys_file_map map);
/* ========================== *
* Dir iter
* ========================== */
struct sys_file_filter_result {
struct string filename;
b32 is_dir;
};
struct sys_file_filter {
struct sys_file_filter_result info;
u64 handle;
};
/* Iterate all files in a directory */
struct sys_file_filter sys_file_filter_begin(struct arena *arena, struct string pattern);
b32 sys_file_filter_next(struct arena *arena, struct sys_file_filter *iter);
void sys_file_filter_end(struct sys_file_filter *iter);
/* ========================== *
* Watch
* ========================== */
enum sys_watch_info_kind {
SYS_WATCH_INFO_KIND_UNKNOWN,
SYS_WATCH_INFO_KIND_ADDED,
SYS_WATCH_INFO_KIND_REMOVED,
SYS_WATCH_INFO_KIND_MODIFIED,
SYS_WATCH_INFO_KIND_RENAMED_OLD,
SYS_WATCH_INFO_KIND_RENAMED_NEW
};
struct sys_watch_info {
enum sys_watch_info_kind kind;
struct string name;
struct sys_watch_info *next;
struct sys_watch_info *prev;
};
struct sys_watch_info_list {
struct sys_watch_info *first;
struct sys_watch_info *last;
u64 count;
};
struct sys_watch *sys_watch_alloc(struct string path);
void sys_watch_release(struct sys_watch *dw);
struct sys_watch_info_list sys_watch_read_wait(struct arena *arena, struct sys_watch *dw);
void sys_watch_wake(struct sys_watch *dw);
/* ========================== *
* Window
* ========================== */
enum sys_btn {
SYS_BTN_NONE,
SYS_BTN_M1,
SYS_BTN_M2,
SYS_BTN_M3,
SYS_BTN_M4,
SYS_BTN_M5,
SYS_BTN_MWHEELUP,
SYS_BTN_MWHEELDOWN,
SYS_BTN_ESC,
SYS_BTN_F1,
SYS_BTN_F2,
SYS_BTN_F3,
SYS_BTN_F4,
SYS_BTN_F5,
SYS_BTN_F6,
SYS_BTN_F7,
SYS_BTN_F8,
SYS_BTN_F9,
SYS_BTN_F10,
SYS_BTN_F11,
SYS_BTN_F12,
SYS_BTN_F13,
SYS_BTN_F14,
SYS_BTN_F15,
SYS_BTN_F16,
SYS_BTN_F17,
SYS_BTN_F18,
SYS_BTN_F19,
SYS_BTN_F20,
SYS_BTN_F21,
SYS_BTN_F22,
SYS_BTN_F23,
SYS_BTN_F24,
SYS_BTN_GRAVE_ACCENT,
SYS_BTN_0,
SYS_BTN_1,
SYS_BTN_2,
SYS_BTN_3,
SYS_BTN_4,
SYS_BTN_5,
SYS_BTN_6,
SYS_BTN_7,
SYS_BTN_8,
SYS_BTN_9,
SYS_BTN_MINUS,
SYS_BTN_EQUAL,
SYS_BTN_BACKSPACE,
SYS_BTN_DELETE,
SYS_BTN_TAB,
SYS_BTN_A,
SYS_BTN_B,
SYS_BTN_C,
SYS_BTN_D,
SYS_BTN_E,
SYS_BTN_F,
SYS_BTN_G,
SYS_BTN_H,
SYS_BTN_I,
SYS_BTN_J,
SYS_BTN_K,
SYS_BTN_L,
SYS_BTN_M,
SYS_BTN_N,
SYS_BTN_O,
SYS_BTN_P,
SYS_BTN_Q,
SYS_BTN_R,
SYS_BTN_S,
SYS_BTN_T,
SYS_BTN_U,
SYS_BTN_V,
SYS_BTN_W,
SYS_BTN_X,
SYS_BTN_Y,
SYS_BTN_Z,
SYS_BTN_SPACE,
SYS_BTN_ENTER,
SYS_BTN_CTRL,
SYS_BTN_SHIFT,
SYS_BTN_ALT,
SYS_BTN_UP,
SYS_BTN_LEFT,
SYS_BTN_DOWN,
SYS_BTN_RIGHT,
SYS_BTN_PAGE_UP,
SYS_BTN_PAGE_DOWN,
SYS_BTN_HOME,
SYS_BTN_END,
SYS_BTN_FORWARD_SLASH,
SYS_BTN_PERIOD,
SYS_BTN_COMMA,
SYS_BTN_QUOTE,
SYS_BTN_LEFT_BRACKET,
SYS_BTN_RIGHT_BRACKET,
SYS_BTN_INSERT,
SYS_BTN_SEMICOLON,
SYS_BTN_COUNT
};
enum sys_window_event_kind {
SYS_EVENT_KIND_NONE,
SYS_EVENT_KIND_BUTTON_DOWN,
SYS_EVENT_KIND_BUTTON_UP,
SYS_EVENT_KIND_CURSOR_MOVE,
SYS_EVENT_KIND_MOUSE_MOVE,
SYS_EVENT_KIND_TEXT,
SYS_EVENT_KIND_QUIT,
SYS_EVENT_KIND_COUNT
};
struct sys_window_event {
enum sys_window_event_kind kind;
/* SYS_EVENT_KIND_BUTTON_DOWN */
/* SYS_EVENT_KIND_BUTTON_UP */
enum sys_btn button;
b32 is_repeat;
/* SYS_EVENT_KIND_TEXT */
u32 text_codepoint;
/* SYS_EVENT_KIND_CURSOR_MOVE */
struct v2 cursor_position;
/* SYS_EVENT_KIND_MOUSE_MOVE */
struct v2 mouse_delta;
};
struct sys_window_event_array {
u64 count;
struct sys_window_event *events;
};
/* NOTE:
* A window object can only be interacted with by the thread that created it.
* This restriction is in place because of how Win32 works, IE you cannot
* create a Win32 window in one thread and process its messages on another. */
enum sys_window_settings_flags {
SYS_WINDOW_SETTINGS_FLAG_NONE = 0x00,
SYS_WINDOW_SETTINGS_FLAG_FULLSCREEN = 0x01,
/* NOTE: Both maximized and minimized can be true at the same time. This
* means that the window was minimized from a maximized state, and will
* restore to being maximized once it's un-minimized. */
SYS_WINDOW_SETTINGS_FLAG_MAXIMIZED = 0x02,
SYS_WINDOW_SETTINGS_FLAG_MINIMIZED = 0x04
};
enum sys_window_flags {
SYS_WINDOW_FLAG_NONE = 0x00,
SYS_WINDOW_FLAG_SHOWING = 0x02
};
/* sys_window_update_settings should be used when altering settings values */
struct sys_window_settings {
char title[256];
u32 flags;
/* NOTE: Below fields are NOT representative of actual window dimensions.
* These values represent the window dimensions when the window is not
* maximized, minimized, or fullscreen. AKA 'floating'. Use
* `sys_window_get_size` for rendering instead. */
i32 floating_x;
i32 floating_y;
i32 floating_width;
i32 floating_height;
};
struct sys_window *sys_window_alloc(void);
void sys_window_release(struct sys_window *sys_window);
struct sys_window_event_array sys_window_pop_events(struct arena *arena, struct sys_window *sys_window);
void sys_window_update_settings(struct sys_window *sys_window, struct sys_window_settings *settings);
struct sys_window_settings sys_window_get_settings(struct sys_window *sys_window);
void sys_window_show(struct sys_window *sys_window);
struct v2 sys_window_get_size(struct sys_window *sys_window);
struct v2 sys_window_get_monitor_size(struct sys_window *sys_window);
/* Returns a platform specific representation of the window. E.g. `hwnd` on win32. */
u64 sys_window_get_internal_handle(struct sys_window *sys_window);
void sys_window_cursor_set_pos(struct sys_window *sys_window, struct v2 pos);
void sys_window_cursor_show(struct sys_window *sys_window);
void sys_window_cursor_hide(struct sys_window *sys_window);
void sys_window_cursor_enable_clip(struct sys_window *sys_window, struct rect bounds);
void sys_window_cursor_disable_clip(struct sys_window *sys_window);
void sys_window_toggle_topmost(struct sys_window *sys_window);
/* ========================== *
* Address
* ========================== */
enum sys_address_family {
SYS_ADDRESS_FAMILY_IPV4,
SYS_ADDRESS_FAMILY_IPV6
};
struct sys_address {
b32 valid;
enum sys_address_family family;
/* NOTE: ipnb & portnb are stored in network byte order */
u8 ipnb[16];
u16 portnb;
};
struct sys_address sys_address_from_string(struct string str);
struct sys_address sys_address_from_port(u16 port);
struct string sys_string_from_address(struct arena *arena, struct sys_address address);
b32 sys_address_eq(struct sys_address a, struct sys_address b);
/* ========================== *
* Sock
* ========================== */
struct sys_sock_read_result {
b32 valid; /* Since data.len = 0 can be valid */
struct sys_address address;
struct string data;
};
struct sys_sock *sys_sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size);
void sys_sock_release(struct sys_sock *sock);
struct sys_sock_read_result sys_sock_read(struct arena *arena, struct sys_sock *sock);
void sys_sock_write(struct sys_sock *sock, struct sys_address address, struct string data);
/* ========================== *
* Util
* ========================== */
enum sys_message_box_kind {
SYS_MESSAGE_BOX_KIND_OK,
SYS_MESSAGE_BOX_KIND_WARNING,
SYS_MESSAGE_BOX_KIND_ERROR,
SYS_MESSAGE_BOX_KIND_FATAL
};
void sys_message_box(enum sys_message_box_kind kind, struct string message);
void sys_set_clipboard_text(struct string str);
struct string sys_get_clipboard_text(struct arena *arena);
void sys_true_rand(struct string b);
u32 sys_num_logical_processors(void);
u32 sys_current_thread_id(void);
i64 sys_current_scheduler_period_ns(void);
/* ========================== *
* Exit
* ========================== */
#define SYS_EXIT_FUNC(name) void name(void)
typedef SYS_EXIT_FUNC(sys_exit_func);
/* Registers a function to be called during graceful shutdown (in reverse order) */
void sys_on_exit(sys_exit_func *func);
/* Signals the program to shut down gracefully and run exit callbacks */
void sys_exit(void);
/* Forcefully exits the program and displays `msg` to the user */
void sys_panic(struct string msg);
/* ========================== *
* App entry point
* ========================== */
/* Must be defined by app */
void sys_app_startup(struct string args_str);
#endif