Skip to content

Commit 05fdf48

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 0826b7e + 647ed6f commit 05fdf48

File tree

6 files changed

+484
-4
lines changed

6 files changed

+484
-4
lines changed

.github/workflows/build-debug.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ jobs:
8181

8282
# Store artifacts.
8383
- uses: Cysharp/Actions/.github/actions/upload-artifact@main
84+
if: ${{ startsWith(matrix.unity, '2021') }} # only execute 2021
8485
with:
8586
name: UniTask.unitypackage-${{ matrix.unity }}.zip
8687
path: ./src/UniTask/*.unitypackage

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,9 @@ It indicates when to run, you can check [PlayerLoopList.md](https://gist.github.
526526

527527
In UniTask, await directly uses native timing, while `WithCancellation` and `ToUniTask` use specified timing. This is usually not a particular problem, but with `LoadSceneAsync`, it causes a different order of Start and continuation after await. So it is recommended not to use `LoadSceneAsync.ToUniTask`.
528528

529+
> Note: When using Unity 2023.1 or newer, ensure you have `using UnityEngine;` in the using statements of your file when working with new `UnityEngine.Awaitable` methods like `SceneManager.LoadSceneAsync`.
530+
> This prevents compilation errors by avoiding the use of the `UnityEngine.AsyncOperation` version.
531+
529532
In the stacktrace, you can check where it is running in playerloop.
530533

531534
![image](https://user-images.githubusercontent.com/46207/83735571-83caea80-a68b-11ea-8d22-5e22864f0d24.png)

src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Factory.cs

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,78 @@ public static UnityEngine.Events.UnityAction UnityAction<T>(T state, Func<T, Uni
184184
return () => asyncAction(state).Forget();
185185
}
186186

187+
/// <summary>
188+
/// Create async void(UniTaskVoid) UnityAction.
189+
/// For example: onClick.AddListener(UniTask.UnityAction(async (T arg) => { /* */ } ))
190+
/// </summary>
191+
public static UnityEngine.Events.UnityAction<T> UnityAction<T>(Func<T, UniTaskVoid> asyncAction)
192+
{
193+
return (arg) => asyncAction(arg).Forget();
194+
}
195+
196+
/// <summary>
197+
/// Create async void(UniTaskVoid) UnityAction.
198+
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1) => { /* */ } ))
199+
/// </summary>
200+
public static UnityEngine.Events.UnityAction<T0, T1> UnityAction<T0, T1>(Func<T0, T1, UniTaskVoid> asyncAction)
201+
{
202+
return (arg0, arg1) => asyncAction(arg0, arg1).Forget();
203+
}
204+
205+
/// <summary>
206+
/// Create async void(UniTaskVoid) UnityAction.
207+
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, T2 arg2) => { /* */ } ))
208+
/// </summary>
209+
public static UnityEngine.Events.UnityAction<T0, T1, T2> UnityAction<T0, T1, T2>(Func<T0, T1, T2, UniTaskVoid> asyncAction)
210+
{
211+
return (arg0, arg1, arg2) => asyncAction(arg0, arg1, arg2).Forget();
212+
}
213+
214+
/// <summary>
215+
/// Create async void(UniTaskVoid) UnityAction.
216+
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, T2 arg2, T3 arg3) => { /* */ } ))
217+
/// </summary>
218+
public static UnityEngine.Events.UnityAction<T0, T1, T2, T3> UnityAction<T0, T1, T2, T3>(Func<T0, T1, T2, T3, UniTaskVoid> asyncAction)
219+
{
220+
return (arg0, arg1, arg2, arg3) => asyncAction(arg0, arg1, arg2, arg3).Forget();
221+
}
222+
223+
// <summary>
224+
/// Create async void(UniTaskVoid) UnityAction.
225+
/// For example: onClick.AddListener(UniTask.UnityAction(async (T arg, CancellationToken cancellationToken) => { /* */ } ))
226+
/// </summary>
227+
public static UnityEngine.Events.UnityAction<T> UnityAction<T>(Func<T, CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
228+
{
229+
return (arg) => asyncAction(arg, cancellationToken).Forget();
230+
}
231+
232+
/// <summary>
233+
/// Create async void(UniTaskVoid) UnityAction.
234+
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, CancellationToken cancellationToken) => { /* */ } ))
235+
/// </summary>
236+
public static UnityEngine.Events.UnityAction<T0, T1> UnityAction<T0, T1>(Func<T0, T1, CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
237+
{
238+
return (arg0, arg1) => asyncAction(arg0, arg1, cancellationToken).Forget();
239+
}
240+
241+
/// <summary>
242+
/// Create async void(UniTaskVoid) UnityAction.
243+
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, T2 arg2, CancellationToken cancellationToken) => { /* */ } ))
244+
/// </summary>
245+
public static UnityEngine.Events.UnityAction<T0, T1, T2> UnityAction<T0, T1, T2>(Func<T0, T1, T2, CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
246+
{
247+
return (arg0, arg1, arg2) => asyncAction(arg0, arg1, arg2, cancellationToken).Forget();
248+
}
249+
250+
/// <summary>
251+
/// Create async void(UniTaskVoid) UnityAction.
252+
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, T2 arg2, T3 arg3, CancellationToken cancellationToken) => { /* */ } ))
253+
/// </summary>
254+
public static UnityEngine.Events.UnityAction<T0, T1, T2, T3> UnityAction<T0, T1, T2, T3>(Func<T0, T1, T2, T3, CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
255+
{
256+
return (arg0, arg1, arg2, arg3) => asyncAction(arg0, arg1, arg2, arg3, cancellationToken).Forget();
257+
}
258+
187259
#endif
188260

189261
/// <summary>
@@ -202,6 +274,22 @@ public static UniTask<T> Defer<T>(Func<UniTask<T>> factory)
202274
return new UniTask<T>(new DeferPromise<T>(factory), 0);
203275
}
204276

277+
/// <summary>
278+
/// Defer the task creation just before call await.
279+
/// </summary>
280+
public static UniTask Defer<TState>(TState state, Func<TState, UniTask> factory)
281+
{
282+
return new UniTask(new DeferPromiseWithState<TState>(state, factory), 0);
283+
}
284+
285+
/// <summary>
286+
/// Defer the task creation just before call await.
287+
/// </summary>
288+
public static UniTask<TResult> Defer<TState, TResult>(TState state, Func<TState, UniTask<TResult>> factory)
289+
{
290+
return new UniTask<TResult>(new DeferPromiseWithState<TState, TResult>(state, factory), 0);
291+
}
292+
205293
/// <summary>
206294
/// Never complete.
207295
/// </summary>
@@ -465,6 +553,93 @@ public UniTaskStatus UnsafeGetStatus()
465553
}
466554
}
467555

556+
sealed class DeferPromiseWithState<TState> : IUniTaskSource
557+
{
558+
Func<TState, UniTask> factory;
559+
TState argument;
560+
UniTask task;
561+
UniTask.Awaiter awaiter;
562+
563+
public DeferPromiseWithState(TState argument, Func<TState, UniTask> factory)
564+
{
565+
this.argument = argument;
566+
this.factory = factory;
567+
}
568+
569+
public void GetResult(short token)
570+
{
571+
awaiter.GetResult();
572+
}
573+
574+
public UniTaskStatus GetStatus(short token)
575+
{
576+
var f = Interlocked.Exchange(ref factory, null);
577+
if (f != null)
578+
{
579+
task = f(argument);
580+
awaiter = task.GetAwaiter();
581+
}
582+
583+
return task.Status;
584+
}
585+
586+
public void OnCompleted(Action<object> continuation, object state, short token)
587+
{
588+
awaiter.SourceOnCompleted(continuation, state);
589+
}
590+
591+
public UniTaskStatus UnsafeGetStatus()
592+
{
593+
return task.Status;
594+
}
595+
}
596+
597+
sealed class DeferPromiseWithState<TState, TResult> : IUniTaskSource<TResult>
598+
{
599+
Func<TState, UniTask<TResult>> factory;
600+
TState argument;
601+
UniTask<TResult> task;
602+
UniTask<TResult>.Awaiter awaiter;
603+
604+
public DeferPromiseWithState(TState argument, Func<TState, UniTask<TResult>> factory)
605+
{
606+
this.argument = argument;
607+
this.factory = factory;
608+
}
609+
610+
public TResult GetResult(short token)
611+
{
612+
return awaiter.GetResult();
613+
}
614+
615+
void IUniTaskSource.GetResult(short token)
616+
{
617+
awaiter.GetResult();
618+
}
619+
620+
public UniTaskStatus GetStatus(short token)
621+
{
622+
var f = Interlocked.Exchange(ref factory, null);
623+
if (f != null)
624+
{
625+
task = f(argument);
626+
awaiter = task.GetAwaiter();
627+
}
628+
629+
return task.Status;
630+
}
631+
632+
public void OnCompleted(Action<object> continuation, object state, short token)
633+
{
634+
awaiter.SourceOnCompleted(continuation, state);
635+
}
636+
637+
public UniTaskStatus UnsafeGetStatus()
638+
{
639+
return task.Status;
640+
}
641+
}
642+
468643
sealed class NeverPromise<T> : IUniTaskSource<T>
469644
{
470645
static readonly Action<object> cancellationCallback = CancellationCallback;

0 commit comments

Comments
 (0)