#include "settings.h" #include "json.h" #include "string.h" #include "arena.h" #include "scratch.h" #include "math.h" struct buffer settings_serialize(struct arena *arena, const struct sys_window_settings *settings) { __prof; struct string minimized = settings->flags & SYS_WINDOW_SETTINGS_FLAG_MINIMIZED ? STR("true") : STR("false"); struct string maximized = settings->flags & SYS_WINDOW_SETTINGS_FLAG_MAXIMIZED ? STR("true") : STR("false"); struct string fullscreen = settings->flags & SYS_WINDOW_SETTINGS_FLAG_FULLSCREEN ? STR("true") : STR("false"); i32 x = settings->floating_x; i32 y = settings->floating_y; i32 width = settings->floating_width; i32 height = settings->floating_height; struct string fmt = STR( "{\n" " \"window\": {\n" " \"minimized\": %F,\n" " \"maximized\": %F,\n" " \"fullscreen\": %F,\n" " \"x\": %F,\n" " \"y\": %F,\n" " \"width\": %F,\n" " \"height\": %F\n" " }\n" "}\n" ); struct string formatted = string_format(arena, fmt, FMT_STR(minimized), FMT_STR(maximized), FMT_STR(fullscreen), FMT_SINT(x), FMT_SINT(y), FMT_SINT(width), FMT_SINT(height)); return BUFFER_FROM_STRING(formatted); } struct sys_window_settings *settings_deserialize(struct arena *arena, struct buffer src, struct string *error_out) { __prof; struct temp_arena scratch = scratch_begin(arena); struct string error = { 0 }; struct json_error json_error = { 0 }; struct sys_window_settings *settings = arena_push_zero(arena, struct sys_window_settings); struct json_parse_result parse_res = json_from_string(scratch.arena, STRING_FROM_BUFFER(src)); if (parse_res.errors.count > 0) { json_error = *parse_res.errors.first; goto abort; } struct json *root = parse_res.root; if (!root) { error = STR("Root object not found."); goto abort; } struct json *window = root->child_first; if (!window || window->type != JSON_TYPE_OBJECT || !string_eq(window->key, STR("window"))) { error = STR("\"window\" object not found"); goto abort; } b32 found_maximized = false; b32 found_fullscreen = false; b32 found_x = false; b32 found_y = false; b32 found_width = false; b32 found_height = false; for (struct json *child = window->child_first; child; child = child->next) { struct string key = child->key; if (string_eq(key, STR("maximized"))) { if (child->type != JSON_TYPE_BOOL) { error = STR("Expected boolean for \"maximized\""); goto abort; } if (child->value.boolean) { settings->flags |= SYS_WINDOW_SETTINGS_FLAG_MAXIMIZED; } found_maximized = true; } else if (string_eq(key, STR("fullscreen"))) { if (child->type != JSON_TYPE_BOOL) { error = STR("Expected boolean for \"fulscreen\""); goto abort; } if (child->value.boolean) { settings->flags |= SYS_WINDOW_SETTINGS_FLAG_FULLSCREEN; } found_fullscreen = true; } else if (string_eq(key, STR("x"))) { if (child->type != JSON_TYPE_NUMBER) { error = STR("Expected number for \"x\""); goto abort; } settings->floating_x = math_round_to_int(child->value.number); found_x = true; } else if (string_eq(key, STR("y"))) { if (child->type != JSON_TYPE_NUMBER) { error = STR("Expected number for \"y\""); goto abort; } settings->floating_y = math_round_to_int(child->value.number); found_y = true; } else if (string_eq(key, STR("width"))) { if (child->type != JSON_TYPE_NUMBER) { error = STR("Expected number for \"width\""); goto abort; } settings->floating_width = math_round_to_int(child->value.number); found_width = true; } else if (string_eq(key, STR("height"))) { if (child->type != JSON_TYPE_NUMBER) { error = STR("Expected number for \"height\""); goto abort; } settings->floating_height = math_round_to_int(child->value.number); found_height = true; } } if (!found_maximized) { error = STR("Missing \"maximized\""); goto abort; } if (!found_fullscreen) { error = STR("Missing \"fullscreen\""); goto abort; } if (!found_x) { error = STR("Missing \"x\""); goto abort; } if (!found_y) { error = STR("Missing \"y\""); goto abort; } if (!found_width) { error = STR("Missing \"width\""); goto abort; } if (!found_height) { error = STR("Missing \"height\""); goto abort; } abort: if (error_out && (error.len > 0 || json_error.msg.len > 0)) { if (json_error.msg.len > 0) { *error_out = string_format(arena, STR("%F\n(%F:%F)"), FMT_STR(json_error.msg), FMT_UINT(json_error.start), FMT_UINT(json_error.end)); } else { *error_out = string_copy(arena, error); } } scratch_end(scratch); return settings; }