Depending on your purpose, you may find it easier to use yield than Thread, since you don't need a synchronization object.
In this case, you want to use Thread, so let's use Thread.
I have reworked your code.
extends Spatial
signal complete_thread
signal complete_one_job
const CHUNK_SIZE := 10
const RADIUS := 5
var thread: Thread
class CChunkParam:
var chunk_size: int
var radius: int
func _init(_chunk_size: int, _radius: int):
self.chunk_size = _chunk_size
self.radius = _radius
func _ready():
connect("complete_thread", self, "_on_complete_thread")
connect("complete_one_job", self, "_on_complete_one_job")
thread = Thread.new()
thread.start(
self,
"_generate_chunk",
CChunkParam.new(CHUNK_SIZE, RADIUS)
)
func _process(_delta):
pass
func _on_complete_one_job(chunk: MeshInstance):
print_debug("signal: complete_one_job")
add_child(chunk)
func _on_complete_thread():
print_debug("signal: complete_thread")
func _exit_tree():
disconnect("complete_one_job", self, "_on_complete_one_job")
disconnect("complete_thread", self, "_on_complete_thread")
thread.wait_to_finish()
func _generate_chunk(param: CChunkParam):
for x in range(-param.radius, param.radius + 1):
for y in range(-param.radius, param.radius + 1):
var chunk = MeshInstance.new()
chunk.mesh = PlaneMesh.new()
chunk.mesh.size = Vector2.ONE * param.chunk_size
chunk.translation = Vector3(x, 0, y) * param.chunk_size
emit_signal("complete_one_job", chunk)
emit_signal("complete_thread")
It is not efficient to call it every time in process, so I changed it to call it only once in ready.