Merge remote-tracking branch 'origin/main'

This commit is contained in:
Ell 2022-10-31 13:02:37 +01:00
commit fe9e5c658a
6 changed files with 63 additions and 40 deletions

1
.github/FUNDING.yml vendored
View file

@ -1 +1,2 @@
github: Ellpeck github: Ellpeck
ko_fi: Ellpeck

View file

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFrameworks>net45;netstandard2.0;net6.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup> </PropertyGroup>
@ -13,11 +13,15 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile> <PackageReadmeFile>README.md</PackageReadmeFile>
<PackageIcon>Logo.png</PackageIcon> <PackageIcon>Logo.png</PackageIcon>
<VersionPrefix>2.1.2</VersionPrefix> <VersionPrefix>2.1.4</VersionPrefix>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Include="../README.md" Pack="true" PackagePath="" /> <None Include="../README.md" Pack="true" PackagePath="" />
<None Include="../Logo.png" Pack="true" PackagePath="" /> <None Include="../Logo.png" Pack="true" PackagePath="" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net45'">
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
</Project> </Project>

View file

@ -16,15 +16,26 @@ namespace Coroutine {
private readonly HashSet<ActiveCoroutine> outstandingEventCoroutines = new HashSet<ActiveCoroutine>(); private readonly HashSet<ActiveCoroutine> outstandingEventCoroutines = new HashSet<ActiveCoroutine>();
private readonly HashSet<ActiveCoroutine> outstandingTickingCoroutines = new HashSet<ActiveCoroutine>(); private readonly HashSet<ActiveCoroutine> outstandingTickingCoroutines = new HashSet<ActiveCoroutine>();
private readonly Stopwatch stopwatch = new Stopwatch(); private readonly Stopwatch stopwatch = new Stopwatch();
private readonly object lockObject = new object();
/// <summary> /// <summary>
/// The amount of <see cref="ActiveCoroutine"/> instances that are currently waiting for a tick (waiting for time to pass) /// The amount of <see cref="ActiveCoroutine"/> instances that are currently waiting for a tick (waiting for time to pass)
/// </summary> /// </summary>
public int TickingCount => this.tickingCoroutines.Count; public int TickingCount {
get {
lock (this.lockObject)
return this.tickingCoroutines.Count;
}
}
/// <summary> /// <summary>
/// The amount of <see cref="ActiveCoroutine"/> instances that are currently waiting for an <see cref="Event"/> /// The amount of <see cref="ActiveCoroutine"/> instances that are currently waiting for an <see cref="Event"/>
/// </summary> /// </summary>
public int EventCount => this.eventCoroutines.Sum(c => c.Value.Count); public int EventCount {
get {
lock (this.lockObject)
return this.eventCoroutines.Sum(c => c.Value.Count);
}
}
/// <summary> /// <summary>
/// Starts the given coroutine, returning a <see cref="ActiveCoroutine"/> object for management. /// Starts the given coroutine, returning a <see cref="ActiveCoroutine"/> object for management.
@ -47,8 +58,10 @@ namespace Coroutine {
/// <returns>An active coroutine object representing this coroutine</returns> /// <returns>An active coroutine object representing this coroutine</returns>
public ActiveCoroutine Start(IEnumerator<Wait> coroutine, string name = "", int priority = 0) { public ActiveCoroutine Start(IEnumerator<Wait> coroutine, string name = "", int priority = 0) {
var inst = new ActiveCoroutine(coroutine, name, priority, this.stopwatch); var inst = new ActiveCoroutine(coroutine, name, priority, this.stopwatch);
if (inst.MoveNext()) if (inst.MoveNext()) {
this.GetOutstandingCoroutines(inst.IsWaitingForEvent).Add(inst); lock (this.lockObject)
this.GetOutstandingCoroutines(inst.IsWaitingForEvent).Add(inst);
}
return inst; return inst;
} }
@ -70,16 +83,18 @@ namespace Coroutine {
/// </summary> /// </summary>
/// <param name="deltaSeconds">The amount of seconds that have passed since the last time this method was invoked</param> /// <param name="deltaSeconds">The amount of seconds that have passed since the last time this method was invoked</param>
public void Tick(double deltaSeconds) { public void Tick(double deltaSeconds) {
this.MoveOutstandingCoroutines(false); lock (this.lockObject) {
this.tickingCoroutines.RemoveAll(c => { this.MoveOutstandingCoroutines(false);
if (c.Tick(deltaSeconds)) { this.tickingCoroutines.RemoveAll(c => {
return true; if (c.Tick(deltaSeconds)) {
} else if (c.IsWaitingForEvent) { return true;
this.outstandingEventCoroutines.Add(c); } else if (c.IsWaitingForEvent) {
return true; this.outstandingEventCoroutines.Add(c);
} return true;
return false; }
}); return false;
});
}
} }
/// <summary> /// <summary>
@ -96,19 +111,21 @@ namespace Coroutine {
/// </summary> /// </summary>
/// <param name="evt">The event to raise</param> /// <param name="evt">The event to raise</param>
public void RaiseEvent(Event evt) { public void RaiseEvent(Event evt) {
this.MoveOutstandingCoroutines(true); lock (this.lockObject) {
var coroutines = this.GetEventCoroutines(evt, false); this.MoveOutstandingCoroutines(true);
if (coroutines != null) { var coroutines = this.GetEventCoroutines(evt, false);
for (var i = 0; i < coroutines.Count; i++) { if (coroutines != null) {
var c = coroutines[i]; for (var i = 0; i < coroutines.Count; i++) {
var tup = (c.Event, c); var c = coroutines[i];
if (this.eventCoroutinesToRemove.Contains(tup)) var tup = (c.Event, c);
continue; if (this.eventCoroutinesToRemove.Contains(tup))
if (c.OnEvent(evt)) { continue;
this.eventCoroutinesToRemove.Add(tup); if (c.OnEvent(evt)) {
} else if (!c.IsWaitingForEvent) { this.eventCoroutinesToRemove.Add(tup);
this.eventCoroutinesToRemove.Add(tup); } else if (!c.IsWaitingForEvent) {
this.outstandingTickingCoroutines.Add(c); this.eventCoroutinesToRemove.Add(tup);
this.outstandingTickingCoroutines.Add(c);
}
} }
} }
} }
@ -119,7 +136,8 @@ namespace Coroutine {
/// </summary> /// </summary>
/// <returns>All active coroutines</returns> /// <returns>All active coroutines</returns>
public IEnumerable<ActiveCoroutine> GetActiveCoroutines() { public IEnumerable<ActiveCoroutine> GetActiveCoroutines() {
return this.tickingCoroutines.Concat(this.eventCoroutines.Values.SelectMany(c => c)); lock (this.lockObject)
return this.tickingCoroutines.Concat(this.eventCoroutines.Values.SelectMany(c => c));
} }
private void MoveOutstandingCoroutines(bool evt) { private void MoveOutstandingCoroutines(bool evt) {

View file

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>

View file

@ -11,8 +11,8 @@ There are two predefined ways to pause a coroutine:
Additionally, Coroutine provides the following features: Additionally, Coroutine provides the following features:
- Creation of custom events to wait for - Creation of custom events to wait for
- Creation of custom wait conditions
- No multi-threading, which allows for any kind of process to be executed in a coroutine, including rendering - No multi-threading, which allows for any kind of process to be executed in a coroutine, including rendering
- Thread-safety, which allows for coroutines to be started from different threads
# How to Use # How to Use
## Setting up the CoroutineHandler ## Setting up the CoroutineHandler

View file

@ -1,18 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<VSTestLogger>nunit</VSTestLogger> <VSTestLogger>nunit</VSTestLogger>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.0.3" /> <PackageReference Include="coverlet.collector" Version="3.1.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="NUnit" Version="3.13.1" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NunitXml.TestLogger" Version="3.0.97" /> <PackageReference Include="NunitXml.TestLogger" Version="3.0.127" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Coroutine\Coroutine.csproj" /> <ProjectReference Include="..\Coroutine\Coroutine.csproj" />
</ItemGroup> </ItemGroup>