From 5dbfdac48efbfd1fa7dc74aea348601060fe5d2f Mon Sep 17 00:00:00 2001
From: Relintai <relintai@relintai.net>
Date: Mon, 7 Apr 2025 12:53:51 +0200
Subject: [PATCH] Now TerrainWorld uses TerrainWorldChunkDataManagers if they
 are available.

---
 modules/terraman/doc_classes/TerrainWorld.xml | 16 ++++
 modules/terraman/world/terrain_world.cpp      | 86 ++++++++++++++++++-
 modules/terraman/world/terrain_world.h        |  7 ++
 3 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/modules/terraman/doc_classes/TerrainWorld.xml b/modules/terraman/doc_classes/TerrainWorld.xml
index 8d5a3868a..c8964c03b 100644
--- a/modules/terraman/doc_classes/TerrainWorld.xml
+++ b/modules/terraman/doc_classes/TerrainWorld.xml
@@ -89,6 +89,13 @@
 			<description>
 			</description>
 		</method>
+		<method name="chunk_get_or_load">
+			<return type="TerrainChunk" />
+			<argument index="0" name="x" type="int" />
+			<argument index="1" name="z" type="int" />
+			<description>
+			</description>
+		</method>
 		<method name="chunk_has" qualifiers="const">
 			<return type="bool" />
 			<argument index="0" name="x" type="int" />
@@ -96,6 +103,13 @@
 			<description>
 			</description>
 		</method>
+		<method name="chunk_load">
+			<return type="TerrainChunk" />
+			<argument index="0" name="x" type="int" />
+			<argument index="1" name="z" type="int" />
+			<description>
+			</description>
+		</method>
 		<method name="chunk_remove">
 			<return type="TerrainChunk" />
 			<argument index="0" name="x" type="int" />
@@ -456,6 +470,8 @@
 		</member>
 		<member name="voxel_structures" type="Array" setter="voxel_structures_set" getter="voxel_structures_get" default="[  ]">
 		</member>
+		<member name="world_chunk_data_manager" type="TerrainWorldChunkDataManager" setter="set_world_chunk_data_manager" getter="get_world_chunk_data_manager">
+		</member>
 		<member name="world_height" type="float" setter="set_world_height" getter="get_world_height" default="256.0">
 		</member>
 	</members>
diff --git a/modules/terraman/world/terrain_world.cpp b/modules/terraman/world/terrain_world.cpp
index f38cdc03a..35ec06d36 100644
--- a/modules/terraman/world/terrain_world.cpp
+++ b/modules/terraman/world/terrain_world.cpp
@@ -42,6 +42,8 @@
 
 #include "../defines.h"
 
+#include "../chunk_data_managers/terrain_world_chunk_data_manager.h"
+
 #include "modules/modules_enabled.gen.h"
 
 #ifdef MODULE_PROPS_ENABLED
@@ -158,6 +160,13 @@ void TerrainWorld::set_level_generator(const Ref<TerrainLevelGenerator> &level_g
 	_level_generator = level_generator;
 }
 
+Ref<TerrainWorldChunkDataManager> TerrainWorld::get_world_chunk_data_manager() const {
+	return _world_chunk_data_manager;
+}
+void TerrainWorld::set_world_chunk_data_manager(const Ref<TerrainWorldChunkDataManager> &p_data_manager) {
+	_world_chunk_data_manager = p_data_manager;
+}
+
 float TerrainWorld::get_voxel_scale() const {
 	return _voxel_scale;
 }
@@ -324,6 +333,10 @@ void TerrainWorld::chunk_add(Ref<TerrainChunk> chunk, const int x, const int z)
 		}
 	}
 
+	if (_world_chunk_data_manager.is_valid()) {
+		_world_chunk_data_manager->on_world_chunk_added(chunk);
+	}
+
 	if (has_method("_chunk_added")) {
 		call("_chunk_added", chunk);
 	}
@@ -381,6 +394,10 @@ Ref<TerrainChunk> TerrainWorld::chunk_remove(const int x, const int z) {
 
 	_chunks.erase(pos);
 
+	if (_world_chunk_data_manager.is_valid()) {
+		_world_chunk_data_manager->on_world_chunk_removed(chunk);
+	}
+
 	emit_signal("chunk_removed", chunk);
 
 	return chunk;
@@ -410,6 +427,10 @@ Ref<TerrainChunk> TerrainWorld::chunk_remove_index(const int index) {
 	//never remove from this here
 	//_generating.erase(chunk);
 
+	if (_world_chunk_data_manager.is_valid()) {
+		_world_chunk_data_manager->on_world_chunk_removed(chunk);
+	}
+
 	emit_signal("chunk_removed", chunk);
 
 	return chunk;
@@ -430,6 +451,10 @@ void TerrainWorld::chunks_clear() {
 
 		chunk->exit_tree();
 
+		if (_world_chunk_data_manager.is_valid()) {
+			_world_chunk_data_manager->on_world_chunk_removed(chunk);
+		}
+
 		emit_signal("chunk_removed", chunk);
 	}
 
@@ -454,8 +479,55 @@ void TerrainWorld::chunks_clear() {
 Ref<TerrainChunk> TerrainWorld::chunk_get_or_create(int x, int z) {
 	Ref<TerrainChunk> chunk = chunk_get(x, z);
 
-	if (!chunk.is_valid()) {
-		chunk = chunk_create(x, z);
+	if (chunk.is_valid()) {
+		return chunk;
+	}
+
+	// Try to load first
+	if (_world_chunk_data_manager.is_valid()) {
+		chunk = _world_chunk_data_manager->load_chunk(Vector2i(x, z));
+
+		if (chunk.is_valid()) {
+			chunk_add(chunk, x, z);
+			return chunk;
+		}
+	}
+
+	chunk = chunk_create(x, z);
+
+	return chunk;
+}
+
+Ref<TerrainChunk> TerrainWorld::chunk_get_or_load(const int x, const int z) {
+	Ref<TerrainChunk> chunk = chunk_get(x, z);
+
+	if (chunk.is_valid()) {
+		return chunk;
+	}
+
+	// Try to load first
+	if (_world_chunk_data_manager.is_valid()) {
+		chunk = _world_chunk_data_manager->load_chunk(Vector2i(x, z));
+
+		if (chunk.is_valid()) {
+			chunk_add(chunk, x, z);
+			return chunk;
+		}
+	}
+
+	return chunk;
+}
+
+Ref<TerrainChunk> TerrainWorld::chunk_load(const int x, const int z) {
+	Ref<TerrainChunk> chunk;
+
+	if (_world_chunk_data_manager.is_valid()) {
+		chunk = _world_chunk_data_manager->load_chunk(Vector2i(x, z));
+
+		if (chunk.is_valid()) {
+			chunk_add(chunk, x, z);
+			return chunk;
+		}
 	}
 
 	return chunk;
@@ -465,6 +537,10 @@ Ref<TerrainChunk> TerrainWorld::chunk_create(const int x, const int z) {
 	Ref<TerrainChunk> c;
 	c = call("_create_chunk", x, z, Ref<TerrainChunk>());
 
+	if (_world_chunk_data_manager.is_valid()) {
+		_world_chunk_data_manager->on_world_chunk_created(c);
+	}
+
 	generation_queue_add_to(c);
 
 	return c;
@@ -1638,6 +1714,10 @@ void TerrainWorld::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_level_generator", "level_generator"), &TerrainWorld::set_level_generator);
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "level_generator", PROPERTY_HINT_RESOURCE_TYPE, "TerrainLevelGenerator"), "set_level_generator", "get_level_generator");
 
+	ClassDB::bind_method(D_METHOD("get_world_chunk_data_manager"), &TerrainWorld::get_world_chunk_data_manager);
+	ClassDB::bind_method(D_METHOD("set_world_chunk_data_manager", "level_generator"), &TerrainWorld::set_world_chunk_data_manager);
+	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_chunk_data_manager", PROPERTY_HINT_RESOURCE_TYPE, "TerrainWorldChunkDataManager"), "set_world_chunk_data_manager", "get_world_chunk_data_manager");
+
 	ClassDB::bind_method(D_METHOD("get_voxel_scale"), &TerrainWorld::get_voxel_scale);
 	ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &TerrainWorld::set_voxel_scale);
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale");
@@ -1714,6 +1794,8 @@ void TerrainWorld::_bind_methods() {
 	BIND_VMETHOD(MethodInfo("_generate_chunk", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "TerrainChunk")));
 
 	ClassDB::bind_method(D_METHOD("chunk_get_or_create", "x", "z"), &TerrainWorld::chunk_get_or_create);
+	ClassDB::bind_method(D_METHOD("chunk_get_or_load", "x", "z"), &TerrainWorld::chunk_get_or_load);
+	ClassDB::bind_method(D_METHOD("chunk_load", "x", "z"), &TerrainWorld::chunk_load);
 	ClassDB::bind_method(D_METHOD("chunk_create", "x", "z"), &TerrainWorld::chunk_create);
 	ClassDB::bind_method(D_METHOD("chunk_setup", "chunk"), &TerrainWorld::chunk_setup);
 
diff --git a/modules/terraman/world/terrain_world.h b/modules/terraman/world/terrain_world.h
index b89dc4475..bb9adb055 100644
--- a/modules/terraman/world/terrain_world.h
+++ b/modules/terraman/world/terrain_world.h
@@ -55,6 +55,7 @@ class TerrainStructure;
 class TerrainChunk;
 class PropData;
 class MeshDataResource;
+class TerrainWorldChunkDataManager;
 
 class TerrainWorld : public Spatial {
 	GDCLASS(TerrainWorld, Spatial);
@@ -108,6 +109,9 @@ public:
 	Ref<TerrainLevelGenerator> get_level_generator() const;
 	void set_level_generator(const Ref<TerrainLevelGenerator> &level_generator);
 
+	Ref<TerrainWorldChunkDataManager> get_world_chunk_data_manager() const;
+	void set_world_chunk_data_manager(const Ref<TerrainWorldChunkDataManager> &p_data_manager);
+
 	float get_voxel_scale() const;
 	void set_voxel_scale(const float value);
 
@@ -158,6 +162,8 @@ public:
 	void chunks_clear();
 
 	Ref<TerrainChunk> chunk_get_or_create(const int x, const int z);
+	Ref<TerrainChunk> chunk_get_or_load(const int x, const int z);
+	Ref<TerrainChunk> chunk_load(const int x, const int z);
 	Ref<TerrainChunk> chunk_create(const int x, const int z);
 	void chunk_setup(Ref<TerrainChunk> chunk);
 
@@ -286,6 +292,7 @@ private:
 
 	Ref<TerrainLibrary> _library;
 	Ref<TerrainLevelGenerator> _level_generator;
+	Ref<TerrainWorldChunkDataManager> _world_chunk_data_manager;
 	float _voxel_scale;
 	int _chunk_spawn_range;