Created
October 21, 2024 22:37
-
-
Save distransient/dbb35d65f5b7027ff63f95a16084dddd to your computer and use it in GitHub Desktop.
Godot settings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class_name ConfigBase extends Node | |
## Base class for Configuration | |
## Types to filter on when reflecting on subclass properties. | |
const VALID_PROP_TYPES : Array[int] = [ | |
Variant.Type.TYPE_BOOL, | |
Variant.Type.TYPE_INT, | |
Variant.Type.TYPE_FLOAT, | |
Variant.Type.TYPE_STRING, | |
] | |
## Name of the file to load and save config on. | |
var _file_name : String = "" | |
## Name of the current script, used for debugging. | |
var _script_name : String = "" | |
## Call this in subclasses after setting [field self._file_name]. | |
func _init() -> void: | |
self._script_name = self._get_script_name() | |
if self._file_name.length() > 0: | |
var config_err: Error = self.read() | |
if config_err == Error.ERR_FILE_NOT_FOUND: self.write() | |
## Synchronously reads this config's file values into the singleton. | |
func read() -> Error: | |
assert(self._file_name.length() > 0, "Config _file_name must be set in subclass.") | |
var config := ConfigFile.new() | |
var config_err: Error = config.load(self._file_name) | |
if config_err == Error.OK: | |
print_debug("[", self._script_name, "]: Reading user cfg from " + self._file_name) | |
self._read_config(config) | |
elif config_err == Error.ERR_FILE_NOT_FOUND: | |
print("[", self._script_name, "]: Config file not yet created: " + self._file_name) | |
else: | |
printerr("[", self._script_name, | |
"]: Error when loading settings cfg: ", | |
config_err) | |
return config_err | |
## Synchronously writes this config's values into the destination file. | |
func write() -> Error: | |
assert(self._file_name.length() > 0, "Config _file_name must be set in subclass.") | |
print_debug("Writing user cfg to " + self._file_name) | |
var config := ConfigFile.new() | |
self._write_config(config) | |
var config_err: Error = config.save(self._file_name) | |
if config_err != Error.OK: | |
printerr("[", self._script_name, | |
"]: Error when saving settings cfg:", | |
config_err) | |
else: | |
print_debug("[", self._script_name, | |
"]: Successfully wrote cfg to path: ", | |
self._file_name) | |
return config_err | |
## Loops over the values in a [ConfigFile], setting the fields on the class. | |
func _read_config(config: ConfigFile) -> void: | |
# Loop over all properties on self, getting the value in the ConfigFile. | |
for prop in self._get_props(): | |
var prop_section : String = prop[0] | |
var prop_key : String = prop[1] | |
var prop_name : String = prop_section + "_" + prop_key | |
var default_val : Variant = self[prop_name] | |
self[prop_name] = config.get_value(prop_section, prop_key, default_val) | |
print_debug("[", self._script_name, "]: Loaded ", prop_name, | |
" (", prop_section, | |
"[", prop_key, | |
"]) from user cfg as ", self[prop_name], | |
" with default ", default_val) | |
## Saves all valid setting names on current script to [ConfigFile]. | |
func _write_config(config: ConfigFile) -> void: | |
# Loop over all properties on self, setting the value in the ConfigFile. | |
for prop in self._get_props(): | |
var prop_section : String = prop[0] | |
var prop_key : String = prop[1] | |
var prop_name : String = prop[0] + "_" + prop[1] | |
var prop_val : Variant = self[prop_name] | |
config.set_value(prop_section, prop_key, prop_val) | |
print_debug("[", self._script_name, "]: Wrote ", prop_name, | |
" (", prop_section, | |
"[", prop_key, | |
"]) to user cfg with value: ", prop_val) | |
## Reflects on all properties of the current script, returning valid setting names. | |
func _get_props() -> Array[PackedStringArray]: | |
var result : Array[PackedStringArray] = [] | |
var script: Script = self.get_script() | |
for prop in script.get_script_property_list(): | |
var prop_type : int = prop["type"] | |
var prop_name : String = prop["name"] | |
var is_internal_prop : bool = prop_name.begins_with("_") | |
var is_valid_prop_type : bool = VALID_PROP_TYPES.has(prop_type) | |
if !is_internal_prop and is_valid_prop_type: | |
print_debug("[", self._script_name, | |
"]: Reflecting on valid public property \"", prop_name, | |
"\" with type: ", prop_type) | |
result.push_back(prop_name.split("_", false, 1)) | |
else: | |
print_debug("[", self._script_name, "]: Ignoring reflected ", | |
"valid " if is_valid_prop_type else "invalid ", | |
"private " if is_internal_prop else "public ", | |
"property \"", prop_name, "\" with type: ", prop_type) | |
return result | |
## Reflects on script property list, fetching just the script name. | |
func _get_script_name() -> String: | |
var script: Script = self.get_script() | |
for prop in script.get_script_property_list(): | |
var prop_type : int = prop["type"] | |
var prop_name : String = prop["name"] | |
if prop_type == Variant.Type.TYPE_NIL: return prop_name | |
return "" | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends ScConfigBase | |
## Configurable user settings file | |
## Destination file name to copy to the base class. | |
const FILE_NAME : String = "user://settings.cfg" | |
## Multiplier for mouse look sensitivity. Not used for UI. | |
var input_mouse_sens : float = 1.0 | |
## Multiplier for joystick look sensitivity (lateral). Not used for UI. | |
var input_joy_look_x_sens : float = 0.02 | |
## Multiplier for joystick look sensitivity (vertical). Not used for UI. | |
var input_joy_look_y_sens : float = 0.02 | |
## Multiplier for joystick look deadzone (lateral). Not used for UI. | |
var input_joy_look_x_deadzone : float = 0.08 | |
## Multiplier for joystick look deadzone (vertical). Not used for UI. | |
var input_joy_look_y_deadzone : float = 0.08 | |
## Multiplier for joystick move deadzone (lateral). Used for movement and UI. | |
var input_joy_move_x_deadzone : float = 0.08 | |
## Multiplier for joystick move deadzone (vertical). Used for movement and UI. | |
var input_joy_move_y_deadzone : float = 0.08 | |
## Sets the destination file name and initializes the configuration. | |
func _init() -> void: | |
self._file_name = FILE_NAME | |
super._init() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment