-
Notifications
You must be signed in to change notification settings - Fork 81
/
Copy pathSaveableResource.gd
130 lines (103 loc) · 3.21 KB
/
SaveableResource.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
## Base class to create saveable Resource
class_name SaveableResource
extends Resource
signal resource_saved
signal resource_loaded
@export_group("SaveableResource")
## Allows to detect older save data information
@export var version:int
## Isn't saved and resets instead of loading
@export var not_saved:bool
## Keep track if loading have happened and without forcing it won't reload.
var is_loaded:bool = false
## Type of saving save files
enum SaveType {FILE, STEAM}
## Class variable for saving behaviour
static var save_type: = SaveType.FILE
var temporary_data:SaveableResource
var is_temporary:bool
static func set_save_type(value:SaveType)->void:
save_type = value
## Override for creating data Resource that will be saved with the ResourceSaver
func prepare_save()->Resource:
return self.duplicate()
## Override to ad logic for reading loaded data and applying to current instance of the Resource
func prepare_load(_data:Resource)->void:
pass
## Override function for resetting to default values
func reset_resource()->void:
pass
func save_temp()->void:
temporary_data = prepare_save()
func load_temp()->void:
prepare_load(temporary_data)
func get_save_file_path()->String:
if resource_name.is_empty():
resource_name = resource_path.get_file().get_basename()
return "user://" + resource_name + ".tres"
## Saves current state.
## If SaveState is temporary it uses temporary data.
func save_resource()->void:
if not_saved:
return
if is_temporary:
save_temp()
return
if save_type == SaveType.FILE:
## TODO: use error codes for return values
if _save_resource_file() > 0:
return
elif save_type == SaveType.STEAM:
## TODO: use steam integration
if _save_resource_file() > 0:
return
resource_saved.emit()
## Loads and sets last saved state.
## If SaveState is temporary it uses temporary data.
## If it is already loaded once without force_load it won't do loading.
func load_resource(force_load:bool = false)->void:
if is_loaded && !force_load:
return
is_loaded = true
if not_saved:
reset_resource()
return
if is_temporary:
load_temp()
return
var data:SaveableResource
if save_type == SaveType.FILE:
data = _load_resource_file()
elif save_type == SaveType.STEAM:
## TODO: use Steam integration
data = _load_resource_file()
if data == null:
print("SaveableResource [INFO]: save file didn't load, resetting - ", resource_name)
reset_resource()
return
prepare_load(data)
resource_loaded.emit()
func delete_resource()->void:
if save_type == SaveType.FILE:
_delete_resource_file()
elif save_type == SaveType.STEAM:
# TODO: use Steam integration
_delete_resource_file()
func _save_resource_file()->int:
var data:SaveableResource = prepare_save()
var path: = get_save_file_path()
if ResourceSaver.save(data, path):
print("ResourceSaver [INFO]: failed to save file", resource_name)
return 1
return 0
func _load_resource_file()->SaveableResource:
var path: = get_save_file_path()
if !FileAccess.file_exists(path):
print("SaveableResource [INFO]: no save file - ", resource_name)
return null
return ResourceLoader.load(path)
func _delete_resource_file()->void:
var path: = get_save_file_path()
if !FileAccess.file_exists(path):
pass
DirAccess.remove_absolute(path)