diff --git a/Classes/ResourceQueue.gd b/Classes/ResourceQueue.gd new file mode 100644 index 0000000..86652cc --- /dev/null +++ b/Classes/ResourceQueue.gd @@ -0,0 +1,147 @@ +class_name ResourceQueue + +var thread +var mutex +var sem + +var time_max = 100 # Milliseconds. + +var queue = [] +var pending = {} + +func _lock(_caller): + mutex.lock() + + +func _unlock(_caller): + mutex.unlock() + + +func _post(_caller): + sem.post() + + +func _wait(_caller): + sem.wait() + + +func queue_resource(path, p_in_front = false): + _lock("queue_resource") + if path in pending: + _unlock("queue_resource") + return + elif ResourceLoader.has_cached(path): + var res = ResourceLoader.load(path) + pending[path] = res + _unlock("queue_resource") + return + else: + var res = ResourceLoader.load_interactive(path) + res.set_meta("path", path) + if p_in_front: + queue.insert(0, res) + else: + queue.push_back(res) + pending[path] = res + _post("queue_resource") + _unlock("queue_resource") + return + + +func cancel_resource(path): + _lock("cancel_resource") + if path in pending: + if pending[path] is ResourceInteractiveLoader: + queue.erase(pending[path]) + pending.erase(path) + _unlock("cancel_resource") + + +func get_progress(path): + _lock("get_progress") + var ret = -1 + if path in pending: + if pending[path] is ResourceInteractiveLoader: + ret = float(pending[path].get_stage()) / float(pending[path].get_stage_count()) + else: + ret = 1.0 + _unlock("get_progress") + return ret + + +func is_ready(path): + var ret + _lock("is_ready") + if path in pending: + ret = !(pending[path] is ResourceInteractiveLoader) + else: + ret = false + _unlock("is_ready") + return ret + + +func _wait_for_resource(res, path): + _unlock("wait_for_resource") + while true: + VisualServer.sync() + OS.delay_usec(16000) # Wait approximately 1 frame. + _lock("wait_for_resource") + if queue.size() == 0 || queue[0] != res: + return pending[path] + _unlock("wait_for_resource") + + +func get_resource(path): + _lock("get_resource") + if path in pending: + if pending[path] is ResourceInteractiveLoader: + var res = pending[path] + if res != queue[0]: + var pos = queue.find(res) + queue.remove(pos) + queue.insert(0, res) + + res = _wait_for_resource(res, path) + pending.erase(path) + _unlock("return") + return res + else: + var res = pending[path] + pending.erase(path) + _unlock("return") + return res + else: + _unlock("return") + return ResourceLoader.load(path) + + +func thread_process(): + _wait("thread_process") + _lock("process") + + while queue.size() > 0: + var res = queue[0] + _unlock("process_poll") + var ret = res.poll() + _lock("process_check_queue") + + if ret == ERR_FILE_EOF || ret != OK: + var path = res.get_meta("path") + if path in pending: # Else, it was already retrieved. + pending[res.get_meta("path")] = res.get_resource() + # Something might have been put at the front of the queue while + # we polled, so use erase instead of remove. + queue.erase(res) + _unlock("process") + + +func thread_func(_u): + while true: + thread_process() + + +func start(): + mutex = Mutex.new() + sem = Semaphore.new() + thread = Thread.new() + thread.start(self, "thread_func", 0) diff --git a/Scenes/Map.gd b/Scenes/Map.gd index 998ae47..fe12e87 100644 --- a/Scenes/Map.gd +++ b/Scenes/Map.gd @@ -6,6 +6,9 @@ class_name GameMap var ship_direction = 0 var ship_speed = 0 +var current_ship_position = Vector2.ZERO +var current_ship_target = Vector2.ZERO + var current_ship_direction = 0 var current_ship_speed = 0 diff --git a/Scenes/Menu.gd b/Scenes/Menu.gd index 81f7dee..80aad20 100644 --- a/Scenes/Menu.gd +++ b/Scenes/Menu.gd @@ -1,6 +1,6 @@ extends Control -export var scale = 2 setget set_scale +export var scale = 4 setget set_scale export var upThreshold = 1.0/Engine.iterations_per_second export var downThreshold = 1.0/30.0 diff --git a/Scenes/World.gd b/Scenes/World.gd index 5e16c32..f9a86fb 100644 --- a/Scenes/World.gd +++ b/Scenes/World.gd @@ -6,8 +6,6 @@ enum Map { RUNTIME, ODYSSEY } export(Map) var mapToLoad = Map.RUNTIME -const runtimeRes = preload("res://Scenes/Maps/runtime.tscn") -const odysseyRes = preload("res://Scenes/Maps/odyssey.tscn") const playerRes = preload("res://Actors/Player/Player.tscn") var map = null @@ -16,9 +14,9 @@ var player = null func _ready(): match mapToLoad: Map.RUNTIME: - map = runtimeRes.instance() + map = load("res://Scenes/Maps/runtime.tscn").instance() Map.ODYSSEY: - map = odysseyRes.instance() + map = load("res://Scenes/Maps/odyssey.tscn").instance() add_child(map) player = playerRes.instance() player.is_controlled = true diff --git a/project.godot b/project.godot index e43245f..59bab19 100644 --- a/project.godot +++ b/project.godot @@ -94,6 +94,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://Actors/Systems/Electricity/ElectricProbe.gd" }, { +"base": "Reference", +"class": "ResourceQueue", +"language": "GDScript", +"path": "res://Classes/ResourceQueue.gd" +}, { "base": "Node2D", "class": "SpawnpointPlayer", "language": "GDScript", @@ -122,6 +127,7 @@ _global_script_class_icons={ "PowerManager": "", "PowerNetwork": "", "ProbeElectric": "", +"ResourceQueue": "", "SpawnpointPlayer": "", "UICommand": "" }