diff options
author | Caleb Kemper <kemper.caleb@gmail.com> | 2023-02-11 01:30:25 -0700 |
---|---|---|
committer | Caleb Kemper <kemper.caleb@gmail.com> | 2023-02-12 14:12:09 -0700 |
commit | 103cb4bee6bdcfe793bddab6a7adf960af1f3aad (patch) | |
tree | 39617fc94f52cbcda7f2651f11811b7a6b0a88db /modules | |
parent | 929ee61170ec4d431d6d2cfeddccdec2a59a11b7 (diff) |
Implement GodotSynchronizationContext.Send
Diffstat (limited to 'modules')
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs index 027eab30fc..79030c79cc 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs @@ -1,17 +1,44 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Threading; +using System.Threading.Tasks; namespace Godot { public sealed class GodotSynchronizationContext : SynchronizationContext, IDisposable { - private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue = new(); + private readonly BlockingCollection<(SendOrPostCallback Callback, object State)> _queue = new(); + + public override void Send(SendOrPostCallback d, object state) + { + // Shortcut if we're already on this context + // Also necessary to avoid a deadlock, since Send is blocking + if (Current == this) + { + d(state); + return; + } + + var source = new TaskCompletionSource(); + + _queue.Add((st => + { + try + { + d(st); + } + finally + { + source.SetResult(); + } + }, state)); + + source.Task.Wait(); + } public override void Post(SendOrPostCallback d, object state) { - _queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state)); + _queue.Add((d, state)); } /// <summary> @@ -21,7 +48,7 @@ namespace Godot { while (_queue.TryTake(out var workItem)) { - workItem.Key(workItem.Value); + workItem.Callback(workItem.State); } } |