125 lines
2.6 KiB
GDScript
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();
|