Skip to content

Commit 40e7b5c

Browse files
Merge pull request #403 from GodotNuts/refactor-storage-remove-task
Update storage to make StorageTask fully transparent
2 parents eb1f83f + b307f50 commit 40e7b5c

File tree

3 files changed

+92
-118
lines changed

3 files changed

+92
-118
lines changed

addons/godot-firebase/storage/storage.gd

+34-37
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ extends Node
1010

1111
const _API_VERSION : String = "v0"
1212

13-
## @arg-types int, int, PackedStringArray
14-
## @arg-enums HTTPRequest.Result, HTTPClient.ResponseCode
15-
## Emitted when a [StorageTask] has finished successful.
16-
signal task_successful(result, response_code, data)
17-
1813
## @arg-types int, int, PackedStringArray
1914
## @arg-enums HTTPRequest.Result, HTTPClient.ResponseCode
2015
## Emitted when a [StorageTask] has finished with an error.
@@ -83,6 +78,7 @@ func _internal_process(_delta : float) -> void:
8378
for header in _response_headers:
8479
if "Content-Length" in header:
8580
_content_length = header.trim_prefix("Content-Length: ").to_int()
81+
break
8682

8783
_http_client.poll()
8884
var chunk = _http_client.read_response_body_chunk() # Get a chunk.
@@ -127,13 +123,13 @@ func ref(path := "") -> StorageReference:
127123
if not _references.has(path):
128124
var ref := StorageReference.new()
129125
_references[path] = ref
130-
ref.valid = true
131126
ref.bucket = bucket
132127
ref.full_path = path
133-
ref.name = path.get_file()
128+
ref.file_name = path.get_file()
134129
ref.parent = ref(path.path_join(".."))
135130
ref.root = _root_ref
136131
ref.storage = self
132+
add_child(ref)
137133
return ref
138134
else:
139135
return _references[path]
@@ -158,9 +154,9 @@ func _check_emulating() -> void :
158154
_base_url = "http://localhost:{port}/{version}/".format({ version = _API_VERSION, port = port })
159155

160156

161-
func _upload(data : PackedByteArray, headers : PackedStringArray, ref : StorageReference, meta_only : bool) -> StorageTask:
157+
func _upload(data : PackedByteArray, headers : PackedStringArray, ref : StorageReference, meta_only : bool) -> Variant:
162158
if _is_invalid_authentication():
163-
return null
159+
return 0
164160

165161
var task := StorageTask.new()
166162
task.ref = ref
@@ -169,11 +165,11 @@ func _upload(data : PackedByteArray, headers : PackedStringArray, ref : StorageR
169165
task._headers = headers
170166
task.data = data
171167
_process_request(task)
172-
return task
168+
return await task.task_finished
173169

174-
func _download(ref : StorageReference, meta_only : bool, url_only : bool) -> StorageTask:
170+
func _download(ref : StorageReference, meta_only : bool, url_only : bool) -> Variant:
175171
if _is_invalid_authentication():
176-
return null
172+
return 0
177173

178174
var info_task := StorageTask.new()
179175
info_task.ref = ref
@@ -182,7 +178,7 @@ func _download(ref : StorageReference, meta_only : bool, url_only : bool) -> Sto
182178
_process_request(info_task)
183179

184180
if url_only or meta_only:
185-
return info_task
181+
return await info_task.task_finished
186182

187183
var task := StorageTask.new()
188184
task.ref = ref
@@ -199,33 +195,36 @@ func _download(ref : StorageReference, meta_only : bool, url_only : bool) -> Sto
199195
task.response_code = info_task.response_code
200196
task.result = info_task.result
201197
task.finished = true
202-
task.task_finished.emit()
198+
task.task_finished.emit(null)
203199
task_failed.emit(task.result, task.response_code, task.data)
204200
_pending_tasks.erase(task)
201+
return null
205202

206-
return task
203+
return await task.task_finished
207204

208-
func _list(ref : StorageReference, list_all : bool) -> StorageTask:
205+
func _list(ref : StorageReference, list_all : bool) -> Array:
209206
if _is_invalid_authentication():
210-
return null
207+
return []
211208

212209
var task := StorageTask.new()
213210
task.ref = ref
214211
task._url = _get_file_url(_root_ref).trim_suffix("/")
215212
task.action = StorageTask.Task.TASK_LIST_ALL if list_all else StorageTask.Task.TASK_LIST
216213
_process_request(task)
217-
return task
214+
return await task.task_finished
218215

219-
func _delete(ref : StorageReference) -> StorageTask:
216+
func _delete(ref : StorageReference) -> bool:
220217
if _is_invalid_authentication():
221-
return null
218+
return false
222219

223220
var task := StorageTask.new()
224221
task.ref = ref
225222
task._url = _get_file_url(ref)
226223
task.action = StorageTask.Task.TASK_DELETE
227224
_process_request(task)
228-
return task
225+
var data = await task.task_finished
226+
227+
return data == null
229228

230229
func _process_request(task : StorageTask) -> void:
231230
if requesting:
@@ -262,7 +261,10 @@ func _finish_request(result : int) -> void:
262261

263262
StorageTask.Task.TASK_DELETE:
264263
_references.erase(task.ref.full_path)
265-
task.ref.valid = false
264+
for child in get_children():
265+
if child.full_path == task.ref.full_path:
266+
child.queue_free()
267+
break
266268
if typeof(task.data) == TYPE_PACKED_BYTE_ARRAY:
267269
task.data = null
268270

@@ -301,26 +303,21 @@ func _finish_request(result : int) -> void:
301303
var json = Utilities.get_json_data(_response_data)
302304
task.data = json
303305

304-
var next_task : StorageTask
305-
if not _pending_tasks.is_empty():
306-
next_task = _pending_tasks.pop_front()
307-
306+
var next_task = _get_next_pending_task()
307+
308308
task.finished = true
309309
task.task_finished.emit(task.data) # I believe this parameter has been missing all along, but not sure. Caused weird results at times with a yield/await returning null, but the task containing data.
310310
if typeof(task.data) == TYPE_DICTIONARY and task.data.has("error"):
311311
task_failed.emit(task.result, task.response_code, task.data)
312-
else:
313-
task_successful.emit(task.result, task.response_code, task.data)
314-
315-
while true:
316-
if next_task and not next_task.finished:
317-
_process_request(next_task)
318-
break
319-
elif not _pending_tasks.is_empty():
320-
next_task = _pending_tasks.pop_front()
321-
else:
322-
break
323312

313+
if next_task and not next_task.finished:
314+
_process_request(next_task)
315+
316+
func _get_next_pending_task() -> StorageTask:
317+
if _pending_tasks.is_empty():
318+
return null
319+
320+
return _pending_tasks.pop_front()
324321

325322
func _get_file_url(ref : StorageReference) -> String:
326323
var url := _extended_url.replace("[APP_ID]", ref.bucket)

addons/godot-firebase/storage/storage_reference.gd

+34-58
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
## This object is used to interact with the cloud storage. You may get data from the server, as well as upload your own back to it.
55
@tool
66
class_name StorageReference
7-
extends RefCounted
7+
extends Node
88

99
## The default MIME type to use when uploading a file.
1010
## Data sent with this type are interpreted as plain binary data. Note that firebase will generate an MIME type based checked the file extenstion if none is provided.
@@ -36,7 +36,7 @@ const MIME_TYPES = {
3636
"txt": "text/plain",
3737
"wav": "audio/wav",
3838
"webm": "video/webm",
39-
"webp": "video/webm",
39+
"webp": "image/webp",
4040
"xml": "text/xml",
4141
}
4242

@@ -51,7 +51,7 @@ var full_path : String = ""
5151
## @default ""
5252
## The name of the file/folder, including any file extension.
5353
## Example: If the [member full_path] is [code]images/user/image.png[/code], then the [member name] would be [code]image.png[/code].
54-
var name : String = ""
54+
var file_name : String = ""
5555

5656
## The parent [StorageReference] one level up the file hierarchy.
5757
## If the current [StorageReference] is the root (i.e. the [member full_path] is [code]""[/code]) then the [member parent] will be [code]null[/code].
@@ -64,116 +64,92 @@ var root : StorageReference
6464
## The Storage API that created this [StorageReference] to begin with.
6565
var storage # FirebaseStorage (Can't static type due to cyclic reference)
6666

67-
## @default false
68-
## Whether this [StorageReference] is valid. None of the functions will work when in an invalid state.
69-
## It is set to false when [method delete] is called.
70-
var valid : bool = false
71-
7267
## @args path
7368
## @return StorageReference
7469
## Returns a reference to another [StorageReference] relative to this one.
7570
func child(path : String) -> StorageReference:
76-
if not valid:
77-
return null
7871
return storage.ref(full_path.path_join(path))
7972

8073
## @args data, metadata
81-
## @return StorageTask
82-
## Makes an attempt to upload data to the referenced file location. Status checked this task is found in the returned [StorageTask].
83-
func put_data(data : PackedByteArray, metadata := {}) -> StorageTask:
84-
if not valid:
85-
return null
74+
## @return int
75+
## Makes an attempt to upload data to the referenced file location. Returns Variant
76+
func put_data(data : PackedByteArray, metadata := {}) -> Variant:
8677
if not "Content-Length" in metadata and not Utilities.is_web():
8778
metadata["Content-Length"] = data.size()
8879

8980
var headers := []
9081
for key in metadata:
9182
headers.append("%s: %s" % [key, metadata[key]])
9283

93-
return storage._upload(data, headers, self, false)
84+
return await storage._upload(data, headers, self, false)
85+
9486

9587
## @args data, metadata
96-
## @return StorageTask
88+
## @return int
9789
## Like [method put_data], but [code]data[/code] is a [String].
98-
func put_string(data : String, metadata := {}) -> StorageTask:
99-
return put_data(data.to_utf8_buffer(), metadata)
90+
func put_string(data : String, metadata := {}) -> Variant:
91+
return await put_data(data.to_utf8_buffer(), metadata)
10092

10193
## @args file_path, metadata
102-
## @return StorageTask
94+
## @return int
10395
## Like [method put_data], but the data comes from a file at [code]file_path[/code].
104-
func put_file(file_path : String, metadata := {}) -> StorageTask:
96+
func put_file(file_path : String, metadata := {}) -> Variant:
10597
var file := FileAccess.open(file_path, FileAccess.READ)
10698
var data := file.get_buffer(file.get_length())
10799

108100
if "Content-Type" in metadata:
109101
metadata["Content-Type"] = MIME_TYPES.get(file_path.get_extension(), DEFAULT_MIME_TYPE)
110102

111-
return put_data(data, metadata)
103+
return await put_data(data, metadata)
112104

113-
## @return StorageTask
105+
## @return Variant
114106
## Makes an attempt to download the files from the referenced file location. Status checked this task is found in the returned [StorageTask].
115-
func get_data() -> StorageTask:
116-
if not valid:
117-
return null
118-
storage._download(self, false, false)
119-
return storage._pending_tasks[-1]
107+
func get_data() -> Variant:
108+
var result = await storage._download(self, false, false)
109+
return result
120110

121111
## @return StorageTask
122112
## Like [method get_data], but the data in the returned [StorageTask] comes in the form of a [String].
123-
func get_string() -> StorageTask:
124-
var task := get_data()
125-
task.task_finished.connect(_on_task_finished.bind(task, "stringify"))
126-
return task
113+
func get_string() -> String:
114+
var task := await get_data()
115+
_on_task_finished(task, "stringify")
116+
return task.data
127117

128118
## @return StorageTask
129119
## Attempts to get the download url that points to the referenced file's data. Using the url directly may require an authentication header. Status checked this task is found in the returned [StorageTask].
130-
func get_download_url() -> StorageTask:
131-
if not valid:
132-
return null
133-
return storage._download(self, false, true)
120+
func get_download_url() -> Variant:
121+
return await storage._download(self, false, true)
134122

135123
## @return StorageTask
136124
## Attempts to get the metadata of the referenced file. Status checked this task is found in the returned [StorageTask].
137-
func get_metadata() -> StorageTask:
138-
if not valid:
139-
return null
140-
return storage._download(self, true, false)
125+
func get_metadata() -> Variant:
126+
return await storage._download(self, true, false)
141127

142128
## @args metadata
143129
## @return StorageTask
144130
## Attempts to update the metadata of the referenced file. Any field with a value of [code]null[/code] will be deleted checked the server end. Status checked this task is found in the returned [StorageTask].
145-
func update_metadata(metadata : Dictionary) -> StorageTask:
146-
if not valid:
147-
return null
131+
func update_metadata(metadata : Dictionary) -> Variant:
148132
var data := JSON.stringify(metadata).to_utf8_buffer()
149133
var headers := PackedStringArray(["Accept: application/json"])
150-
return storage._upload(data, headers, self, true)
134+
return await storage._upload(data, headers, self, true)
151135

152136
## @return StorageTask
153137
## Attempts to get the list of files and/or folders under the referenced folder This function is not nested unlike [method list_all]. Status checked this task is found in the returned [StorageTask].
154-
func list() -> StorageTask:
155-
if not valid:
156-
return null
157-
return storage._list(self, false)
138+
func list() -> Array:
139+
return await storage._list(self, false)
158140

159141
## @return StorageTask
160142
## Attempts to get the list of files and/or folders under the referenced folder This function is nested unlike [method list]. Status checked this task is found in the returned [StorageTask].
161-
func list_all() -> StorageTask:
162-
if not valid:
163-
return null
164-
return storage._list(self, true)
143+
func list_all() -> Array:
144+
return await storage._list(self, true)
165145

166146
## @return StorageTask
167147
## Attempts to delete the referenced file/folder. If successful, the reference will become invalid And can no longer be used. If you need to reference this location again, make a new reference with [method StorageTask.ref]. Status checked this task is found in the returned [StorageTask].
168-
func delete() -> StorageTask:
169-
if not valid:
170-
return null
171-
return storage._delete(self)
148+
func delete() -> bool:
149+
return await storage._delete(self)
172150

173151
func _to_string() -> String:
174152
var string := "gs://%s/%s" % [bucket, full_path]
175-
if not valid:
176-
string += " [Invalid RefCounted]"
177153
return string
178154

179155
func _on_task_finished(task : StorageTask, action : String) -> void:

0 commit comments

Comments
 (0)