power_play/src/settings/settings_core.c
2025-07-30 15:47:14 -05:00

151 lines
5.3 KiB
C

String settings_serialize(Arena *arena, const P_WindowSettings *settings)
{
__prof;
String minimized = settings->flags & P_WindowSettingsFlag_Minimized ? Lit("true") : Lit("false");
String maximized = settings->flags & P_WindowSettingsFlag_Maximized ? Lit("true") : Lit("false");
String fullscreen = settings->flags & P_WindowSettingsFlag_Fullscreen ? Lit("true") : Lit("false");
i32 x = settings->floating_x;
i32 y = settings->floating_y;
i32 width = settings->floating_width;
i32 height = settings->floating_height;
String fmt = Lit(
"{\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"
);
String formatted = StringFormat(arena,
fmt,
FmtString(minimized),
FmtString(maximized),
FmtString(fullscreen),
FmtSint(x),
FmtSint(y),
FmtSint(width),
FmtSint(height));
return formatted;
}
P_WindowSettings *settings_deserialize(Arena *arena, String src, String *error_out)
{
__prof;
TempArena scratch = BeginScratch(arena);
String error = ZI;
JSON_Error json_error = ZI;
P_WindowSettings *settings = PushStruct(arena, P_WindowSettings);
JSON_Result parse_res = json_from_string(scratch.arena, src);
if (parse_res.errors.count > 0) {
json_error = *parse_res.errors.first;
goto abort;
}
JSON_Blob *root = parse_res.root;
if (!root) {
error = Lit("Root object not found.");
goto abort;
}
JSON_Blob *window = root->child_first;
if (!window || window->type != JSON_TYPE_OBJECT || !EqString(window->key, Lit("window"))) {
error = Lit("\"window\" object not found");
goto abort;
}
b32 found_maximized = 0;
b32 found_fullscreen = 0;
b32 found_x = 0;
b32 found_y = 0;
b32 found_width = 0;
b32 found_height = 0;
for (JSON_Blob *child = window->child_first; child; child = child->next) {
String key = child->key;
if (EqString(key, Lit("maximized"))) {
if (child->type != JSON_TYPE_BOOL) {
error = Lit("Expected boolean for \"maximized\"");
goto abort;
}
if (child->value.boolean) {
settings->flags |= P_WindowSettingsFlag_Maximized;
}
found_maximized = 1;
} else if (EqString(key, Lit("fullscreen"))) {
if (child->type != JSON_TYPE_BOOL) {
error = Lit("Expected boolean for \"fulscreen\"");
goto abort;
}
if (child->value.boolean) {
settings->flags |= P_WindowSettingsFlag_Fullscreen;
}
found_fullscreen = 1;
} else if (EqString(key, Lit("x"))) {
if (child->type != JSON_TYPE_NUMBER) {
error = Lit("Expected number for \"x\"");
goto abort;
}
settings->floating_x = RoundF32ToI32(child->value.number);
found_x = 1;
} else if (EqString(key, Lit("y"))) {
if (child->type != JSON_TYPE_NUMBER) {
error = Lit("Expected number for \"y\"");
goto abort;
}
settings->floating_y = RoundF32ToI32(child->value.number);
found_y = 1;
} else if (EqString(key, Lit("width"))) {
if (child->type != JSON_TYPE_NUMBER) {
error = Lit("Expected number for \"width\"");
goto abort;
}
settings->floating_width = RoundF32ToI32(child->value.number);
found_width = 1;
} else if (EqString(key, Lit("height"))) {
if (child->type != JSON_TYPE_NUMBER) {
error = Lit("Expected number for \"height\"");
goto abort;
}
settings->floating_height = RoundF32ToI32(child->value.number);
found_height = 1;
}
}
if (!found_maximized) { error = Lit("Missing \"maximized\""); goto abort; }
if (!found_fullscreen) { error = Lit("Missing \"fullscreen\""); goto abort; }
if (!found_x) { error = Lit("Missing \"x\""); goto abort; }
if (!found_y) { error = Lit("Missing \"y\""); goto abort; }
if (!found_width) { error = Lit("Missing \"width\""); goto abort; }
if (!found_height) { error = Lit("Missing \"height\""); goto abort; }
abort:
if (error_out && (error.len > 0 || json_error.msg.len > 0)) {
if (json_error.msg.len > 0) {
*error_out = StringFormat(arena,
Lit("%F\n(%F:%F)"),
FmtString(json_error.msg),
FmtUint(json_error.start),
FmtUint(json_error.end));
} else {
*error_out = CopyString(arena, error);
}
}
EndScratch(scratch);
return settings;
}