-
To avoid xy problem: I was thinking about leveraging gd for writing code where Go shines and Godot is bad at (networking, HTTP requests, IPC, etc.). My idea was to do a bunch of work on the Go side and communicate the results asynchronously to the Godot via signals. I modified the example to call signal from goroutine: type HelloWorld struct {
classdb.Extension[HelloWorld, SceneTree.Instance]
something chan<- struct{}
}
func (h *HelloWorld) DoSomething() {
go func() {
time.Sleep(time.Second * 5)
h.something <- struct{}{}
}()
} func _ready():
var a = HelloWorld.new()
a.connect("something", handle_sig)
a.DoSomething()
func handle_sig():
print("yay") It results in crash though:
I assume the bindings are not thread safe? Is it possible to use signals like this? Or perhaps should I use other method (pooling from the Godot side?) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Thanks for reporting this use case, as you've mentioned, it makes perfect sense to use Go in this way. There are some issues here, the What I'm going to do, is add a representation for this using channels. If you add a write only channel field to your class. This will be registered as a signal available in Godot. Then you can send to this from a goroutine. I would avoid calling any I'll close this issue once I've implemented the following, which I will be working on today. type HelloWorld struct {
classdb.Extension[HelloWorld, SceneTree.Instance]
Something chan<- struct{} `gd:"something"`
}
func (h *HelloWorld) DoSomething() {
go func() {
time.Sleep(time.Second * 5)
h.Something <- struct{}{}
}()
} |
Beta Was this translation helpful? Give feedback.
Thanks for reporting this use case, as you've mentioned, it makes perfect sense to use Go in this way.
There are some issues here, the
Something
field needs to be exported, you can tag it asgd:"something"
. This should fix the panic. There's still the possibility of race conditions here. On the Godot side,Emit
isn't necessarily thread 'safe'. So to do this safely, the signal needs to be emitted through a deferred call that runs on the main thread.What I'm going to do, is add a representation for this using channels. If you add a write only channel field to your class. This will be registered as a signal available in Godot. Then you can send to this from a goroutine.
I would avoid callin…