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;
}
}