From bd525cb85a7168122ab987b76869020673d1498f Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sat, 22 Jun 2019 17:24:50 +0200 Subject: [PATCH] the actual thing --- .gitignore | 5 +++ Coroutine.sln | 22 +++++++++++ Coroutine/Coroutine.cs | 36 +++++++++++++++++ Coroutine/Coroutine.csproj | 58 ++++++++++++++++++++++++++++ Coroutine/CoroutineHandler.cs | 44 +++++++++++++++++++++ Coroutine/Event.cs | 7 ++++ Coroutine/Properties/AssemblyInfo.cs | 35 +++++++++++++++++ Coroutine/Wait.cs | 24 ++++++++++++ Coroutine/WaitEvent.cs | 19 +++++++++ Coroutine/WaitSeconds.cs | 20 ++++++++++ README.md | 2 +- Test/Example.cs | 57 +++++++++++++++++++++++++++ Test/Test.csproj | 58 ++++++++++++++++++++++++++++ 13 files changed, 386 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 Coroutine.sln create mode 100644 Coroutine/Coroutine.cs create mode 100644 Coroutine/Coroutine.csproj create mode 100644 Coroutine/CoroutineHandler.cs create mode 100644 Coroutine/Event.cs create mode 100644 Coroutine/Properties/AssemblyInfo.cs create mode 100644 Coroutine/Wait.cs create mode 100644 Coroutine/WaitEvent.cs create mode 100644 Coroutine/WaitSeconds.cs create mode 100644 Test/Example.cs create mode 100644 Test/Test.csproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38b37f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea +bin +obj +packages +*.user \ No newline at end of file diff --git a/Coroutine.sln b/Coroutine.sln new file mode 100644 index 0000000..1b25596 --- /dev/null +++ b/Coroutine.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Coroutine", "Coroutine\Coroutine.csproj", "{1657964D-2503-426A-8514-D020660BEE4D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{8BE6B559-927D-47A6-8253-D7D809D337AF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1657964D-2503-426A-8514-D020660BEE4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1657964D-2503-426A-8514-D020660BEE4D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1657964D-2503-426A-8514-D020660BEE4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1657964D-2503-426A-8514-D020660BEE4D}.Release|Any CPU.Build.0 = Release|Any CPU + {8BE6B559-927D-47A6-8253-D7D809D337AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8BE6B559-927D-47A6-8253-D7D809D337AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8BE6B559-927D-47A6-8253-D7D809D337AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8BE6B559-927D-47A6-8253-D7D809D337AF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Coroutine/Coroutine.cs b/Coroutine/Coroutine.cs new file mode 100644 index 0000000..ab276de --- /dev/null +++ b/Coroutine/Coroutine.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; + +namespace Coroutine { + internal class Coroutine { + + private readonly IEnumerator enumerator; + + public Coroutine(IEnumerator enumerator) { + this.enumerator = enumerator; + this.enumerator.MoveNext(); + } + + public bool Tick(double deltaSeconds) { + var curr = this.enumerator.Current; + if (curr != null && curr.Tick(deltaSeconds)) { + if (!this.enumerator.MoveNext()) + return true; + } + return false; + } + + public bool OnEvent(Event evt) { + var curr = this.enumerator.Current; + if (curr != null && curr.OnEvent(evt)) { + if (!this.enumerator.MoveNext()) + return true; + } + return false; + } + + public WaitType GetCurrentType() { + return this.enumerator.Current.GetWaitType(); + } + + } +} \ No newline at end of file diff --git a/Coroutine/Coroutine.csproj b/Coroutine/Coroutine.csproj new file mode 100644 index 0000000..fd2d995 --- /dev/null +++ b/Coroutine/Coroutine.csproj @@ -0,0 +1,58 @@ + + + + + Debug + AnyCPU + {1657964D-2503-426A-8514-D020660BEE4D} + Library + Properties + Coroutine + Coroutine + v4.7.2 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + diff --git a/Coroutine/CoroutineHandler.cs b/Coroutine/CoroutineHandler.cs new file mode 100644 index 0000000..ec50c5e --- /dev/null +++ b/Coroutine/CoroutineHandler.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; + +namespace Coroutine { + public static class CoroutineHandler { + + private static readonly List TickingCoroutines = new List(); + private static readonly List EventCoroutines = new List(); + + public static void Start(IEnumerator coroutine) { + var inst = new Coroutine(coroutine); + var type = inst.GetCurrentType(); + if (type == WaitType.Tick) + TickingCoroutines.Add(inst); + else if (type == WaitType.Event) + EventCoroutines.Add(inst); + } + + public static void Tick(double deltaSeconds) { + for (var i = TickingCoroutines.Count - 1; i >= 0; i--) { + var coroutine = TickingCoroutines[i]; + if (coroutine.Tick(deltaSeconds)) { + TickingCoroutines.RemoveAt(i); + } else if (coroutine.GetCurrentType() != WaitType.Tick) { + TickingCoroutines.RemoveAt(i); + EventCoroutines.Add(coroutine); + } + } + } + + public static void RaiseEvent(Event evt) { + for (var i = EventCoroutines.Count - 1; i >= 0; i--) { + var coroutine = EventCoroutines[i]; + if (coroutine.OnEvent(evt)) { + EventCoroutines.RemoveAt(i); + } else if (coroutine.GetCurrentType() != WaitType.Event) { + EventCoroutines.RemoveAt(i); + TickingCoroutines.Add(coroutine); + } + } + } + + } +} \ No newline at end of file diff --git a/Coroutine/Event.cs b/Coroutine/Event.cs new file mode 100644 index 0000000..3ad04d6 --- /dev/null +++ b/Coroutine/Event.cs @@ -0,0 +1,7 @@ +namespace Coroutine { + public class Event { + + + + } +} \ No newline at end of file diff --git a/Coroutine/Properties/AssemblyInfo.cs b/Coroutine/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..0adf7e4 --- /dev/null +++ b/Coroutine/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Coroutine")] +[assembly: AssemblyDescription("A simple implementation of Unity's Coroutines to be used for any C# project")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Ellpeck")] +[assembly: AssemblyProduct("Coroutine")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1657964D-2503-426A-8514-D020660BEE4D")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Coroutine/Wait.cs b/Coroutine/Wait.cs new file mode 100644 index 0000000..ebfba88 --- /dev/null +++ b/Coroutine/Wait.cs @@ -0,0 +1,24 @@ +using System; + +namespace Coroutine { + public abstract class Wait { + + public abstract WaitType GetWaitType(); + + public virtual bool Tick(double deltaSeconds) { + throw new NotSupportedException(); + } + + public virtual bool OnEvent(Event evt) { + throw new NotSupportedException(); + } + + } + + public enum WaitType { + + Tick, + Event + + } +} \ No newline at end of file diff --git a/Coroutine/WaitEvent.cs b/Coroutine/WaitEvent.cs new file mode 100644 index 0000000..af78286 --- /dev/null +++ b/Coroutine/WaitEvent.cs @@ -0,0 +1,19 @@ +namespace Coroutine { + public class WaitEvent : Wait { + + private readonly Event evt; + + public WaitEvent(Event evt) { + this.evt = evt; + } + + public override WaitType GetWaitType() { + return WaitType.Event; + } + + public override bool OnEvent(Event evt) { + return evt == this.evt; + } + + } +} \ No newline at end of file diff --git a/Coroutine/WaitSeconds.cs b/Coroutine/WaitSeconds.cs new file mode 100644 index 0000000..e5a4c7c --- /dev/null +++ b/Coroutine/WaitSeconds.cs @@ -0,0 +1,20 @@ +namespace Coroutine { + public class WaitSeconds : Wait { + + private double seconds; + + public WaitSeconds(double seconds) { + this.seconds = seconds; + } + + public override WaitType GetWaitType() { + return WaitType.Tick; + } + + public override bool Tick(double deltaSeconds) { + this.seconds -= deltaSeconds; + return this.seconds <= 0; + } + + } +} \ No newline at end of file diff --git a/README.md b/README.md index 98ac056..b6c4095 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# Coroutines +# Coroutine A simple implementation of Unity's Coroutines to be used for any C# project diff --git a/Test/Example.cs b/Test/Example.cs new file mode 100644 index 0000000..7956f38 --- /dev/null +++ b/Test/Example.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using Coroutine; + +namespace Test { + internal static class Example { + + private static readonly Event TestEvent = new Event(); + + public static void Main() { + CoroutineHandler.Start(WaitSeconds()); + CoroutineHandler.Start(RaiseTestEvent()); + CoroutineHandler.Start(WaitForTestEvent()); + CoroutineHandler.Start(PrintEvery5Seconds()); + + var lastTime = DateTime.Now; + while (true) { + var currTime = DateTime.Now; + CoroutineHandler.Tick((currTime - lastTime).TotalSeconds); + lastTime = currTime; + Thread.Sleep(1); + } + } + + private static IEnumerator WaitSeconds() { + Console.WriteLine("First thing " + DateTime.Now); + yield return new WaitSeconds(1); + Console.WriteLine("After 1 second " + DateTime.Now); + yield return new WaitSeconds(5); + Console.WriteLine("After 5 seconds " + DateTime.Now); + yield return new WaitSeconds(10); + Console.WriteLine("After 10 seconds " + DateTime.Now); + } + + private static IEnumerator RaiseTestEvent() { + yield return new WaitSeconds(10); + Console.WriteLine("Raising test event"); + CoroutineHandler.RaiseEvent(TestEvent); + } + + private static IEnumerator WaitForTestEvent() { + yield return new WaitSeconds(5); + Console.WriteLine("Waited 5 seconds before waiting for the event"); + yield return new WaitEvent(TestEvent); + Console.WriteLine("Test event received"); + } + + private static IEnumerator PrintEvery5Seconds() { + while (true) { + yield return new WaitSeconds(10); + Console.WriteLine("The time is " + DateTime.Now); + } + } + + } +} \ No newline at end of file diff --git a/Test/Test.csproj b/Test/Test.csproj new file mode 100644 index 0000000..ed472fc --- /dev/null +++ b/Test/Test.csproj @@ -0,0 +1,58 @@ + + + + + Debug + AnyCPU + {8BE6B559-927D-47A6-8253-D7D809D337AF} + Exe + Properties + Test + Test + v4.7.2 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + {1657964d-2503-426a-8514-d020660bee4d} + Coroutine + + + + + +