godot/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
Ignacio Roldán Etcheverry 50b603c7dc C#: Begin move to .NET Core
We're targeting .NET 5 for now to make development easier while
.NET 6 is not yet released.

TEMPORARY REGRESSIONS
---------------------

Assembly unloading is not implemented yet. As such, many Godot
resources are leaked at exit. This will be re-implemented later
together with assembly hot-reloading.
2021-09-22 08:27:12 +02:00

68 lines
1.9 KiB
C#

using System;
using System.Runtime.InteropServices;
using Godot.NativeInterop;
namespace Godot
{
public class SignalAwaiter : IAwaiter<object[]>, IAwaitable<object[]>
{
private bool _completed;
private object[] _result;
private Action _action;
public SignalAwaiter(Object source, StringName signal, Object target)
{
NativeFuncs.godotsharp_internal_signal_awaiter_connect(Object.GetPtr(source), ref signal.NativeValue,
Object.GetPtr(target), GCHandle.ToIntPtr(GCHandle.Alloc(this)));
}
public bool IsCompleted => _completed;
public void OnCompleted(Action action)
{
this._action = action;
}
public object[] GetResult() => _result;
public IAwaiter<object[]> GetAwaiter() => this;
[UnmanagedCallersOnly]
internal static unsafe void SignalCallback(IntPtr awaiterGCHandlePtr, godot_variant** args, int argCount,
godot_bool* outAwaiterIsNull)
{
try
{
var awaiter = (SignalAwaiter)GCHandle.FromIntPtr(awaiterGCHandlePtr).Target;
if (awaiter == null)
{
*outAwaiterIsNull = true.ToGodotBool();
return;
}
*outAwaiterIsNull = false.ToGodotBool();
awaiter._completed = true;
object[] signalArgs = new object[argCount];
for (int i = 0; i < argCount; i++)
signalArgs[i] = Marshaling.variant_to_mono_object(args[i]);
awaiter._result = signalArgs;
if (awaiter._action != null)
{
awaiter._action();
}
}
catch (Exception e)
{
ExceptionUtils.DebugPrintUnhandledException(e);
*outAwaiterIsNull = false.ToGodotBool();
}
}
}
}