gdbasics/scripts/libs/settings.gd

156 lines
3.9 KiB
GDScript

###
### settings management API
###
extends Object
class_name GDBSettings
const __META_STATE = "__gdb_settings_state__"
class __State:
# modification of the libraries behaviour
var settings_file_name := "user://settings.dat"
var disable_default_settings := false
var settings_changed := false
var values := {}
signal setting_changed(name, value)
################
# public stuff #
################
func _init():
assert(0, "This class should not be instantiated.")
static func has_value(name : String) -> bool:
return __get_state().values.has(name)
static func get_value(name : String, def = null, type = TYPE_NIL):
if type == TYPE_NIL && def != null:
type = typeof(def)
var val : Variant = __get_state().values.get(name, def)
if type is Object:
if !val is type:
return def
else:
match type:
TYPE_NIL:
return val
TYPE_STRING:
val = str(val)
TYPE_INT:
if val is String:
val = val.to_int()
else:
val = int(val)
TYPE_FLOAT:
if val is String:
val = val.to_float()
else:
val = float(val)
TYPE_BOOL:
val = bool(val)
_:
if typeof(val) != type:
return def
if val is Array || val is Dictionary:
val = val.duplicate()
return val
static func set_value(name : String, value) -> void:
if __get_state().values.get(name) != value:
__set_value(name, value)
# save next frame (in case multiple values are changed)
__get_state().settings_changed = true
# await GDBUtility.get_scene_tree().process_frame
# TODO: cannot make this a coroutine (bug?!)
if __get_state().settings_changed:
store_to_file()
__get_state().settings_changed = false
static func toggle_value(name : String) -> void:
set_value(name, !__get_state().values.get(name, false))
static func array_add_value(name : String, value) -> void:
var arr = get_value(name, [])
arr.append(value)
set_value(name, arr)
static func array_remove_value(name : String, value) -> void:
var arr = get_value(name, [])
arr.erase(value)
set_value(name, arr)
static func array_has_value(name : String, value) -> bool:
var arr = get_value(name, [])
return arr.has(value)
static func array_toggle_value(name : String, value) -> void:
var arr = get_value(name, [])
if arr.has(value):
arr.erase(value)
else:
arr.append(value)
set_value(name, arr)
static func load_from_file() -> void:
var in_file = File.new()
if not in_file.file_exists(__get_state().settings_file_name):
return # nothing to load
in_file.open(__get_state().settings_file_name, File.READ)
var json := JSON.new()
if json.parse(in_file.get_as_text()) != OK:
printerr("Error parsing settings file, invalid json!")
printerr("at line {}: {}".format([json.get_error_line(), json.get_error_message()]))
return
__load_data(json.get_data())
static func store_to_file() -> void:
var out_file = File.new()
out_file.open(__get_state().settings_file_name, File.WRITE)
out_file.store_line(__save_data())
out_file.close()
static func set_disable_default_settings(disable : bool) -> void:
__get_state().disable_default_settings = disable
static func is_disable_default_settings() -> bool:
return __get_state().disable_default_settings
static func setting_changed() -> Signal:
return __get_state().setting_changed
#################
# private stuff #
#################
static func __save_data():
var json := JSON.new()
return json.stringify(__get_state().values)
static func __load_data(data : Dictionary):
for name in data:
__set_value(name, data[name])
static func __set_value(name : String, value):
__get_state().values[name] = value
__on_setting_changed(name, value)
__get_state().emit_signal("setting_changed", name, value)
static func __on_setting_changed(name : String, value):
if __get_state().disable_default_settings:
return
match name:
"fullscreen":
OS.window_fullscreen = value
"vsync":
OS.vsync_enabled = value
static func __get_state() -> __State:
return GDBUtility.get_state_object(__META_STATE, __State)