78 lines
3.2 KiB
GDScript
78 lines
3.2 KiB
GDScript
@tool
|
|
extends RefCounted
|
|
## Store object properties in an INI-style configuration file.
|
|
|
|
|
|
const CONFIG_PATH_PROPERTY := &"CONFIG_PATH"
|
|
const MAIN_SECTION_PROPERTY := &"MAIN_SECTION"
|
|
const MAIN_SECTION_DEFAULT := "main"
|
|
|
|
static var verbose: bool = false
|
|
|
|
static func _get_config_file(p_object: Object) -> String:
|
|
var from_object_constant = p_object.get(CONFIG_PATH_PROPERTY)
|
|
return from_object_constant if from_object_constant is String else ""
|
|
|
|
|
|
static func _get_main_section(p_object: Object) -> String:
|
|
var from_object_constant = p_object.get(MAIN_SECTION_PROPERTY)
|
|
return from_object_constant if from_object_constant != null else MAIN_SECTION_DEFAULT
|
|
|
|
|
|
static func _msg(p_text: String, p_arg1 = "") -> void:
|
|
if verbose:
|
|
print(p_text, p_arg1)
|
|
|
|
|
|
## Load object properties from config file and return status. [br]
|
|
## If p_config_path is empty, configuration path is taken from object's CONFIG_PATH property.
|
|
static func load_from_config(p_object: Object, p_config_path: String = "") -> int:
|
|
var config_path: String = p_config_path
|
|
if config_path.is_empty():
|
|
config_path = _get_config_file(p_object)
|
|
var section: String = _get_main_section(p_object)
|
|
var config := ConfigFile.new()
|
|
var err: int = config.load(config_path)
|
|
if err != OK:
|
|
_msg("ConfigMapper: Failed to load config: %s err_code: %d" % [config_path, err])
|
|
return err
|
|
_msg("ConfigMapper: Loading config: ", config_path)
|
|
|
|
for prop_info in p_object.get_property_list():
|
|
if prop_info.usage & PROPERTY_USAGE_CATEGORY and prop_info.hint_string.is_empty():
|
|
_msg("ConfigMapper: Processing category: ", prop_info.name)
|
|
section = prop_info.name
|
|
elif prop_info.usage & PROPERTY_USAGE_SCRIPT_VARIABLE and prop_info.usage & PROPERTY_USAGE_STORAGE:
|
|
var value = null
|
|
if config.has_section_key(section, prop_info.name):
|
|
value = config.get_value(section, prop_info.name)
|
|
if value != null and typeof(value) == prop_info.type:
|
|
_msg("ConfigMapper: Loaded setting: %s section: %s value: %s" % [prop_info.name, section, value])
|
|
p_object.set(prop_info.name, value)
|
|
_msg("ConfigMapper: Finished with code: ", OK)
|
|
return OK
|
|
|
|
|
|
## Save object properties to config file and return status. [br]
|
|
## If p_config_path is empty, configuration path is taken from object's CONFIG_PATH property. [br]
|
|
## WARNING: replaces file contents!
|
|
static func save_to_config(p_object: Object, p_config_path: String = "") -> int:
|
|
var config_path: String = p_config_path
|
|
if config_path.is_empty():
|
|
config_path = _get_config_file(p_object)
|
|
var section: String = _get_main_section(p_object)
|
|
var config := ConfigFile.new()
|
|
_msg("ConfigMapper: Saving config: ", config_path)
|
|
|
|
for prop_info in p_object.get_property_list():
|
|
if prop_info.usage & PROPERTY_USAGE_CATEGORY and prop_info.hint_string.is_empty():
|
|
_msg("ConfigMapper: Processing category: ", prop_info.name)
|
|
section = prop_info.name
|
|
elif prop_info.usage & PROPERTY_USAGE_SCRIPT_VARIABLE and prop_info.usage & PROPERTY_USAGE_STORAGE:
|
|
_msg("ConfigMapper: Saving setting: %s section: %s value: %s" % [prop_info.name, section, p_object.get(prop_info.name)])
|
|
config.set_value(section, prop_info.name, p_object.get(prop_info.name))
|
|
|
|
var err: int = config.save(config_path)
|
|
_msg("ConfigMapper: Finished with code: ", err)
|
|
return err
|