0 votes

Exactly like the title says. I create a thread, it runs one time and the waittofinish function does not work. this is my entire code:


extends Spatial var objects = 0
var block = load("res://Scenes/Blocks/Block.tscn")
var chunks = []
var generator_thread = Thread.new() onready var gridmap = $GridMap
onready var player = $Player export var generatorseed = int()
export var generator
heightamplifier = int()
export var chunk
size = int() func ready():
generator
thread.start(self, "generatechunk", [generatorseed, chunksize, Vector2(0, 0)])
generator
thread.waittofinish() func process(delta):
$Label.text = String(Engine.get
framespersecond()) + "\n" + String(objects)
print(generatorthread.isactive())
var pos = player.globaltransform.origin
pos = gridmap.world
tomap(pos)
pos = pos / chunk
size
pos = Vector2(floor(pos.x), floor(pos.z))
for x in range(pos.x - 3, pos.y + 3):
for y in range(pos.y - 3, pos.y + 3):
if not(generatorthread.isactive()):
generatorthread = Thread.new()
generator
thread.start(self, "generatechunk", [generatorseed, chunk_size, Vector2(x, y)]) func generatechunk(data):
var gen
seed = data[0]
var size = data[1]
var place = data[2]
if place in chunks:
return
chunks.append(place)
place = place * size
var noise = OpenSimplexNoise.new()
noise.seed = gen_seed
var cells = [] for x in range(place.x - size, place.x + size): for z in range(place.y - size, place.y + size): for y in range(0, noise.get_noise_2d(x, z) * generator_height_amplifier + generator_height_amplifier): cells.append(Vector3(x, y, z)) yield(get_tree(), "idle_frame") for cell in cells: gridmap.set_cell_item(cell.x, cell.y, cell.z, 0) yield(get_tree(), "idle_frame") call_deferred("generate_done") func generate_done(): generator_thread.wait_to_finish()

I don't know almost anything about threads, this is the first time I used them in godot, so please explain in noob terms.

Godot version 3.2.3
in Engine by (25 points)

1 Answer

+1 vote
Best answer

In the native noob language huh, i'm a bit rusty but will try.

The way i see it you're calling the wait_to_finish() function inside of the generator_thread essentially giving it more work to do.

Also having the wait_to_finish() function called in the _ready() function just after starting it is a bad idea because you're basically not giving it a chance to do its thing.

Solution
Try using a timer to do your dirty work.

var thread_timer = Timer.new()

in the _ready() function connect the timer to your thread cleanup function

call("connect", "timeout", self, "generate_done")

at the end of your thread start the timer

thread_timer.start()

It's a good idea to also return something at the end of none interactive threads for e.g return OK to verify things went accordingly.

if wait_to_finish() == OK:
    print("thread successful")
by (3,282 points)
selected by

Thanks, it worked!

Please know that what i've said above is a super simplification of what's actually happening and that you should delve deeper into how threads are managed.

You were trying to join and end the thread upon itself and the reason the timer works is because its functionality executes on the main thread.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.