//////////////////////////////////////////////////////////// //~ Serialize String SETTINGS_StringFromWindowSettings(Arena *arena, const P_WindowSettings *settings) { 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 = FormatString( , fmt, FmtString(minimized), FmtString(maximized), FmtString(fullscreen), FmtSint(x), FmtSint(y), FmtSint(width), FmtSint(height) ); return formatted; } //////////////////////////////////////////////////////////// //~ Deserialize P_WindowSettings *SETTINGS_WindowSettingsFromString(Arena *arena, String src, String *error_out) { TempArena scratch = BeginScratch(arena); String error = ZI; JSON_Error json_error = ZI; P_WindowSettings *settings = PushStruct(arena, P_WindowSettings); JSON_Result parse_result = JSON_BlobFromString(scratch.arena, src); if (parse_result.errors.count > 0) { json_error = *parse_result.errors.first; goto abort; } JSON_Blob *root = parse_result.root; if (!root) { error = Lit("Root object not found."); goto abort; } JSON_Blob *window = root->child_first; if (!window || window->type != JSON_Type_Object || !MatchString(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 (MatchString(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 (MatchString(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 (MatchString(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 (MatchString(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 (MatchString(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 (MatchString(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 = StringF( arena, Lit("%F\n(%F:%F)"), FmtString(json_error.msg), FmtUint(json_error.start), FmtUint(json_error.end) ); } else { *error_out = PushString(arena, error); } } EndScratch(scratch); return settings; }