Skip to content

Commit

Permalink
Merge pull request #619 from kochounoyume/add-state-argument
Browse files Browse the repository at this point in the history
Add overload in UniTask.WaitUntil, UniTask.WaitWhile and UniTask.Defer
  • Loading branch information
neuecc authored Sep 26, 2024
2 parents 83d8a2b + 06283f0 commit 6f41315
Show file tree
Hide file tree
Showing 3 changed files with 407 additions and 3 deletions.
103 changes: 103 additions & 0 deletions src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Factory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,22 @@ public static UniTask<T> Defer<T>(Func<UniTask<T>> factory)
return new UniTask<T>(new DeferPromise<T>(factory), 0);
}

/// <summary>
/// Defer the task creation just before call await.
/// </summary>
public static UniTask Defer<TState>(TState state, Func<TState, UniTask> factory)
{
return new UniTask(new DeferPromiseWithState<TState>(state, factory), 0);
}

/// <summary>
/// Defer the task creation just before call await.
/// </summary>
public static UniTask<TResult> Defer<TState, TResult>(TState state, Func<TState, UniTask<TResult>> factory)
{
return new UniTask<TResult>(new DeferPromiseWithState<TState, TResult>(state, factory), 0);
}

/// <summary>
/// Never complete.
/// </summary>
Expand Down Expand Up @@ -465,6 +481,93 @@ public UniTaskStatus UnsafeGetStatus()
}
}

sealed class DeferPromiseWithState<TState> : IUniTaskSource
{
Func<TState, UniTask> factory;
TState argument;
UniTask task;
UniTask.Awaiter awaiter;

public DeferPromiseWithState(TState argument, Func<TState, UniTask> factory)
{
this.argument = argument;
this.factory = factory;
}

public void GetResult(short token)
{
awaiter.GetResult();
}

public UniTaskStatus GetStatus(short token)
{
var f = Interlocked.Exchange(ref factory, null);
if (f != null)
{
task = f(argument);
awaiter = task.GetAwaiter();
}

return task.Status;
}

public void OnCompleted(Action<object> continuation, object state, short token)
{
awaiter.SourceOnCompleted(continuation, state);
}

public UniTaskStatus UnsafeGetStatus()
{
return task.Status;
}
}

sealed class DeferPromiseWithState<TState, TResult> : IUniTaskSource<TResult>
{
Func<TState, UniTask<TResult>> factory;
TState argument;
UniTask<TResult> task;
UniTask<TResult>.Awaiter awaiter;

public DeferPromiseWithState(TState argument, Func<TState, UniTask<TResult>> factory)
{
this.argument = argument;
this.factory = factory;
}

public TResult GetResult(short token)
{
return awaiter.GetResult();
}

void IUniTaskSource.GetResult(short token)
{
awaiter.GetResult();
}

public UniTaskStatus GetStatus(short token)
{
var f = Interlocked.Exchange(ref factory, null);
if (f != null)
{
task = f(argument);
awaiter = task.GetAwaiter();
}

return task.Status;
}

public void OnCompleted(Action<object> continuation, object state, short token)
{
awaiter.SourceOnCompleted(continuation, state);
}

public UniTaskStatus UnsafeGetStatus()
{
return task.Status;
}
}

sealed class NeverPromise<T> : IUniTaskSource<T>
{
static readonly Action<object> cancellationCallback = CancellationCallback;
Expand Down
Loading

0 comments on commit 6f41315

Please sign in to comment.