I want to implement a threaded loading component into my game. I am currently saving all my settings and other level files as bytes externally (meaning not in the res:// folders), as I want to be able to export files and send them to others, so they can use them as well. There is the ResourceLoader.load_threaded_request() method, but that only returns Resources and not PackedByteArrays. As far as I can tell, there is only the FileAccess.get_file_as_bytes() method for importing byte files, which has to run in the main thread (and thus blocking it until the load is complete). Does someone know if I am missing some method here?
EDIT: I have put my fix for this into the comments
Fix:
Run the FileAccess.get_file_as_bytes() method in a thread. I thought a thread wouldn't allow for loading files using FileAccess, but it seems I was mistaken. I personally just make the Thread run my _threaded_loading(file_path:String) method and then call a signal named loaded_bytes(data:PackedByteArray). The _threaded_loading method looks like this:
func _threaded_loading(path:String) -> void:
print("I am the thread and I will now load this file")
var file:FileAccess = FileAccess.open(path, FileAccess.READ)
print("i have opened the file")
var bytes:PackedByteArray = file.get_buffer(file.get_length())
print("I have the bytes of the file")
file.close()
print("I have closed the file")
call_deferred_thread_group("emit_signal", "loaded_bytes", bytes)
return
It is important to emit the signal deferred, as a Thread on its own can't emit a signal on its own. I did print a lot in the method just to check that everything is working as intended. I hope this helps someone!
I have found that this is incredibly fast. Loading files in threads in insane. Here is a demo where Godot loads 456 files, which all together add up to 1.6 GB in size in less than four seconds
https://files.catbox.moe/g28op4.webm