122 lines
3.3 KiB
GDScript
122 lines
3.3 KiB
GDScript
extends Node
|
|
class_name InputSettingsModel
|
|
|
|
## ===============================
|
|
## Dependencies
|
|
## ===============================
|
|
const InputSchema = preload("res://__settings/input/InputSchema.gd")
|
|
const SettingsStorage = preload("res://__settings/SettingStorage.gd")
|
|
|
|
## ===============================
|
|
## Signals
|
|
## ===============================
|
|
signal binding_changed(action: String)
|
|
signal bindings_applied
|
|
signal bindings_reverted
|
|
|
|
## ===============================
|
|
## Internal State
|
|
## ===============================
|
|
var _bindings_committed : Dictionary = {}
|
|
var _bindings_working : Dictionary = {}
|
|
var _storage := SettingsStorage.new()
|
|
|
|
const SECTION := "input"
|
|
|
|
## ===============================
|
|
## Lifecycle
|
|
## ===============================
|
|
func _ready() -> void:
|
|
_load()
|
|
|
|
## ===============================
|
|
## Public API (Read)
|
|
## ===============================
|
|
func get_bindings(action: String) -> Array:
|
|
return _bindings_working.get(action, []).duplicate(true)
|
|
|
|
func get_all_bindings() -> Dictionary:
|
|
return _bindings_working.duplicate(true)
|
|
|
|
## ===============================
|
|
## Public API (Write)
|
|
## ===============================
|
|
func set_bindings(action: String, bindings: Array) -> void:
|
|
_bindings_working[action] = bindings
|
|
emit_signal("binding_changed", action)
|
|
|
|
func add_binding(action: String, binding: Dictionary) -> void:
|
|
if not _bindings_working.has(action):
|
|
_bindings_working[action] = []
|
|
_bindings_working[action].append(binding)
|
|
emit_signal("binding_changed", action)
|
|
|
|
func clear_bindings(action: String) -> void:
|
|
_bindings_working[action] = []
|
|
emit_signal("binding_changed", action)
|
|
|
|
## ===============================
|
|
## Transaction
|
|
## ===============================
|
|
func apply() -> void:
|
|
_bindings_committed = _bindings_working.duplicate(true)
|
|
_save_to_storage()
|
|
_apply_to_input_map()
|
|
emit_signal("bindings_applied")
|
|
|
|
func revert() -> void:
|
|
_bindings_working = _bindings_committed.duplicate(true)
|
|
emit_signal("bindings_reverted")
|
|
|
|
func has_unsaved_changes() -> bool:
|
|
return _bindings_working != _bindings_committed
|
|
|
|
## ===============================
|
|
## Internal
|
|
## ===============================
|
|
func _load() -> void:
|
|
_storage.load()
|
|
|
|
# 1. defaults
|
|
_bindings_committed = InputSchema.defaults().duplicate(true)
|
|
|
|
# 2. override from storage
|
|
for action in _bindings_committed.keys():
|
|
var saved = _storage.get_value(SECTION, action, null)
|
|
if saved != null:
|
|
_bindings_committed[action] = saved
|
|
|
|
_bindings_working = _bindings_committed.duplicate(true)
|
|
|
|
# 3. apply to engine at startup
|
|
_apply_to_input_map()
|
|
|
|
func _save_to_storage() -> void:
|
|
for action in _bindings_committed.keys():
|
|
_storage.set_value(SECTION, action, _bindings_committed[action])
|
|
_storage.save()
|
|
|
|
func _apply_to_input_map() -> void:
|
|
for action in _bindings_committed.keys():
|
|
if not InputMap.has_action(action):
|
|
InputMap.add_action(action)
|
|
|
|
InputMap.action_erase_events(action)
|
|
|
|
for binding in _bindings_committed[action]:
|
|
var event = _binding_to_event(binding)
|
|
if event:
|
|
InputMap.action_add_event(action, event)
|
|
|
|
func _binding_to_event(binding: Dictionary) -> InputEvent:
|
|
match binding.get("type"):
|
|
"key":
|
|
var e := InputEventKey.new()
|
|
e.keycode = binding.get("keycode", 0)
|
|
return e
|
|
"mouse":
|
|
var e := InputEventMouseButton.new()
|
|
e.button_index = binding.get("button", 0)
|
|
return e
|
|
return null
|