109 lines
3.2 KiB
GDScript3
109 lines
3.2 KiB
GDScript3
|
|
# scripts/settings/SettingsModel.gd
|
||
|
|
extends Node
|
||
|
|
class_name SettingsModel
|
||
|
|
|
||
|
|
## ===============================
|
||
|
|
## Dependencies
|
||
|
|
## ===============================
|
||
|
|
const SettingsSchema = preload("res://__settings/SettingSchema.gd")
|
||
|
|
const SettingsStorage = preload("res://__settings/SettingStorage.gd")
|
||
|
|
|
||
|
|
## ===============================
|
||
|
|
## Signals
|
||
|
|
## ===============================
|
||
|
|
signal setting_changed(section: String, key: String, value)
|
||
|
|
signal settings_applied
|
||
|
|
signal settings_reverted
|
||
|
|
|
||
|
|
## ===============================
|
||
|
|
## Internal State
|
||
|
|
## ===============================
|
||
|
|
var _data_committed : Dictionary = {} # 已生效 / 已保存
|
||
|
|
var _data_working : Dictionary = {} # UI 正在修改
|
||
|
|
var _storage := SettingsStorage.new()
|
||
|
|
|
||
|
|
## ===============================
|
||
|
|
## Lifecycle
|
||
|
|
## ===============================
|
||
|
|
func _ready() -> void:
|
||
|
|
_load()
|
||
|
|
|
||
|
|
## ===============================
|
||
|
|
## Public API (Read)
|
||
|
|
## ===============================
|
||
|
|
func get_setting(section: String, key: String) -> Variant:
|
||
|
|
return _data_working.get(section, {}).get(key)
|
||
|
|
|
||
|
|
func get_section(section: String) -> Dictionary:
|
||
|
|
return _data_working.get(section, {}).duplicate(true)
|
||
|
|
|
||
|
|
## ===============================
|
||
|
|
## Public API (Write - Working Only)
|
||
|
|
## ===============================
|
||
|
|
func set_setting(section: String, key: String, value: Variant) -> void:
|
||
|
|
if not _data_working.has(section):
|
||
|
|
_data_working[section] = {}
|
||
|
|
|
||
|
|
_data_working[section][key] = value
|
||
|
|
emit_signal("setting_changed", section, key, value)
|
||
|
|
|
||
|
|
## ===============================
|
||
|
|
## Typed Getters
|
||
|
|
## ===============================
|
||
|
|
func get_bool(section: String, key: String) -> bool:
|
||
|
|
var value = get_setting(section, key)
|
||
|
|
return value if typeof(value) == TYPE_BOOL else false
|
||
|
|
|
||
|
|
func get_int(section: String, key: String) -> int:
|
||
|
|
var value = get_setting(section, key)
|
||
|
|
return value if typeof(value) == TYPE_INT else 0
|
||
|
|
|
||
|
|
func get_float(section: String, key: String) -> float:
|
||
|
|
var value = get_setting(section, key)
|
||
|
|
if typeof(value) == TYPE_FLOAT or typeof(value) == TYPE_INT:
|
||
|
|
return float(value)
|
||
|
|
return 0.0
|
||
|
|
|
||
|
|
func get_string(section: String, key: String) -> String:
|
||
|
|
var value = get_setting(section, key)
|
||
|
|
return value if typeof(value) == TYPE_STRING else ""
|
||
|
|
|
||
|
|
## ===============================
|
||
|
|
## Transaction Control
|
||
|
|
## ===============================
|
||
|
|
func apply() -> void:
|
||
|
|
_data_committed = _data_working.duplicate(true)
|
||
|
|
|
||
|
|
for section in _data_committed.keys():
|
||
|
|
for key in _data_committed[section].keys():
|
||
|
|
_storage.set_value(section, key, _data_committed[section][key])
|
||
|
|
|
||
|
|
_storage.save()
|
||
|
|
emit_signal("settings_applied")
|
||
|
|
|
||
|
|
func revert() -> void:
|
||
|
|
_data_working = _data_committed.duplicate(true)
|
||
|
|
emit_signal("settings_reverted")
|
||
|
|
|
||
|
|
func has_unsaved_changes() -> bool:
|
||
|
|
return _data_working != _data_committed
|
||
|
|
|
||
|
|
## ===============================
|
||
|
|
## Internal
|
||
|
|
## ===============================
|
||
|
|
func _load() -> void:
|
||
|
|
_storage.load()
|
||
|
|
|
||
|
|
# 1. Load defaults
|
||
|
|
_data_committed = SettingsSchema.defaults().duplicate(true)
|
||
|
|
|
||
|
|
# 2. Override with saved values
|
||
|
|
for section in _data_committed.keys():
|
||
|
|
for key in _data_committed[section].keys():
|
||
|
|
var default_value = _data_committed[section][key]
|
||
|
|
var value = _storage.get_value(section, key, default_value)
|
||
|
|
_data_committed[section][key] = value
|
||
|
|
|
||
|
|
# 3. Init working copy
|
||
|
|
_data_working = _data_committed.duplicate(true)
|