using System; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace Chartboost { /// For referencing generically public interface ILater { } /// Read-only interface for a standard public interface ILater : ILater { event Action OnComplete; TaskAwaiter GetAwaiter(); } /// Basic Later for passing a single type to callbacks and awaiters public class Later : BaseLater { public void Complete(TResult result) => _complete(result); } /// Separated implementation so the derivations can offer different methods for completion public abstract class BaseLater : ILater { public event Action OnComplete { remove => DidComplete -= value; add { if (_isComplete) DidComplete += value; else value?.Invoke(_result); } } public TaskAwaiter GetAwaiter() { if (_completionSource != null) return _completionSource.Task.GetAwaiter(); _completionSource = new TaskCompletionSource(); if (_isComplete) _completionSource.TrySetResult(_result); else DidComplete += result => _completionSource.TrySetResult(result); return _completionSource.Task.GetAwaiter(); } protected void _complete(TResult result) { if (_isComplete) return; _result = result; var toComplete = DidComplete; DidComplete = null; _isComplete = true; toComplete?.Invoke(_result); } private TaskCompletionSource _completionSource; private event Action DidComplete; private bool _isComplete; private TResult _result; } }