From d19f885ad9b733b8d8ee3484c164dce611ebe3cd Mon Sep 17 00:00:00 2001 From: teneko Date: Sun, 6 Oct 2024 11:08:41 +0100 Subject: [PATCH] feat!: renamed YieldReturn to YieldAssign and moved Yielders.Yield to Coroutine.Yield BREAKING CHANGE: To better reflect that you "replace" the coroutine result of a yielder the name YieldReturn has been renamed to YieldAssign. Also moved Yielders.Yield to Coroutine.Yield to align with Task.Yield. --- README.md | 133 ++++++++++++++---- samples/Playground/Playground.csproj | 3 +- samples/Playground/Program.cs | 19 ++- .../Coroutines/Coroutine.Yield.cs | 14 ++ .../Coroutines/Iterators/AsyncIterator.T.cs | 4 +- .../Coroutines/Iterators/AsyncIterator.cs | 4 +- .../Coroutines/Iterators/AsyncIteratorImpl.cs | 4 +- .../Coroutines/Iterators/IAsyncIterator.T.cs | 4 +- .../Coroutines/Iterators/IAsyncIterator.cs | 4 +- .../Coroutines/Yielders.Yield.cs | 8 -- ...eldReturn.T.cs => Yielders.YieldAssign.cs} | 22 +-- src/Tenekon.Coroutines/Coroutines/Yielders.cs | 2 +- ...T.cs => AsyncIteratorTests.YieldAssign.cs} | 6 +- .../Iterators/AsyncIteratorTests.cs | 4 +- ...Assembly_HasApprovedPublicApi.verified.txt | 22 +-- 15 files changed, 164 insertions(+), 89 deletions(-) create mode 100644 src/Tenekon.Coroutines/Coroutines/Coroutine.Yield.cs rename src/Tenekon.Coroutines/Coroutines/{Yielders.YieldReturn.T.cs => Yielders.YieldAssign.cs} (69%) rename test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/{AsyncIteratorTests.YieldReturn.T.cs => AsyncIteratorTests.YieldAssign.cs} (89%) diff --git a/README.md b/README.md index b66bfa3..9c8f602 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ dotnet add package Tenekon.Coroutines --version ## Quick start guide -**Simple Coroutine** +**Simple Coroutine: Hello World** ```csharp using static Tenekon.Coroutines.Yielders; @@ -53,7 +53,31 @@ await Func(async () => { // Hello world ``` -**Simple AsyncIterator** +**Advanced Coroutine: Parallelism** + +```csharp +await Coroutine.Start(async () => +{ + var t1 = await Coroutine.Factory.StartNew(new Func(async () => + { + Thread.Sleep(3000); + Console.WriteLine(DateTime.UtcNow - Process.GetCurrentProcess().StartTime.ToUniversalTime() + ": Finished"); + })); + + var t2 = await Coroutine.Factory.StartNew(new Func(async () => + { + Thread.Sleep(3000); + Console.WriteLine(DateTime.UtcNow - Process.GetCurrentProcess().StartTime.ToUniversalTime() + ": Finished"); + })); + + await Task.WhenAll(t1.AsTask(), t2.AsTask()); +}); + +// 00:00:03.0317613: Finished +// 00:00:03.0317757: Finished +``` + +**Simple AsyncIterator: Iterator** ```csharp using static Tenekon.Coroutines.Yielders; @@ -64,16 +88,15 @@ var iterator = AsyncIterator.Create(async () => { }); while (await iterator.MoveNextAsync()) { - if (iterator.CurrentKey == CallKey) { - Console.WriteLine(((CallArgument)iterator.Current).Closure); - } + Console.WriteLine(((CallArgument)iterator.Current).Closure); } // Outputs: // Hello world +// Hello world ``` -**Advanced AsyncIterator** +**Advanced AsyncIterator: Iterator, Replace Current** ```csharp using static Tenekon.Coroutines.Yielders; @@ -84,10 +107,8 @@ var iterator = AsyncIterator.Create(async () => { }); while (await iterator.MoveNextAsync()) { - if (iterator.CurrentKey == CallKey) { - Console.WriteLine(((CallArgument)iterator.Current).Closure); - iterator.Current = new CallArgument(Console.WriteLine, "Hello iterator") - } + Console.WriteLine(((CallArgument)iterator.Current).Closure); + iterator.Current = new CallArgument(Console.WriteLine, "Hello iterator") } // Outputs: @@ -95,7 +116,7 @@ while (await iterator.MoveNextAsync()) { // Hello iterator ``` -**Advanced AsyncIterator** +**Advanced AsyncIterator: Iterator, Yield Assign** ```csharp using static Tenekon.Coroutines.Iterator.Yielders; @@ -106,10 +127,8 @@ var iterator = AsyncIterator.Create(async () => { }); while (await iterator.MoveNextAsync()) { - if (iterator.CurrentKey == ExchangeKey) { - Console.WriteLine(((ExchangeArgument)iterator.Current).Value); - iterator.YieldReturn("Hello iterator"); - } + Console.WriteLine(((ExchangeArgument)iterator.Current).Value); + iterator.YieldAssign("Hello iterator"); } // Outputs: @@ -123,11 +142,61 @@ Yielders are the equivalent to effects in Redux-Saga. In the following are all available `Yielders` classes and their contained yielders listed. -We recommend to make use of `using static`, e.g. `using static Tenekon.Coroutines.Yielders`. +### Tenekon.Coroutines.Coroutine + +The yielding components of `Coroutine` are designed to align with the functionality of `Task`. + +#### Tenekon.Coroutines.Coroutine.Yield + +Use `Yield` to instruct the coroutine to suspend and resume immediatelly. In the underlying code, `Task.Yield()` is used. + +| Yielder | Signature | +| ------- | ----------------------------- | +| `Yield` | `Coroutine Coroutine Yield()` | + +#### Tenekon.Coroutines.Coroutine.Run + +The `Coroutine.Run` yielder is the equivalent to `Task.Run` + +| Yielder | Signature | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Coroutine.Run` | `Coroutine Run(Func provider, CancellationToken cancellationToken)` | +| `Coroutine.Run` | `Coroutine Run(Func provider)` | +| `Coroutine.Run` | `Coroutine Run(Func provider, TClosure closure, CancellationToken cancellationToken)` | +| `Coroutine.Run` | `Coroutine Run(Func provider, TClosure closure)` | +| `Coroutine.Run` | `Coroutine> Run(Func> provider, CancellationToken cancellationToken)` | +| `Coroutine.Run` | `Coroutine> Run(Func> provider)` | +| `Coroutine.Run` | `Coroutine> Run(Func> provider, TClosure closure, CancellationToken cancellationToken)` | +| `Coroutine.Run` | `Coroutine> Run(Func> provider, TClosure closure)` | + +#### Tenekon.Coroutines.Coroutine.Run + +The `Coroutine.Factory.StartNew` yielder is the equivalent to `Task.Factory.StartNew` + +| Yielder | Signature | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Coroutine.Factory.StartNew` | `Coroutine StartNew(Func provider, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)` | +| `Coroutine.Factory.StartNew` | `Coroutine StartNew(Func provider, CancellationToken cancellationToken)` | +| `Coroutine.Factory.StartNew` | `Coroutine StartNew(Func provider, TaskCreationOptions creationOptions)` | +| `Coroutine.Factory.StartNew` | `Coroutine StartNew(Func provider)` | +| `Coroutine.Factory.StartNew` | `Coroutine StartNew(Func provider, TClosure closure, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)` | +| `Coroutine.Factory.StartNew` | `Coroutine StartNew(Func provider, TClosure closure, CancellationToken cancellationToken)` | +| `Coroutine.Factory.StartNew` | `Coroutine StartNew(Func provider, TClosure closure, TaskCreationOptions creationOptions)` | +| `Coroutine.Factory.StartNew` | `Coroutine StartNew(Func provider, TClosure closure)` | +| `Coroutine.Factory.StartNew` | `Coroutine> StartNew(Func> provider, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)` | +| `Coroutine.Factory.StartNew` | `Coroutine> StartNew(Func> provider, CancellationToken cancellationToken)` | +| `Coroutine.Factory.StartNew` | `Coroutine> StartNew(Func> provider, TaskCreationOptions creationOptions)` | +| `Coroutine.Factory.StartNew` | `Coroutine> StartNew(Func> provider)` | +| `Coroutine.Factory.StartNew` | `Coroutine> StartNew(Func> provider, TClosure closure, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)` | +| `Coroutine.Factory.StartNew` | `Coroutine> StartNew(Func> provider, TClosure closure, CancellationToken cancellationToken)` | +| `Coroutine.Factory.StartNew` | `Coroutine> StartNew(Func> provider, TClosure closure, TaskCreationOptions creationOptions)` | +| `Coroutine.Factory.StartNew` | `Coroutine> StartNew(Func> provider, TClosure closure)` | ### Tenekon.Coroutines.Yielders -#### Call +We recommend to make use of `using static`, e.g. `using static Tenekon.Coroutines.Yielders`. + +#### Tenekon.Coroutines.Yielders.Call The `Call` yielder is the equivalent to the `call` effect in Redux-Saga. @@ -140,7 +209,7 @@ Use it to instruct the coroutine to suspend and invoke `provider` with optional | `Call` | `Coroutine Call(Func> provider)` | | `Call` | `Coroutine Call(Func> provider, TClosure closure)` | -#### Launch +#### Tenekon.Coroutines.Yielders.Launch The `Launch` yielder is the equivalent to the `fork` effect in Redux-Saga. @@ -153,7 +222,7 @@ Use it to instruct the coroutine to suspend and invoke `provider` with optional | `Launch` | `Coroutine> Launch(Func> provider)` | | `Launch` | `Coroutine> Launch(Func> provider, TClosure closure)` | -#### Spawn +#### Tenekon.Coroutines.Yielders.Spawn The `Spawn` yielder is the equivalent to the `spawn` effect in Redux-Saga. @@ -166,7 +235,7 @@ Use it to instruct the coroutine to suspend and invoke `provider` with optional | `Spawn` | `Coroutine> Spawn(Func> provider)` | | `Spawn` | `Coroutine> Spawn(Func> provider, TClosure closure)` | -#### Spawn +#### Tenekon.Coroutines.Yielders.Spawn Use `Throw` to instruct the coroutine to suspend and let the coroutine throw `exception`. The coroutine resumes immediatelly and throws `excpetion`. @@ -174,7 +243,7 @@ Use `Throw` to instruct the coroutine to suspend and let the coroutine throw `ex | ------- | -------------------------------------- | | `Throw` | `Coroutine Throw(Exception exception)` | -#### WithContext +#### Tenekon.Coroutines.Yielders.WithContext Use `WithContext` to instruct the coroutine to suspend and invoke `provider` with `additiveContext` and optional `closure`. @@ -185,15 +254,7 @@ Use `WithContext` to instruct the coroutine to suspend and invoke `provider` wit | `WithContext` | `Coroutine WithContext(CoroutineContext additiveContext, Func> provider)` | | `WithContext` | `Coroutine WithContext(CoroutineContext additiveContext, Func> provider, TClosure closure)` | -#### Yield - -Use `Yield` to instruct the coroutine to suspend and resume immediatelly. In the underlying is `Task.Yield()` used. - -| Yielder | Signature | -| ------- | ----------------------------- | -| `Yield` | `Coroutine Coroutine Yield()` | - -#### YieldReturn +#### Tenekon.Coroutines.Yielders.YieldReturn Use `YieldReturn` to instruct the coroutine to suspend and resume immediatelly. Allows the coroutine middleware to get the hands on `value`. @@ -201,7 +262,17 @@ Use `YieldReturn` to instruct the coroutine to suspend and resume immediatelly. | ------------- | ----------------------------------- | | `YieldReturn` | `Coroutine YieldReturn(T value)` | -## Tenekon.Coroutines.Iterators.Yielders +#### Tenekon.Coroutines.Yielders.YieldAssign + +Use `YieldAssign` to instruct the coroutine to suspend and resume immediatelly. +Allows the coroutine middleware to get the hands on `value` and also to yield assign a custom value of type `TAssign`. +If you do not yield assign a custom value of type `TAssign`, then `default(TAssign)` is yield assigned. + +| Yielder | Signature | +| ------------- | ------------------------------------------------------------------------------------------------ | +| `YieldAssign` | `YieldAssign Yield(TYield value) => new(value)` -> `Coroutine Assign()` | + +## Tenekon.Coroutines.Yielders.Exchange Use `Exchange` to instruct the coroutine to suspend and resume immediatelly. Allows the coroutine middleware to get the hands on `value` and exchange it. diff --git a/samples/Playground/Playground.csproj b/samples/Playground/Playground.csproj index 7e0305d..d00b746 100644 --- a/samples/Playground/Playground.csproj +++ b/samples/Playground/Playground.csproj @@ -2,9 +2,10 @@ Exe - net6.0 + net8.0 enable enable + true diff --git a/samples/Playground/Program.cs b/samples/Playground/Program.cs index d7adf35..736a72f 100644 --- a/samples/Playground/Program.cs +++ b/samples/Playground/Program.cs @@ -1,22 +1,19 @@ -using Tenekon.Coroutines; +using System.Diagnostics; +using Tenekon.Coroutines; await Coroutine.Start(async () => { - Console.WriteLine(Environment.CurrentManagedThreadId); - - var t1 = await Coroutine.Factory.StartNew(async () => + var t1 = await Coroutine.Factory.StartNew(new Func(async () => { - Console.WriteLine("Hello World " + Environment.CurrentManagedThreadId); Thread.Sleep(3000); - Console.WriteLine("Finished"); - }); + Console.WriteLine(DateTime.UtcNow - Process.GetCurrentProcess().StartTime.ToUniversalTime() + ": Finished"); + })); - var t2 = await Coroutine.Factory.StartNew(async () => + var t2 = await Coroutine.Factory.StartNew(new Func(async () => { - Console.WriteLine("Hello World " + Environment.CurrentManagedThreadId); Thread.Sleep(3000); - Console.WriteLine("Finished"); - }); + Console.WriteLine(DateTime.UtcNow - Process.GetCurrentProcess().StartTime.ToUniversalTime() + ": Finished"); + })); await Task.WhenAll(t1.AsTask(), t2.AsTask()); }); \ No newline at end of file diff --git a/src/Tenekon.Coroutines/Coroutines/Coroutine.Yield.cs b/src/Tenekon.Coroutines/Coroutines/Coroutine.Yield.cs new file mode 100644 index 0000000..3b8a56d --- /dev/null +++ b/src/Tenekon.Coroutines/Coroutines/Coroutine.Yield.cs @@ -0,0 +1,14 @@ +using Tenekon.Coroutines.Sources; +using static Tenekon.Coroutines.Yielders.Arguments; + +namespace Tenekon.Coroutines; + +partial struct Coroutine +{ + public static Coroutine Yield() + { + var completionSource = ManualResetCoroutineCompletionSource.RentFromCache(); + var argument = new YieldArgument(completionSource); + return new(completionSource, argument); + } +} diff --git a/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIterator.T.cs b/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIterator.T.cs index b6d879e..d9ee7d5 100644 --- a/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIterator.T.cs +++ b/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIterator.T.cs @@ -10,9 +10,9 @@ partial class AsyncIteratorImpl ValueTask IAsyncIterator.MoveNextAsync() => MoveNextAsync(); - void IAsyncIterator.YieldReturn(TYieldResult result) => YieldReturn(result); + void IAsyncIterator.YieldAssign(TYieldResult result) => YieldAssign(result); - void IAsyncIterator.YieldReturn() => YieldReturn(); + void IAsyncIterator.YieldAssign() => YieldAssign(); void IAsyncIterator.Return(TResult result) => Return(result); diff --git a/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIterator.cs b/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIterator.cs index 87bbe3b..85582b4 100644 --- a/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIterator.cs +++ b/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIterator.cs @@ -29,9 +29,9 @@ partial class AsyncIteratorImpl ValueTask IAsyncIterator.MoveNextAsync() => MoveNextAsync(); - void IAsyncIterator.YieldReturn(TYieldResult result) => YieldReturn(result); + void IAsyncIterator.YieldAssign(TYieldResult result) => YieldAssign(result); - void IAsyncIterator.YieldReturn() => YieldReturn(); + void IAsyncIterator.YieldAssign() => YieldAssign(); void IAsyncIterator.Return() => Return(default!); diff --git a/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIteratorImpl.cs b/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIteratorImpl.cs index c9a0fe5..2bb4b98 100644 --- a/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIteratorImpl.cs +++ b/src/Tenekon.Coroutines/Coroutines/Iterators/AsyncIteratorImpl.cs @@ -200,7 +200,7 @@ public async ValueTask MoveNextAsync() return false; } - public void YieldReturn(TYieldResult result) + public void YieldAssign(TYieldResult result) { if (_nextSuspensionPoint._state != 0) { try { @@ -220,7 +220,7 @@ public void YieldReturn(TYieldResult result) } } - public void YieldReturn() + public void YieldAssign() { if (_nextSuspensionPoint._state != 0) { try { diff --git a/src/Tenekon.Coroutines/Coroutines/Iterators/IAsyncIterator.T.cs b/src/Tenekon.Coroutines/Coroutines/Iterators/IAsyncIterator.T.cs index 57ebbb0..338a709 100644 --- a/src/Tenekon.Coroutines/Coroutines/Iterators/IAsyncIterator.T.cs +++ b/src/Tenekon.Coroutines/Coroutines/Iterators/IAsyncIterator.T.cs @@ -20,9 +20,9 @@ public interface IAsyncIterator /// ValueTask MoveNextAsync(); - void YieldReturn(TYieldResult result); + void YieldAssign(TYieldResult result); - void YieldReturn(); + void YieldAssign(); void Return(TResult result); diff --git a/src/Tenekon.Coroutines/Coroutines/Iterators/IAsyncIterator.cs b/src/Tenekon.Coroutines/Coroutines/Iterators/IAsyncIterator.cs index 906bd31..68fbbb7 100644 --- a/src/Tenekon.Coroutines/Coroutines/Iterators/IAsyncIterator.cs +++ b/src/Tenekon.Coroutines/Coroutines/Iterators/IAsyncIterator.cs @@ -20,9 +20,9 @@ public interface IAsyncIterator /// ValueTask MoveNextAsync(); - void YieldReturn(TYieldResult result); + void YieldAssign(TYieldResult result); - void YieldReturn(); + void YieldAssign(); void Return(); diff --git a/src/Tenekon.Coroutines/Coroutines/Yielders.Yield.cs b/src/Tenekon.Coroutines/Coroutines/Yielders.Yield.cs index c36d8d1..9c41a31 100644 --- a/src/Tenekon.Coroutines/Coroutines/Yielders.Yield.cs +++ b/src/Tenekon.Coroutines/Coroutines/Yielders.Yield.cs @@ -1,17 +1,9 @@ using Tenekon.Coroutines.Sources; -using static Tenekon.Coroutines.Yielders.Arguments; namespace Tenekon.Coroutines; partial class Yielders { - public static Coroutine Yield() - { - var completionSource = ManualResetCoroutineCompletionSource.RentFromCache(); - var argument = new YieldArgument(completionSource); - return new(completionSource, argument); - } - partial class Arguments { public class YieldArgument : ICallableArgument>, ISiblingCoroutine diff --git a/src/Tenekon.Coroutines/Coroutines/Yielders.YieldReturn.T.cs b/src/Tenekon.Coroutines/Coroutines/Yielders.YieldAssign.cs similarity index 69% rename from src/Tenekon.Coroutines/Coroutines/Yielders.YieldReturn.T.cs rename to src/Tenekon.Coroutines/Coroutines/Yielders.YieldAssign.cs index c37aaf7..95c7b9f 100644 --- a/src/Tenekon.Coroutines/Coroutines/Yielders.YieldReturn.T.cs +++ b/src/Tenekon.Coroutines/Coroutines/Yielders.YieldAssign.cs @@ -5,17 +5,17 @@ namespace Tenekon.Coroutines; partial class Yielders { - public readonly struct YieldReturnQuery(TYield value) + public readonly struct YieldAssign(TYield value) { - public readonly Coroutine Return() + public readonly Coroutine Assign() { - var completionSource = ManualResetCoroutineCompletionSource.RentFromCache(); - var argument = new YieldReturnArgument(value, completionSource); + var completionSource = ManualResetCoroutineCompletionSource.RentFromCache(); + var argument = new YieldReturnArgument(value, completionSource); return new(completionSource, argument); } } - public static YieldReturnQuery Yield(TValue value) => new(value); + public static YieldAssign Yield(TYield value) => new(value); partial class Arguments { @@ -33,9 +33,9 @@ internal readonly struct YieldReturnArgumentCore(TYield value, public readonly override int GetHashCode() => HashCode.Combine(Value); } - public class YieldReturnArgument : ICallableArgument>, ISiblingCoroutine + public class YieldReturnArgument : ICallableArgument>, ISiblingCoroutine { - private readonly YieldReturnArgumentCore _core; + private readonly YieldReturnArgumentCore _core; public TYield Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -43,16 +43,16 @@ public TYield Value { } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal YieldReturnArgument(TYield value, ManualResetCoroutineCompletionSource completionSource) => _core = new(value, completionSource); + internal YieldReturnArgument(TYield value, ManualResetCoroutineCompletionSource completionSource) => _core = new(value, completionSource); public YieldReturnArgument(TYield value) => _core = new(value, completionSource: null); - void ICallableArgument>.Callback(in CoroutineContext context, ManualResetCoroutineCompletionSource completionSource) => + void ICallableArgument>.Callback(in CoroutineContext context, ManualResetCoroutineCompletionSource completionSource) => completionSource.SetDefaultResult(); - void ISiblingCoroutine.ActOnCoroutine(ref CoroutineArgumentReceiver argumentReceiver) => ActOnCoroutine(ref argumentReceiver, YieldReturnVariantKey, this, _core._completionSource); + void ISiblingCoroutine.ActOnCoroutine(ref CoroutineArgumentReceiver argumentReceiver) => ActOnCoroutine(ref argumentReceiver, YieldAssign, this, _core._completionSource); - public override bool Equals([AllowNull] object obj) => obj is YieldReturnArgument other && _core.Equals(other._core); + public override bool Equals([AllowNull] object obj) => obj is YieldReturnArgument other && _core.Equals(other._core); public override int GetHashCode() => _core.GetHashCode(); } diff --git a/src/Tenekon.Coroutines/Coroutines/Yielders.cs b/src/Tenekon.Coroutines/Coroutines/Yielders.cs index 137a7ff..0c90177 100644 --- a/src/Tenekon.Coroutines/Coroutines/Yielders.cs +++ b/src/Tenekon.Coroutines/Coroutines/Yielders.cs @@ -33,7 +33,7 @@ public partial class Arguments public readonly static Key ThrowKey = new(s_scope, 6); public readonly static Key YieldKey = new(s_scope, 7); public readonly static Key ExchangeKey = new(s_scope, 8); - public readonly static Key YieldReturnVariantKey = new(s_scope, 9); + public readonly static Key YieldAssign = new(s_scope, 9); public readonly static Key StartNewKey = new(s_scope, 10); public readonly static Key RunKey = new(s_scope, 11); diff --git a/test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.YieldReturn.T.cs b/test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.YieldAssign.cs similarity index 89% rename from test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.YieldReturn.T.cs rename to test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.YieldAssign.cs index c9ba01a..03cac84 100644 --- a/test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.YieldReturn.T.cs +++ b/test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.YieldAssign.cs @@ -2,13 +2,13 @@ partial class AsyncIteratorTests { - public class YieldReturnVariant + public class YieldAssign { public class SyncCoroutineWithSyncResult : AbstractSyncCoroutineWithSyncResult { public override int ExpectedResult => 0; - protected override Coroutine CreateCoroutine() => Yield(int.MaxValue).Return(); + protected override Coroutine CreateCoroutine() => Yield(int.MaxValue).Assign(); protected override ValueTask Unwrap(int resultWrapper) => new(resultWrapper); protected override ValueTask> Unwrap(Coroutine coroutine) => new(coroutine); } @@ -19,7 +19,7 @@ public class AsyncCoroutineWithSyncResult : AbstractAsyncCoroutineWithSyncResult public override int ExpectedYieldResult => Two; public override int ExpectedYieldResultOfClone => 0; - protected override async Coroutine CreateCoroutine() => await Yield(int.MaxValue).Return(); + protected override async Coroutine CreateCoroutine() => await Yield(int.MaxValue).Assign(); protected override ValueTask Unwrap(int resultWrapper) => new(resultWrapper); protected override ValueTask> Unwrap(Coroutine coroutine) => new(coroutine); } diff --git a/test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.cs b/test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.cs index ca298e5..fc8f0ac 100644 --- a/test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.cs +++ b/test/Tenekon.Coroutines.NetTest/Coroutines/Iterators/AsyncIteratorTests.cs @@ -83,7 +83,7 @@ public virtual async Task MoveNextThenYieldReturnThenGetResult_Returns() { var iterator = CreateCoroutine().GetAsyncIterator(); _ = await iterator.MoveNextAsync(); - iterator.YieldReturn(ExpectedYieldResult); + iterator.YieldAssign(ExpectedYieldResult); var asyncResult = await iterator.GetResultAsync(); var result = await Unwrap(asyncResult); result.Should().Be(await Unwrap(ExpectedYieldResult)); @@ -125,7 +125,7 @@ public virtual async Task Clone_DoesNotConsumesOriginalIterator() _ = await our.MoveNextAsync(); var their = our.Clone(); _ = await their.MoveNextAsync(); - their.YieldReturn(ExpectedYieldResultOfClone); + their.YieldAssign(ExpectedYieldResultOfClone); var ourAsyncResult = await our.GetResultAsync(); var ourResult = await Unwrap(ourAsyncResult); var theirAsyncResult = await their.GetResultAsync(); diff --git a/test/Tenekon.Coroutines.NetTest/Coroutines/PublicApiTests.CoroutinesNetAssembly_HasApprovedPublicApi.verified.txt b/test/Tenekon.Coroutines.NetTest/Coroutines/PublicApiTests.CoroutinesNetAssembly_HasApprovedPublicApi.verified.txt index 47ba391..e79746a 100644 --- a/test/Tenekon.Coroutines.NetTest/Coroutines/PublicApiTests.CoroutinesNetAssembly_HasApprovedPublicApi.verified.txt +++ b/test/Tenekon.Coroutines.NetTest/Coroutines/PublicApiTests.CoroutinesNetAssembly_HasApprovedPublicApi.verified.txt @@ -75,6 +75,7 @@ namespace Tenekon.Coroutines public static Tenekon.Coroutines.CompilerServices.CoroutineAwaitable Start(System.Func> provider, Tenekon.Coroutines.CoroutineContext context = default) { } public static Tenekon.Coroutines.CompilerServices.CoroutineAwaitable Start(System.Func provider, TClosure closure, Tenekon.Coroutines.CoroutineContext context = default) { } public static Tenekon.Coroutines.CompilerServices.CoroutineAwaitable Start(System.Func> provider, TClosure closure, Tenekon.Coroutines.CoroutineContext context = default) { } + public static Tenekon.Coroutines.Coroutine Yield() { } public static Tenekon.Coroutines.Coroutine op_Implicit(System.Threading.Tasks.Task task) { } public static Tenekon.Coroutines.Coroutine op_Implicit(System.Threading.Tasks.ValueTask task) { } public static bool operator !=(Tenekon.Coroutines.Coroutine left, Tenekon.Coroutines.Coroutine right) { } @@ -287,8 +288,7 @@ namespace Tenekon.Coroutines public static Tenekon.Coroutines.Coroutine WithContext(in Tenekon.Coroutines.CoroutineContext additiveContext, Tenekon.Coroutines.CoroutineProviderDelegate provider) { } public static Tenekon.Coroutines.Coroutine WithContext(in Tenekon.Coroutines.CoroutineContext additiveContext, Tenekon.Coroutines.CoroutineProviderWithClosureDelegate provider, TClosure closure) { } public static Tenekon.Coroutines.Coroutine WithContext(in Tenekon.Coroutines.CoroutineContext additiveContext, Tenekon.Coroutines.CoroutineProviderWithClosureDelegate provider, TClosure closure) { } - public static Tenekon.Coroutines.Coroutine Yield() { } - public static Tenekon.Coroutines.Yielders.YieldReturnQuery Yield(TValue value) { } + public static Tenekon.Coroutines.Yielders.YieldAssign Yield(TYield value) { } public static Tenekon.Coroutines.Coroutine YieldReturn(T value) { } public class Arguments { @@ -300,9 +300,9 @@ namespace Tenekon.Coroutines public static readonly Tenekon.Coroutines.Key StartNewKey; public static readonly Tenekon.Coroutines.Key ThrowKey; public static readonly Tenekon.Coroutines.Key WithContextKey; + public static readonly Tenekon.Coroutines.Key YieldAssign; public static readonly Tenekon.Coroutines.Key YieldKey; public static readonly Tenekon.Coroutines.Key YieldReturnKey; - public static readonly Tenekon.Coroutines.Key YieldReturnVariantKey; public Arguments() { } public class CallArgument : Tenekon.Coroutines.ICallableArgument, Tenekon.Coroutines.ICallableArgument>, Tenekon.Coroutines.ISiblingCoroutine { @@ -458,7 +458,7 @@ namespace Tenekon.Coroutines public override bool Equals([System.Diagnostics.CodeAnalysis.AllowNull] object obj) { } public override int GetHashCode() { } } - public class YieldReturnArgument : Tenekon.Coroutines.ICallableArgument, Tenekon.Coroutines.ICallableArgument>, Tenekon.Coroutines.ISiblingCoroutine + public class YieldReturnArgument : Tenekon.Coroutines.ICallableArgument, Tenekon.Coroutines.ICallableArgument>, Tenekon.Coroutines.ISiblingCoroutine { public YieldReturnArgument(TYield value) { } public TYield Value { get; } @@ -466,10 +466,10 @@ namespace Tenekon.Coroutines public override int GetHashCode() { } } } - public readonly struct YieldReturnQuery + public readonly struct YieldAssign { - public YieldReturnQuery(TYield value) { } - public Tenekon.Coroutines.Coroutine Return() { } + public YieldAssign(TYield value) { } + public Tenekon.Coroutines.Coroutine Assign() { } } } } @@ -548,8 +548,8 @@ namespace Tenekon.Coroutines.Iterators System.Threading.Tasks.ValueTask MoveNextAsync(); void Return(); void Throw(System.Exception e); - void YieldReturn(); - void YieldReturn(TYieldResult result); + void YieldAssign(); + void YieldAssign(TYieldResult result); } public interface IAsyncIterator { @@ -562,8 +562,8 @@ namespace Tenekon.Coroutines.Iterators System.Threading.Tasks.ValueTask MoveNextAsync(); void Return(TResult result); void Throw(System.Exception e); - void YieldReturn(); - void YieldReturn(TYieldResult result); + void YieldAssign(); + void YieldAssign(TYieldResult result); } [System.Flags] public enum SuspensionPointState