One_Eleven_Android/scripts/Singletons/SceneLoader.gd
2024-11-10 03:34:28 +03:00

125 lines
2.6 KiB
GDScript

extends Node
var thread
var scene_queue = {}
var file = File.new()
var cache = {}
var awaiters = []
signal on_progress
signal on_scene_loaded
var running;
func _ready():
running = true;
thread = Thread.new()
thread.start(self, "_thread_runner", null)
func _thread_runner(o):
while running:
OS.delay_msec(5)
if scene_queue.size() > 0:
for i in scene_queue:
var err = scene_queue[i].loader.poll()
call_deferred("emit_signal", "on_progress", scene_queue[i].path, scene_queue[i].loader.get_stage_count(), scene_queue[i].loader.get_stage())
if err == ERR_FILE_EOF:
scene_queue[i].loader = scene_queue[i].loader.get_resource()
scene_queue[i].instance = scene_queue[i].loader.instance()
cache[scene_queue[i].path] = scene_queue[i]
call_deferred("emit_signal", "on_scene_loaded", scene_queue[i])
scene_queue.erase(scene_queue[i].path)
elif err != OK:
print("Failed to load: " + scene_queue[i].path)
scene_queue.erase(scene_queue[i].path)
for awaiter in awaiters:
if cache.has(awaiter.path):
if awaiter.path == cache[awaiter.path].path:
awaiter.loader = cache[awaiter.path].loader
awaiter.instance = cache[awaiter.path].instance.duplicate()
call_deferred("emit_signal", "on_scene_loaded", awaiter)
awaiters.remove(awaiters.find(awaiter))
func load_scene(path, props = null):
if not file.file_exists(path):
print("File does not exist: " + path)
return
if cache.has(path):
call_deferred("emit_signal", "on_scene_loaded", {path = path, loader = cache[path].loader, instance = cache[path].loader.instance(), props = props})
return
if not scene_queue.has(path):
scene_queue[path] = {path = path, loader = ResourceLoader.load_interactive(path), instance = null, props = props}
else :
awaiters.push_back({path = path, loader = null, instance = null, props = props})
func is_loading_scene(path):
return scene_queue.has(path)
func clear_cache():
for item in cache:
item.instance.queue_free()
cache = {}
func pop_cache():
if cache.size() > 5:
var lastKey = cache.keys()[0];
cache[lastKey].instance.queue_free()
cache.erase(lastKey);
func getSceneByPath(scenePath:String)->Node:
for i in cache.keys():
var item = cache[i];
if item.path == scenePath:
return item.instance;
return null;
func free_scene_cache(sceneName:String):
sceneName = sceneName + ".tscn";
for i in cache.keys():
if sceneName in i:
cache[i].instance.queue_free()
cache.erase(i);
func get_cache_size()->int:
return cache.size();
func stop_scene_loader():
running = false;
if thread != null:
thread.wait_to_finish();