Skip to content

Commit

Permalink
Merge pull request #17 from Cysharp/feature/net7.0
Browse files Browse the repository at this point in the history
Adopt to .NET 7
  • Loading branch information
mayuki committed Aug 1, 2023
2 parents 9ed32c0 + ab7d254 commit 586dbff
Show file tree
Hide file tree
Showing 28 changed files with 1,666 additions and 1,778 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/build-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ jobs:
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
with:
dotnet-version: |
3.1.x
5.0.x
6.0.x
7.0.x
- run: dotnet build -c Debug -p:DefineConstants=RUNNING_IN_CI
- run: dotnet pack ./src/LogicLooper/LogicLooper.csproj -c Debug --no-build -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg
- run: dotnet test -c Debug --no-build
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ jobs:
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
with:
dotnet-version: |
3.1.x
5.0.x
6.0.x
7.0.x
- run: dotnet build -c Release -p:VersionPrefix=${{ env.GIT_TAG }} -p:DefineConstants=RUNNING_IN_CI
- run: dotnet test -c Release --no-build
- run: dotnet pack -c Release --no-build -p:VersionPrefix=${{ env.GIT_TAG }} -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg -o ./publish
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,63 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Cysharp.Threading.CompilerServices
{
namespace Cysharp.Threading.CompilerServices;

#if !DEBUG
[EditorBrowsable(EditorBrowsableState.Never)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public struct LogicLooperCoroutineAsyncValueTaskMethodBuilder
{
private readonly LogicLooperCoroutine _coroutine;
public struct LogicLooperCoroutineAsyncValueTaskMethodBuilder
{
private readonly LogicLooperCoroutine _coroutine;

public static LogicLooperCoroutineAsyncValueTaskMethodBuilder Create()
{
return new LogicLooperCoroutineAsyncValueTaskMethodBuilder(new LogicLooperCoroutine(LogicLooperCoroutineActionContext.Current!));
}
public static LogicLooperCoroutineAsyncValueTaskMethodBuilder Create()
{
return new LogicLooperCoroutineAsyncValueTaskMethodBuilder(new LogicLooperCoroutine(LogicLooperCoroutineActionContext.Current!));
}

private LogicLooperCoroutineAsyncValueTaskMethodBuilder(LogicLooperCoroutine coroutine)
{
_coroutine = coroutine ?? throw new ArgumentNullException(nameof(coroutine));
}
private LogicLooperCoroutineAsyncValueTaskMethodBuilder(LogicLooperCoroutine coroutine)
{
_coroutine = coroutine ?? throw new ArgumentNullException(nameof(coroutine));
}

public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}

public void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
}

public void SetResult()
{
_coroutine.SetResult();
}
public void SetResult()
{
_coroutine.SetResult();
}

public void SetException(Exception exception)
{
_coroutine.SetException(exception);
}
public void SetException(Exception exception)
{
_coroutine.SetException(exception);
}

public LogicLooperCoroutine Task => _coroutine;
public LogicLooperCoroutine Task => _coroutine;

public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (!(awaiter is LogicLooperCoroutineFrameAwaitable))
throw new InvalidOperationException($"Cannot use general-purpose awaitable in the Coroutine action. Use {nameof(LogicLooperCoroutineActionContext)}'s methods instead of {nameof(Task)}'s.");
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (!(awaiter is LogicLooperCoroutineFrameAwaitable))
throw new InvalidOperationException($"Cannot use general-purpose awaitable in the Coroutine action. Use {nameof(LogicLooperCoroutineActionContext)}'s methods instead of {nameof(Task)}'s.");

awaiter.OnCompleted(stateMachine.MoveNext);
}
awaiter.OnCompleted(stateMachine.MoveNext);
}

public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (!(awaiter is LogicLooperCoroutineFrameAwaitable))
throw new InvalidOperationException($"Cannot use general-purpose awaitable in the Coroutine action. Use {nameof(LogicLooperCoroutineActionContext)}'s methods instead of {nameof(Task)}'s.");
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (!(awaiter is LogicLooperCoroutineFrameAwaitable))
throw new InvalidOperationException($"Cannot use general-purpose awaitable in the Coroutine action. Use {nameof(LogicLooperCoroutineActionContext)}'s methods instead of {nameof(Task)}'s.");

awaiter.UnsafeOnCompleted(stateMachine.MoveNext);
}
awaiter.UnsafeOnCompleted(stateMachine.MoveNext);
}
}
Original file line number Diff line number Diff line change
@@ -1,66 +1,63 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Cysharp.Threading.CompilerServices
{
namespace Cysharp.Threading.CompilerServices;

#if !DEBUG
[EditorBrowsable(EditorBrowsableState.Never)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public struct LogicLooperCoroutineAsyncValueTaskMethodBuilder<TResult>
{
private readonly LogicLooperCoroutine<TResult> _coroutine;
public struct LogicLooperCoroutineAsyncValueTaskMethodBuilder<TResult>
{
private readonly LogicLooperCoroutine<TResult> _coroutine;

public static LogicLooperCoroutineAsyncValueTaskMethodBuilder<TResult> Create()
{
return new LogicLooperCoroutineAsyncValueTaskMethodBuilder<TResult>(new LogicLooperCoroutine<TResult>(LogicLooperCoroutineActionContext.Current!));
}
public static LogicLooperCoroutineAsyncValueTaskMethodBuilder<TResult> Create()
{
return new LogicLooperCoroutineAsyncValueTaskMethodBuilder<TResult>(new LogicLooperCoroutine<TResult>(LogicLooperCoroutineActionContext.Current!));
}

private LogicLooperCoroutineAsyncValueTaskMethodBuilder(LogicLooperCoroutine<TResult> coroutine)
{
_coroutine = coroutine ?? throw new ArgumentNullException(nameof(coroutine));
}
private LogicLooperCoroutineAsyncValueTaskMethodBuilder(LogicLooperCoroutine<TResult> coroutine)
{
_coroutine = coroutine ?? throw new ArgumentNullException(nameof(coroutine));
}

public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}

public void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
}

public void SetResult(TResult result)
{
_coroutine.SetResult(result);
}
public void SetResult(TResult result)
{
_coroutine.SetResult(result);
}

public void SetException(Exception exception)
{
_coroutine.SetException(exception);
}
public void SetException(Exception exception)
{
_coroutine.SetException(exception);
}

public LogicLooperCoroutine<TResult> Task => _coroutine;
public LogicLooperCoroutine<TResult> Task => _coroutine;

public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (!(awaiter is LogicLooperCoroutineFrameAwaitable))
throw new InvalidOperationException($"Cannot use general-purpose awaitable in the Coroutine action. Use {nameof(LogicLooperCoroutineActionContext)}'s methods instead of {nameof(Task)}'s.");
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (!(awaiter is LogicLooperCoroutineFrameAwaitable))
throw new InvalidOperationException($"Cannot use general-purpose awaitable in the Coroutine action. Use {nameof(LogicLooperCoroutineActionContext)}'s methods instead of {nameof(Task)}'s.");

awaiter.OnCompleted(stateMachine.MoveNext);
}
awaiter.OnCompleted(stateMachine.MoveNext);
}

public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (!(awaiter is LogicLooperCoroutineFrameAwaitable))
throw new InvalidOperationException($"Cannot use general-purpose awaitable in the Coroutine action. Use {nameof(LogicLooperCoroutineActionContext)}'s methods instead of {nameof(Task)}'s.");
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (!(awaiter is LogicLooperCoroutineFrameAwaitable))
throw new InvalidOperationException($"Cannot use general-purpose awaitable in the Coroutine action. Use {nameof(LogicLooperCoroutineActionContext)}'s methods instead of {nameof(Task)}'s.");

awaiter.UnsafeOnCompleted(stateMachine.MoveNext);
}
awaiter.UnsafeOnCompleted(stateMachine.MoveNext);
}
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace Cysharp.Threading.CompilerServices
{
namespace Cysharp.Threading.CompilerServices;

#if !DEBUG
[EditorBrowsable(EditorBrowsableState.Never)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public struct LogicLooperCoroutineFrameAwaitable : INotifyCompletion, ICriticalNotifyCompletion
{
private readonly int _waitFrames;
private readonly LogicLooperCoroutine _coroutine;
public struct LogicLooperCoroutineFrameAwaitable : INotifyCompletion, ICriticalNotifyCompletion
{
private readonly int _waitFrames;
private readonly LogicLooperCoroutine _coroutine;

public LogicLooperCoroutineFrameAwaitable GetAwaiter() => this;
public LogicLooperCoroutineFrameAwaitable GetAwaiter() => this;

public bool IsCompleted => false;
public void GetResult()
{ }
public bool IsCompleted => false;
public void GetResult()
{ }

public LogicLooperCoroutineFrameAwaitable(LogicLooperCoroutine coroutine, int waitFrames)
{
_coroutine = coroutine ?? throw new ArgumentNullException(nameof(coroutine));
_waitFrames = (waitFrames > 0) ? waitFrames - 1 : throw new ArgumentOutOfRangeException(nameof(waitFrames));
}
public LogicLooperCoroutineFrameAwaitable(LogicLooperCoroutine coroutine, int waitFrames)
{
_coroutine = coroutine ?? throw new ArgumentNullException(nameof(coroutine));
_waitFrames = (waitFrames > 0) ? waitFrames - 1 : throw new ArgumentOutOfRangeException(nameof(waitFrames));
}

public void OnCompleted(Action continuation)
{
_coroutine.SetContinuation(_waitFrames, continuation);
}
public void OnCompleted(Action continuation)
{
_coroutine.SetContinuation(_waitFrames, continuation);
}

public void UnsafeOnCompleted(Action continuation)
{
_coroutine.SetContinuation(_waitFrames, continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
_coroutine.SetContinuation(_waitFrames, continuation);
}
}
80 changes: 37 additions & 43 deletions src/LogicLooper/ILogicLooper.cs
Original file line number Diff line number Diff line change
@@ -1,54 +1,48 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Cysharp.Threading;

namespace Cysharp.Threading
/// <summary>
/// Provides interface for update loop programming model.
/// </summary>
public interface ILogicLooper : IDisposable
{
/// <summary>
/// Provides interface for update loop programming model.
/// Gets a unique identifier of the looper.
/// </summary>
public interface ILogicLooper : IDisposable
{
/// <summary>
/// Gets a unique identifier of the looper.
/// </summary>
int Id { get; }
int Id { get; }

/// <summary>
/// Gets an approximately count of running actions.
/// </summary>
int ApproximatelyRunningActions { get; }
/// <summary>
/// Gets an approximately count of running actions.
/// </summary>
int ApproximatelyRunningActions { get; }

/// <summary>
/// Gets a duration of the last processed frame.
/// </summary>
TimeSpan LastProcessingDuration { get; }
/// <summary>
/// Gets a duration of the last processed frame.
/// </summary>
TimeSpan LastProcessingDuration { get; }

/// <summary>
/// Gets a target frame rate of the looper.
/// </summary>
double TargetFrameRate { get; }
/// <summary>
/// Gets a target frame rate of the looper.
/// </summary>
double TargetFrameRate { get; }

/// <summary>
/// Registers a loop-frame action to the looper and returns <see cref="Task"/> to wait for completion.
/// </summary>
/// <param name="loopAction"></param>
/// <returns></returns>
Task RegisterActionAsync(LogicLooperActionDelegate loopAction);
/// <summary>
/// Registers a loop-frame action to the looper and returns <see cref="Task"/> to wait for completion.
/// </summary>
/// <param name="loopAction"></param>
/// <returns></returns>
Task RegisterActionAsync(LogicLooperActionDelegate loopAction);

/// <summary>
/// Registers a loop-frame action with state object to the looper and returns <see cref="Task"/> to wait for completion.
/// </summary>
/// <param name="loopAction"></param>
/// <param name="state"></param>
/// <returns></returns>
Task RegisterActionAsync<TState>(LogicLooperActionWithStateDelegate<TState> loopAction, TState state);
/// <summary>
/// Registers a loop-frame action with state object to the looper and returns <see cref="Task"/> to wait for completion.
/// </summary>
/// <param name="loopAction"></param>
/// <param name="state"></param>
/// <returns></returns>
Task RegisterActionAsync<TState>(LogicLooperActionWithStateDelegate<TState> loopAction, TState state);

/// <summary>
/// Stops the action loop of the looper.
/// </summary>
/// <param name="shutdownDelay"></param>
Task ShutdownAsync(TimeSpan shutdownDelay);
}
/// <summary>
/// Stops the action loop of the looper.
/// </summary>
/// <param name="shutdownDelay"></param>
Task ShutdownAsync(TimeSpan shutdownDelay);
}
Loading

0 comments on commit 586dbff

Please sign in to comment.