godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

(C# Godot 3.5) Cross Language Scripting should allow awaiting #5709

Closed jarommadsen closed 2 years ago

jarommadsen commented 2 years ago

Describe the project you are working on

A Gotm.io asynchronous multiplayer game.

Describe the problem or limitation you are having in your project

I'm attempting to use Gotm's plugin that's entirely written in GDScript. I have very little interest in working in a untyped language. The API is composed entirely of web calls meaning they're basically all asynchronous.

The only feasible path I can see is to attempt to use Cross-language scripting. However, Godot.Object.Call only returns an object and provides no way to await the function to know if it's actually completed.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Provide an alternative method that supports await or return a more helpful result type that can be awaited.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Something like Godot.Object.AsyncCall or YieldCall.

GDScript MyGDScript = (GDScript) GD.Load("res://path_to_gd_file.gd");
Object myGDScriptNode = (Godot.Object) MyGDScript.New();
await myGDScriptNode.AsyncCall("async_method", this);
// Do stuff that's dependent on `async_method` finishing first

If this enhancement will not be used often, can it be worked around with a few lines of script?

AFAIK it can not be worked around if the GDScript method needs yielded/awaited.

Is there a reason why this should be core and not an add-on in the asset library?

Asynchronous functions are a fundamental concept and should be part of the cross-language scripting support.

jarommadsen commented 2 years ago

I thought I'd already tried this but casting the result object from Call to Godot.Object allows me to await the ToSignal(result, 'completed').

GDScript MyGDScript = (GDScript) GD.Load("res://path_to_gd_file.gd");
Object myGDScriptNode = (Godot.Object) MyGDScript.New();
var result = (Godot.Object) myGDScriptNode.Call("async_method");
await ToSignal(result, "completed");
Zireael07 commented 2 years ago

This should probably be documented in the cross-language documentation page.

Calinou commented 2 years ago

Feel free to open a pull request on https://github.com/godotengine/godot-docs for this :slightly_smiling_face:

If this is relevant for 4.0, open a pull request against the master branch. If this is not relevant for 4.0, make sure to open it on the 3.6 branch of the docs, as it can be cherry-picked to 3.5 and stable this way.