summaryrefslogtreecommitdiffstats
path: root/ChunkLoader.gd
diff options
context:
space:
mode:
authordusoleil <howcansocksbereal@gmail.com>2022-09-18 07:45:13 -0400
committerdusoleil <howcansocksbereal@gmail.com>2022-09-18 07:45:13 -0400
commit3ac2fb62b67b6446ab31b2455a4cb74069f1c54f (patch)
tree4764fa39466d7fd0d4ac9133e5a237dd1576a487 /ChunkLoader.gd
parent5923cd97dfafd7fee2784a91e81d7d55ed28448e (diff)
downloadgodot_wildjam_49-3ac2fb62b67b6446ab31b2455a4cb74069f1c54f.tar.gz
godot_wildjam_49-3ac2fb62b67b6446ab31b2455a4cb74069f1c54f.zip
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.
Diffstat (limited to '')
-rw-r--r--ChunkLoader.gd66
1 files changed, 66 insertions, 0 deletions
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)