update settings manager

This commit is contained in:
Crispy 2021-05-23 21:14:34 +02:00
parent e5bd68d0ec
commit ba65c823f1
4 changed files with 154 additions and 53 deletions

View file

@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/settings-manager/settings.gd" type="Script" id=1]
[node name="Settings" type="Node"]
script = ExtResource( 1 )
[node name="AutosaveTimer" type="Timer" parent="."]
wait_time = 300.0
autostart = true
[connection signal="timeout" from="AutosaveTimer" to="." method="_on_AutosaveTimer_timeout"]

View file

@ -1,10 +1,10 @@
extends Node extends Node
signal setting_changed # emitted with name, value signal settings_saved
signal settings_loaded # emitted when settings are loaded from file, needs to be connected in _init() signal settings_loaded # emitted when settings are loaded from file, needs to be connected in _init()
const DEBUG_SETTINGS = false var DEBUG_SETTINGS = true
const SETTINGS_PATH = "user://settings.json" var SETTINGS_PATH = "user://settings.json"
const SETTINGS_DEF = { const SETTINGS_DEF = {
"example_1": { "example_1": {
"name": "Example Toggle", "name": "Example Toggle",
@ -16,66 +16,130 @@ const SETTINGS_DEF = {
"example_2": { "example_2": {
"name": "Example Number", "name": "Example Number",
"type": "number", "type": "number",
"default": 42, "default": 42
"min": 1, # optional
"max": 100, # optional
"step": 4 # optional
}, },
"example_3": { "example_3": {
"name": "Example section",
"type": "dict",
"definition": {
"example_4": {
"name": "Example text", "name": "Example text",
"type": "string", "type": "string",
"default": "hello world" "default": "hello world"
}, },
"example_4": { "example_5": {
"name": "Example Vector3", "name": "Example Vector3",
"type": "Vector3", "type": "vector3",
"default": [1, 2, 3] "default": Vector3(1,2,3)
},
"example_6": {
"name": "Example Quat",
"type": "quat",
"default": Quat()
} }
}
},
"example_7": {
"name": "Example array",
"type": "array",
"default": [1,23,4]
},
"example_8": {
"name": "Example dict with varying size containing arrays",
"type": "dict",
"flags": ["resize"],
"definition": {
"type": "array",
"default": [99,45,1]
}
},
"example_9": {
"name": "Example dict with varying size containing more dicts",
"type": "dict",
"flags": ["resize"],
"definition": {
"type": "dict",
"definition": {
"property1": {
"name": "Property 1",
"type": "number",
"default": 123
},
"property2": {
"name": "Property 2",
"type": "number",
"default": 345
},
}
}
},
} }
var _settings = {} var s: Dictionary = {}
func _ready() -> void: func _ready() -> void:
_init_settings() _init_settings()
load_settings() load_settings()
emit_signal("settings_loaded")
save_settings() save_settings()
func get_setting(key): func _init_settings() -> void:
return _settings[key]
func set_setting(key, val):
if _settings[key] == val:
return
_settings[key] = val
emit_signal("setting_changed", key, val)
save_settings()
if DEBUG_SETTINGS:
print("Settings changed: ", key, " -> ", val)
func _init_settings():
for key in SETTINGS_DEF: for key in SETTINGS_DEF:
_settings[key] = SETTINGS_DEF[key].default s[key] = _init_sub_setting(SETTINGS_DEF[key])
if DEBUG_SETTINGS: if DEBUG_SETTINGS:
print("Default settings: ", _settings) print("Default settings: ", s)
func _init_sub_setting(def):
match def.type:
"dict":
if has_flag(def, "resize"):
return {}
var _s = {}
for key in def.definition:
_s[key] = _init_sub_setting(def.definition[key])
return _s
_:
return def.default
func save_settings(): func save_settings():
var to_save = {} var to_save = {}
for key in _settings: for key in s:
if not (SETTINGS_DEF[key].has("flags") and "no_save" in SETTINGS_DEF[key].flags): var val = _save_sub_setting(s[key], SETTINGS_DEF[key])
to_save[key] = _settings[key] if val != null:
to_save[key] = val
var file = File.new() var file = File.new()
file.open(SETTINGS_PATH, File.WRITE) file.open(SETTINGS_PATH, File.WRITE)
file.store_line(to_json(to_save)) file.store_line(to_json(to_save))
file.close() file.close()
emit_signal("settings_saved")
func _save_sub_setting(val, def):
if has_flag(def, "no_save"):
return null
match def.type:
"vector2":
return [val.x, val.y]
"vector3":
return [val.x, val.y, val.z]
"quat":
return [val.x, val.y, val.z, val.w]
"dict":
var resize = has_flag(def, "resize")
var _s = {}
for key in val:
var subdef = def.definition if resize else def.definition[key]
var v = _save_sub_setting(val[key], subdef)
if v != null:
_s[key] = v
return _s
_:
return val
func load_settings() -> void: func load_settings() -> void:
@ -90,18 +154,43 @@ func load_settings() -> void:
var new_settings = parse_json(file.get_as_text()) var new_settings = parse_json(file.get_as_text())
file.close() file.close()
# in case the settings format has changed, this is better than just clonging blindly
for key in new_settings: for key in new_settings:
if _settings.has(key): s[key] = _load_sub_setting(new_settings[key], SETTINGS_DEF[key])
var value = new_settings[key]
match SETTINGS_DEF[key].type:
["Vector2", "vector2"]:
_settings[key] = Vector2(value[0], value[1])
["Vector3", "vector3"]:
_settings[key] = Vector3(value[0], value[1], value[2])
_:
_settings[key] = value
emit_signal("settings_loaded")
if DEBUG_SETTINGS: if DEBUG_SETTINGS:
print("Loaded settings from file") print("Loaded settings from file")
print(_settings) print(s)
func _load_sub_setting(val, def):
match def.type:
"vector2":
return Vector2(val[0], val[1])
"vector3":
return Vector3(val[0], val[1], val[2])
"quat":
return Quat(val[0], val[1], val[2], val[3])
"dict":
var _s = {}
var resize = has_flag(def, "resize")
for key in val:
var subdef = def.definition if resize else def.definition[key]
_s[key] = _load_sub_setting(val[key], subdef)
return _s
_:
return val
func has_flag(def, flag):
return def.has("flags") and flag in def.flags
func _exit_tree() -> void:
# save on quit
save_settings()
func _on_AutosaveTimer_timeout() -> void:
# auto saves every 5 minutes, saving should also be done manually
save_settings()

View file

@ -3,7 +3,7 @@ extends EditorPlugin
func _enter_tree() -> void: func _enter_tree() -> void:
add_autoload_singleton("Settings", "res://addons/settings-manager/settings.gd") add_autoload_singleton("Settings", "res://addons/settings-manager/Settings.tscn")
func _exit_tree() -> void: func _exit_tree() -> void:

View file

@ -19,11 +19,11 @@ config/icon="res://icon.png"
[autoload] [autoload]
OverlayInit="*res://addons/openvr_overlay/overlay_init.gd" OverlayInit="*res://addons/openvr_overlay/overlay_init.gd"
Settings="*res://addons/settings-manager/settings.gd" Settings="*res://addons/settings-manager/Settings.tscn"
[editor_plugins] [editor_plugins]
enabled=PoolStringArray( "res://addons/openvr_overlay/plugin.cfg", "res://addons/settings-manager/plugin.cfg" ) enabled=PoolStringArray( "res://addons/godot-openvr/plugin.cfg", "res://addons/openvr_overlay/plugin.cfg", "res://addons/settings-manager/plugin.cfg" )
[gdnative] [gdnative]