72 lines
2.6 KiB
GDScript
72 lines
2.6 KiB
GDScript
@abstract
|
|
class_name SaveKitResource
|
|
extends Resource
|
|
## Base class for user-defined resources that can be saved and loaded.
|
|
##
|
|
## [code]SaveKitResource[/code]s are used instead of the base [Resource] class to clearly identify data that is meant for persistence in save files, versus resource data that is part of the game's PCK.
|
|
|
|
## Emitted whenever this resource is saved.
|
|
signal saved
|
|
|
|
## Emitted whenever this resource is loaded.
|
|
signal loaded
|
|
|
|
const ReflectionUtils := preload("reflection_utils.gd")
|
|
const Serializer := preload("serializer.gd")
|
|
const Deserializer := preload("deserializer.gd")
|
|
|
|
## Saves data for this resource into a dictionary, suitable for persisting. This will serialize all of the resource's exported properties that have a non-default value.
|
|
##
|
|
## This method can be overridden to implement custom saving behavior.
|
|
func save_to_dict(s: Serializer) -> Dictionary:
|
|
var script: Script = get_script()
|
|
var script_property_default_values: Dictionary[String, Variant]
|
|
ReflectionUtils.get_script_default_property_values(script, script_property_default_values)
|
|
|
|
var save_dict := {}
|
|
for property in script.get_script_property_list():
|
|
var name: String = property["name"]
|
|
var usage: PropertyUsageFlags = property["usage"]
|
|
if usage & PROPERTY_USAGE_STORAGE == 0:
|
|
continue
|
|
|
|
var value: Variant = get(name)
|
|
|
|
# Don't save default values
|
|
if name in script_property_default_values and value == script_property_default_values[name]:
|
|
continue
|
|
|
|
save_dict[name] = s.encode_var(value)
|
|
|
|
saved.emit()
|
|
return save_dict
|
|
|
|
## Loads data into this resource from the given dictionary. This will set the resource's properties to the decoded values of [param data].
|
|
##
|
|
## This method can be overridden to implement custom loading behavior.
|
|
func load_from_dict(s: Deserializer, data: Dictionary) -> void:
|
|
var properties_by_name: Dictionary[String, Dictionary]
|
|
for property: Dictionary in self.get_property_list():
|
|
properties_by_name[property.name] = property
|
|
|
|
for name: String in data:
|
|
if name not in properties_by_name:
|
|
push_warning("Cannot load saved property ", name, " not currently found on resource ", self )
|
|
continue
|
|
|
|
var property := properties_by_name[name]
|
|
var usage_flags: PropertyUsageFlags = property["usage"]
|
|
if usage_flags & PROPERTY_USAGE_STORAGE == 0:
|
|
push_warning("Not loading property ", name, " with storage disabled")
|
|
continue
|
|
|
|
var encoded_value: Variant = data[name]
|
|
var type: Variant.Type = property["type"]
|
|
var classname: StringName = property.get("class_name", &"")
|
|
|
|
var decoded_value: Variant = s.decode_var(encoded_value, type, classname)
|
|
set(name, decoded_value)
|
|
|
|
loaded.emit()
|
|
emit_changed()
|