refactor: JSON → INI config via Godot ConfigFile
This commit is contained in:
parent
c6bc1edda4
commit
a6d4c290d3
4 changed files with 64 additions and 43 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -16,7 +16,7 @@ godot_temp_*
|
|||
*~
|
||||
|
||||
# Config — user overrides, not committed
|
||||
config/config.json
|
||||
config/config.cfg
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
|
|
|
|||
|
|
@ -10,10 +10,12 @@ func _ready() -> void:
|
|||
_load_config()
|
||||
|
||||
|
||||
## Read a flat setting by key (e.g. "background_color", "show_cpu").
|
||||
func get_setting(key: String, default_value: Variant = null) -> Variant:
|
||||
return _settings.get(key, default_value)
|
||||
|
||||
|
||||
## Persist a setting and emit the change signal.
|
||||
func set_setting(key: String, value: Variant) -> void:
|
||||
if _settings.has(key) and _settings[key] != value:
|
||||
_settings[key] = value
|
||||
|
|
@ -21,7 +23,7 @@ func set_setting(key: String, value: Variant) -> void:
|
|||
config_changed.emit(key, value)
|
||||
|
||||
|
||||
## Parse a "r, g, b" string from config into a Color with alpha 1.0.
|
||||
## Parse a "r, g, b" string setting into a Color (alpha = 1.0).
|
||||
func get_color(key: String, default_color: Color = Color.WHITE) -> Color:
|
||||
var raw: Variant = _settings.get(key)
|
||||
if raw == null or typeof(raw) != TYPE_STRING:
|
||||
|
|
@ -35,45 +37,59 @@ func get_color(key: String, default_color: Color = Color.WHITE) -> Color:
|
|||
return Color(r, g, b, 1.0)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# INI loading via Godot's ConfigFile
|
||||
# Keys are flattened as "{section}_{key}" for simple lookup.
|
||||
# User config.cfg overrides default.cfg on a per-key basis.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
func _load_config() -> void:
|
||||
# Load defaults, then overlay user config.
|
||||
var defaults := _read_json_file("res://config/default.json")
|
||||
var user := _read_json_file("res://config/config.json")
|
||||
|
||||
_settings.clear()
|
||||
if defaults != null and defaults is Dictionary:
|
||||
_merge_dict(_settings, defaults as Dictionary)
|
||||
if user != null and user is Dictionary:
|
||||
_merge_dict(_settings, user as Dictionary)
|
||||
_load_cfg("res://config/default.cfg")
|
||||
_load_cfg("res://config/config.cfg") # silently ignored if absent
|
||||
|
||||
|
||||
static func _read_json_file(path: String) -> Variant:
|
||||
var file := FileAccess.open(path, FileAccess.READ)
|
||||
if file == null:
|
||||
return null
|
||||
var content: String = file.get_as_text()
|
||||
var parsed: Variant = JSON.parse_string(content)
|
||||
return parsed
|
||||
|
||||
|
||||
static func _merge_dict(dst: Dictionary, src: Dictionary) -> void:
|
||||
for key in src:
|
||||
dst[key] = src[key]
|
||||
func _load_cfg(path: String) -> void:
|
||||
var cfg := ConfigFile.new()
|
||||
if cfg.load(path) != OK:
|
||||
return
|
||||
for section in cfg.get_sections():
|
||||
for key in cfg.get_section_keys(section):
|
||||
_settings[section + "_" + key] = cfg.get_value(section, key)
|
||||
|
||||
|
||||
func _save_user_config() -> void:
|
||||
# Only persists settings that differ from defaults.
|
||||
var defaults := _read_json_file("res://config/default.json")
|
||||
if not (defaults is Dictionary):
|
||||
# Load defaults to compare against.
|
||||
var defaults := ConfigFile.new()
|
||||
if defaults.load("res://config/default.cfg") != OK:
|
||||
return
|
||||
|
||||
var diff: Dictionary = {}
|
||||
for key in _settings:
|
||||
if not defaults.has(key) or defaults[key] != _settings[key]:
|
||||
diff[key] = _settings[key]
|
||||
# Collect default keys for reference.
|
||||
var default_keys: Dictionary = {}
|
||||
for section in defaults.get_sections():
|
||||
for key in defaults.get_section_keys(section):
|
||||
default_keys[section + "_" + key] = { "section": section, "key": key }
|
||||
|
||||
var path: String = "res://config/config.json"
|
||||
var json_str: String = JSON.stringify(diff, "\t")
|
||||
var file := FileAccess.open(path, FileAccess.WRITE)
|
||||
if file != null:
|
||||
file.store_string(json_str)
|
||||
var user_cfg := ConfigFile.new()
|
||||
var has_diff: bool = false
|
||||
|
||||
for flat_key in _settings:
|
||||
var entry: Variant = default_keys.get(flat_key)
|
||||
var section: String
|
||||
var cfg_key: String
|
||||
if entry != null:
|
||||
section = entry.section
|
||||
cfg_key = entry.key
|
||||
else:
|
||||
# Not in defaults — derive section from flat key (before first "_").
|
||||
var parts: PackedStringArray = flat_key.split("_", true, 1)
|
||||
section = parts[0] if parts.size() > 1 else "general"
|
||||
cfg_key = parts[-1]
|
||||
|
||||
var default_val: Variant = defaults.get_value(section, cfg_key, null)
|
||||
if _settings[flat_key] != default_val:
|
||||
user_cfg.set_value(section, cfg_key, _settings[flat_key])
|
||||
has_diff = true
|
||||
|
||||
if has_diff:
|
||||
user_cfg.save("res://config/config.cfg")
|
||||
|
|
|
|||
14
config/default.cfg
Normal file
14
config/default.cfg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[background]
|
||||
color=0.08, 0.08, 0.12
|
||||
|
||||
[modules]
|
||||
show_cpu=true
|
||||
show_memory=true
|
||||
show_network=true
|
||||
show_disk=true
|
||||
|
||||
[performance]
|
||||
refresh_interval=1.0
|
||||
|
||||
[general]
|
||||
theme=default
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"background_color": "0.08, 0.08, 0.12",
|
||||
"refresh_interval": 1.0,
|
||||
"show_cpu": true,
|
||||
"show_memory": true,
|
||||
"show_network": true,
|
||||
"show_disk": true,
|
||||
"theme": "default"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue