extends Reference class_name Settings const SETTINGS_FILE_PATH := "user://settings.json" const SETTINGS_FILE_VERSION := "SETTINGS_V1" var settings : Dictionary var defer_save := false func _init(): load_settings() func set_value(name: String, value) -> void: settings[name] = value if defer_save == false: save_settings() func get_value(name: String, default = null): if settings.has(name) == false: printerr("Setting '%s' not found." % name) return settings.get(name, default) func remove_value(name: String) -> void: settings.erase(name) if defer_save == false: save_settings() func save_settings(file_path: String = SETTINGS_FILE_PATH): match file_path.get_extension(): "json": export_json(file_path, settings) _: printerr("Invalid settings file extension '%s', expected 'json'." % file_path.get_file()) return static func export_json(file_path: String, data: Dictionary): var settings_file := { "version": SETTINGS_FILE_VERSION, "settings": data, } var indentation_char := "" if file_path == SETTINGS_FILE_PATH else "\t" var file_content := JSON.print(settings_file, indentation_char) var file := File.new() file.open(file_path, File.WRITE) file.store_string(file_content) file.close() func load_settings(file_path: String = SETTINGS_FILE_PATH): match file_path.get_extension(): "json": settings = import_json(file_path) _: printerr("Invalid settings file extension '%s', expected 'json'." % file_path.get_file()) return static func import_json(file_path: String) -> Dictionary: var result := {} var file := File.new() var error := file.open(file_path, File.READ_WRITE) if error != OK: printerr("Failed to open settings file '%s' (error %d)." % [file_path, error]) return result var file_content = file.get_as_text() file.close() var parse_result = JSON.parse(file_content) # @DAM All these import/export json functions in database/state/settings could maybe be abstracted!? # if parse_result.error != OK: # printerr("Failed to parse settings file '%s' (error %d)." % [file_path, parse_result.error]) # elif typeof(parse_result.result) != TYPE_DICTIONARY: # printerr("Invalid settings file type '%s', expected '%s'." % [typeof(parse_result.result), TYPE_DICTIONARY]) # elif parse_result.result["version"] != SETTINGS_FILE_VERSION: # printerr("Invalid settings file version '%s', expected '%s'." % [parse_result.result["version"], SETTINGS_FILE_VERSION]) # elif typeof(parse_result.result["settings"]) != TYPE_ARRAY: # printerr("Invalid settings content type '%s', expected '%s'." % [typeof(parse_result.result["settings"]), TYPE_DICTIONARY]) # else: # result = parse_result.result["settings"] # WIP WIP WIP # Decide on how to print errors. # Maybe use error checking as defined above. # Maybe create parameterized functions to import/export JSON files. if parse_result.error != OK: printerr("Failed to parse settings file '%s' (error %d)." % [file_path, parse_result.error]) return result if typeof(parse_result.result) != TYPE_DICTIONARY: print_stack() # @DAM Decide on how to print errors ... once and for all! printerr("Invalid settings file type '%s', expected '%s'." % [typeof(parse_result.result), TYPE_DICTIONARY]) return result if parse_result.result["version"] != SETTINGS_FILE_VERSION: printerr("Invalid settings file version '%s', expected '%s'." % [parse_result.result["version"], SETTINGS_FILE_VERSION]) return result if typeof(parse_result.result["settings"]) != TYPE_DICTIONARY: printerr("Invalid settings content type '%s', expected '%s'." % [typeof(parse_result.result["settings"]), TYPE_DICTIONARY]) return result result = parse_result.result["settings"] return result