1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- namespace Godot
- {
- public class GodotTaskScheduler : TaskScheduler
- {
- private GodotSynchronizationContext Context { get; set; }
- private readonly LinkedList<Task> _tasks = new LinkedList<Task>();
- public GodotTaskScheduler()
- {
- Context = new GodotSynchronizationContext();
- SynchronizationContext.SetSynchronizationContext(Context);
- }
- protected sealed override void QueueTask(Task task)
- {
- lock (_tasks)
- {
- _tasks.AddLast(task);
- }
- }
- protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
- {
- if (SynchronizationContext.Current != Context)
- {
- return false;
- }
- if (taskWasPreviouslyQueued)
- {
- TryDequeue(task);
- }
- return TryExecuteTask(task);
- }
- protected sealed override bool TryDequeue(Task task)
- {
- lock (_tasks)
- {
- return _tasks.Remove(task);
- }
- }
- protected sealed override IEnumerable<Task> GetScheduledTasks()
- {
- lock (_tasks)
- {
- return _tasks.ToArray();
- }
- }
- public void Activate()
- {
- ExecuteQueuedTasks();
- Context.ExecutePendingContinuations();
- }
- private void ExecuteQueuedTasks()
- {
- while (true)
- {
- Task task;
- lock (_tasks)
- {
- if (_tasks.Any())
- {
- task = _tasks.First.Value;
- _tasks.RemoveFirst();
- }
- else
- {
- break;
- }
- }
- if (task != null)
- {
- if (!TryExecuteTask(task))
- {
- throw new InvalidOperationException();
- }
- }
- }
- }
- }
- }
|