158 lines
5.7 KiB
C
158 lines
5.7 KiB
C
#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;
|
|
}
|