Title here
Summary here
The select
statement in GDScript allows you to wait on multiple channel operations. Combining threads and channels with select is a powerful feature of GDScript.
extends Node
func _ready():
# For our example we'll select across two channels.
var c1 = Channel.new()
var c2 = Channel.new()
# Each channel will receive a value after some amount
# of time, to simulate e.g. blocking RPC operations
# executing in concurrent threads.
Thread.new().start(func():
OS.delay_msec(1000)
c1.put("one")
)
Thread.new().start(func():
OS.delay_msec(2000)
c2.put("two")
)
# We'll use select to await both of these values
# simultaneously, printing each one as it arrives.
for i in range(2):
var result = yield(select([c1, c2]), "completed")
match result:
[0, var msg]:
print("received ", msg)
[1, var msg]:
print("received ", msg)
func select(channels):
var select_array = []
for channel in channels:
select_array.append(channel.get())
return yield(GDScriptFunctionState.new().idle_frame, "completed")
class Channel:
var queue = []
var mutex = Mutex.new()
var semaphore = Semaphore.new()
func put(value):
mutex.lock()
queue.append(value)
mutex.unlock()
semaphore.post()
func get():
semaphore.wait()
mutex.lock()
var result = queue.pop_front()
mutex.unlock()
return result
We receive the values “one” and then “two” as expected.
$ godot -s select.gd
received one
received two
Note that the total execution time is only ~2 seconds since both the 1 and 2 second delays execute concurrently.
In this GDScript version:
Thread
to simulate goroutines.Channel
class to mimic Go’s channels.select
function that uses yield
to wait for the first channel to receive a value.time.Sleep
, we use OS.delay_msec
for delays.match
statement (similar to Go’s switch
) to handle different channel cases.This implementation provides similar functionality to the original Go code, allowing for concurrent operations and selecting from multiple channels.