Skip to content

Sending Godot Objects across threads #150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
TitanNano opened this issue Mar 6, 2023 · 6 comments
Closed

Sending Godot Objects across threads #150

TitanNano opened this issue Mar 6, 2023 · 6 comments
Labels
status: duplicate This issue or pull request already exists

Comments

@TitanNano
Copy link
Contributor

In gdnative it was possible to send engine objects across threads depending on the associated ownership. In gdextension on the other hand, it is currently not possible to move objects between threads. From the current implementation, it looks like all godot classes have deliberately been made !Send.

Are there already plans to provide a similar mechanic as in gdnative? I would really need to send objects across threads, especially ones that I have constructed in my own code and have exclusive access to.

@Bromeon
Copy link
Member

Bromeon commented Mar 6, 2023

Yes, this is planned in #18 🙂

Unlike the GDNative binding, I would like to take a slightly different approach, allowing safe use where possible. This has of course some caveats, and can likely not be done for most Godot types, as they're not thread-safe.

Later I will close this issue as a duplicate, but I would appreciate if you could elaborate your use case a bit! You mentioned objects that you constructed in your own code?

@Bromeon Bromeon added the status: duplicate This issue or pull request already exists label Mar 6, 2023
@TitanNano
Copy link
Contributor Author

TitanNano commented Mar 6, 2023

My current use case is the following:
I have a rust module that constructs the level terrain with the help of Godots SurfaceTool. To speed things up, the entire terrain is split up into chunks and each chunk is being built in parallel utilizing rayon. The chunk generation results in a ArrayMesh that has to be sent back to the main thread.

So far, I was able to port the module from gdnative to gdextension without many issues even with the currently experimental state of the library. The only thing blocking me from completing the port is not being able to send the ArrayMeshes back to the main thread.

@Bromeon
Copy link
Member

Bromeon commented Mar 6, 2023

Thanks for elaborating!

I don't think it will be possible to send Gd<ArrayMesh> to another thread in safe Rust. When the old thread keeps a reference, we may run into race conditions, because ArrayMesh (like most Godot classes) is not thread-safe on its own. And having only Send but not Sync will also not work, because it's very easy to create a new reference using Gd::share() in the old thread.

Probably, this would need something like Arc<UniqueGd<ArrayMesh>>, with UniqueGd ensuring there is no other reference to it. This would be similar to GDNative's Ref<T, Unique> and would possibly require an unsafe Gd::assume_unique() or something.


If you're currently blocked by this, you can always cheat and route the object through GDScript, either with method calls, or by storing it in a certain position of the scene tree (in the old thread) and accessing it there (in the new thread). This is still thread-unsafe, but outside godot-rust's safety responsibility.

@TitanNano
Copy link
Contributor Author

After attempting to work around my issue via some GDScript resource, I noticed that I'm taking all my input as Godot Dictionaries. Dictionaries were Send in GDNative but are currently not in gdextension. So, I'm now contemplating if I want to convert these dictionaries into "safe" Rust structs or if I want to wait for development of the gdextension lib to progress. 😅

@Bromeon
Copy link
Member

Bromeon commented Mar 7, 2023

Dictionaries may be Send in gdnative, but that doesn't make them thread-safe. You need unsafe to access them.

@Bromeon
Copy link
Member

Bromeon commented Mar 12, 2023

Closing in favor of #18.

@Bromeon Bromeon closed this as not planned Won't fix, can't repro, duplicate, stale Mar 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants