From 3ac2fb62b67b6446ab31b2455a4cb74069f1c54f Mon Sep 17 00:00:00 2001 From: dusoleil Date: Sun, 18 Sep 2022 07:45:13 -0400 Subject: Add ChunkLoader to World Generation Break up world gen into chunk and offload generating them to a Chunk Loader. The World figures out which chunks should be loaded and gives this to the Chunk Loader. The Chunk Loader frees any chunks out of render distance. It also picks an unloaded chunk and gives it to a worker thread to generate it. --- ChunkLoader.gd | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ChunkLoader.gd (limited to 'ChunkLoader.gd') diff --git a/ChunkLoader.gd b/ChunkLoader.gd new file mode 100644 index 0000000..90cac4f --- /dev/null +++ b/ChunkLoader.gd @@ -0,0 +1,66 @@ +extends Node + +var world = null + +var Chunk = preload("res://Chunk.tscn") +var chunks = {} +var loaded_chunks = {} +var chunk_thread = Thread.new() +var mtx = Mutex.new() +var sgnl = Semaphore.new() +var exit = false +var chunk_to_load = null + +func _ready(): + chunk_thread.start(self, "chunk_loader") + +func _exit_tree(): + mtx.lock() + exit = true + sgnl.post() + mtx.unlock() + chunk_thread.wait_to_finish() + +func add_chunk(coords:Vector2): + chunks[coords] = coords.length() + +func chunk_update(): + var closest_unloaded_chunk = null + var closest_len = 0.0 + for chunk in chunks.keys(): + if !loaded_chunks.has(chunk): + if closest_unloaded_chunk == null || closest_len > chunks[chunk]: + closest_unloaded_chunk = chunk + closest_len = chunks[chunk] + if closest_unloaded_chunk != null: + mtx.lock() + if chunk_to_load == null: + chunk_to_load = closest_unloaded_chunk + sgnl.post() + mtx.unlock() + for chunk in loaded_chunks.keys(): + if !chunks.has(chunk): + var c = loaded_chunks[chunk].get_ref() + if c != null: + c.queue_free() + loaded_chunks.erase(chunk) + chunks = {} + +func chunk_loader(): + while true: + sgnl.wait() + mtx.lock() + var x = exit + var coords = chunk_to_load + chunk_to_load = null + mtx.unlock() + if x: + break + var chunk = Chunk.instance() + chunk.transform.origin = Vector3(coords.x,0.0,coords.y) + ChunkGen.gen_chunk(chunk) + self.call_deferred("finish_chunk", chunk) + +func finish_chunk(chunk): + world.get_node("Chunks").add_child(chunk) + loaded_chunks[Vector2(chunk.transform.origin.x,chunk.transform.origin.z)] = weakref(chunk) -- cgit v1.2.3