Skip to content

Commit

Permalink
Merge pull request #2 from daihaminkey/godot-4
Browse files Browse the repository at this point in the history
Add Godot 4 support
  • Loading branch information
Atlinx authored Mar 31, 2023
2 parents 76663b3 + 3c03477 commit 69678b2
Show file tree
Hide file tree
Showing 151 changed files with 173 additions and 6,572 deletions.
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Godot 4+ specific ignores
.godot/

# Godot-specific ignores
.import/
export.cfg
Expand All @@ -7,6 +10,9 @@ export_presets.cfg
.mono/
data_*/

# IntelliJ
.idea/

# VSCode Settings
.vscode/

Expand All @@ -21,4 +27,7 @@ obj/

# Tests
tests/results.xml
tests/metadata.json
tests/metadata.json

# MacOS
.DS_Store
5 changes: 3 additions & 2 deletions GDTask.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Godot.NET.Sdk/3.3.0">
<Project Sdk="Godot.NET.Sdk/4.0.0">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup>
<ItemGroup>
<Folder Include="tests\manual\" />
Expand Down
95 changes: 49 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# GDTask ✅

![Deploy](https://github.com/Fractural/GDTask/actions/workflows/deploy.yml/badge.svg) ![Unit Tests](https://github.com/Fractural/GDTask/actions/workflows/tests.yml/badge.svg)
> **NOTE:**
>
> This branch is for the Godot 4.x version of the addon.
> You can download the Godot 3.x version from the main branch.
Adds async/await features in Godot for easier async coding.
Based on code from [Cysharp's UniTask library for Unity](https://github.com/Cysharp/UniTask).
Expand All @@ -10,50 +13,50 @@ using Fractural.Tasks;

public Test : Node
{
public override _Ready()
{
// Running a task from a non-async method
Run().Forget();
}

public async GDTaskVoid Run()
{
await GDTask.DelayFrame(100);

// waiting some amount of time
await GDTask.Delay(TimeSpan.FromSeconds(10));

// Waiting a single frame
await GDTask.Yield();
await GDTask.NextFrame();
await GDTask.WaitForEndOfFrame();

// Waiting for specific lifetime call
await GDTask.WaitForPhysicsProcess();

// Cancellation
var cts = new CancellationTokenSource();
CancellableReallyLongTask(cts.Token).Forget();
await GDTask.Delay(TimeSpan.FromSeconds(3));
cts.Cancel();

// Async await with return value
string result = await RunWithResult();
return result + " with additional text";
}

public async GDTask<string> RunWithResult()
{
await GDTask.Delay(TimeSpan.FromSeconds(3));
return "A result string";
}

public async GDTaskVoid ReallyLongTask(CancellationToken cancellationToken)
{
GD.Print("Starting long task.");
await GDTask.Delay(TimeSpan.FromSeconds(1000000), cancellationToken: cancellationToken);
GD.Print("Finished long task.");
}
public override _Ready()
{
// Running a task from a non-async method
Run().Forget();
}

public async GDTaskVoid Run()
{
await GDTask.DelayFrame(100);

// waiting some amount of time
await GDTask.Delay(TimeSpan.FromSeconds(10));

// Waiting a single frame
await GDTask.Yield();
await GDTask.NextFrame();
await GDTask.WaitForEndOfFrame();

// Waiting for specific lifetime call
await GDTask.WaitForPhysicsProcess();

// Cancellation
var cts = new CancellationTokenSource();
CancellableReallyLongTask(cts.Token).Forget();
await GDTask.Delay(TimeSpan.FromSeconds(3));
cts.Cancel();

// Async await with return value
string result = await RunWithResult();
return result + " with additional text";
}

public async GDTask<string> RunWithResult()
{
await GDTask.Delay(TimeSpan.FromSeconds(3));
return "A result string";
}

public async GDTaskVoid ReallyLongTask(CancellationToken cancellationToken)
{
GD.Print("Starting long task.");
await GDTask.Delay(TimeSpan.FromSeconds(1000000), cancellationToken: cancellationToken);
GD.Print("Finished long task.");
}
}
```

Expand All @@ -73,4 +76,4 @@ Git Submodules
git submodule add -b release https://github.com/fractural/GDTask.git addons/GDTask
```

3. Add `addons/GDTask/Autoload/GDTaskPlayerLoopAutoload` as an autoload
3. Add `addons/GDTask/Autoload/GDTaskPlayerLoopAutoload` as an autoload
4 changes: 2 additions & 2 deletions addons/GDTask/AsyncLazy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Fractural.Tasks
{
public class AsyncLazy
public partial class AsyncLazy
{
static Action<object> continuation = SetCompletionSource;

Expand Down Expand Up @@ -122,7 +122,7 @@ static void SetCompletionSource(object state)
}
}

public class AsyncLazy<T>
public partial class AsyncLazy<T>
{
static Action<object> continuation = SetCompletionSource;

Expand Down
10 changes: 5 additions & 5 deletions addons/GDTask/Autoload/GDTaskPlayerLoopAutoload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public interface IPlayerLoopItem
/// <summary>
/// Singleton that forwards Godot calls and values to GDTasks.
/// </summary>
public class GDTaskPlayerLoopAutoload : Node
public partial class GDTaskPlayerLoopAutoload : Node
{
public static int MainThreadId => Global.mainThreadId;
public static bool IsMainThread => System.Threading.Thread.CurrentThread.ManagedThreadId == Global.mainThreadId;
Expand Down Expand Up @@ -81,8 +81,8 @@ public void LocalAddContinuation(PlayerLoopTiming timing, Action continuation)
}

public static GDTaskPlayerLoopAutoload Global { get; private set; }
public float DeltaTime => GetProcessDeltaTime();
public float PhysicsDeltaTime => GetPhysicsProcessDeltaTime();
public double DeltaTime => GetProcessDeltaTime();
public double PhysicsDeltaTime => GetPhysicsProcessDeltaTime();

private int mainThreadId;
private ContinuationQueue[] yielders;
Expand Down Expand Up @@ -124,13 +124,13 @@ public override void _Notification(int what)
}
}

public override void _Process(float delta)
public override void _Process(double delta)
{
yielders[(int) PlayerLoopTiming.Process].Run();
runners[(int) PlayerLoopTiming.Process].Run();
}

public override void _PhysicsProcess(float delta)
public override void _PhysicsProcess(double delta)
{
yielders[(int) PlayerLoopTiming.PhysicsProcess].Run();
runners[(int) PlayerLoopTiming.PhysicsProcess].Run();
Expand Down
4 changes: 2 additions & 2 deletions addons/GDTask/CancellationTokenEqualityComparer.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading;

namespace Fractural.Tasks
{
public class CancellationTokenEqualityComparer : IEqualityComparer<CancellationToken>
public partial class CancellationTokenEqualityComparer : IEqualityComparer<CancellationToken>
{
public static readonly IEqualityComparer<CancellationToken> Default = new CancellationTokenEqualityComparer();

Expand Down
8 changes: 4 additions & 4 deletions addons/GDTask/GDTask.Delay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public static GDTask WaitForPhysicsProcess(CancellationToken cancellationToken)

#if DEBUG
// force use Realtime.
if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.EditorHint)
if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.IsEditorHint())
{
delayType = DelayType.Realtime;
}
Expand Down Expand Up @@ -431,7 +431,7 @@ public bool MoveNext()
{
#if DEBUG
// force use Realtime.
if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.EditorHint)
if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.IsEditorHint())
{
//goto ++currentFrameCount
}
Expand Down Expand Up @@ -477,8 +477,8 @@ static DelayPromise()
}

int initialFrame;
float delayTimeSpan;
float elapsed;
double delayTimeSpan;
double elapsed;
CancellationToken cancellationToken;

GDTaskCompletionSourceCore<object> core;
Expand Down
6 changes: 3 additions & 3 deletions addons/GDTask/GDTask.WaitUntil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static GDTask WaitUntilCanceled(CancellationToken cancellationToken, Play
public static GDTask<U> WaitUntilValueChanged<T, U>(T target, Func<T, U> monitorFunction, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Process, IEqualityComparer<U> equalityComparer = null, CancellationToken cancellationToken = default(CancellationToken))
where T : class
{
var isGodotObject = target is Godot.Object; // don't use (unityObject == null)
var isGodotObject = target is Godot.GodotObject; // don't use (unityObject == null)

return new GDTask<U>(isGodotObject
? WaitUntilValueChangedGodotObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out var token)
Expand Down Expand Up @@ -343,7 +343,7 @@ static WaitUntilValueChangedGodotObjectPromise()
}

T target;
Godot.Object targetAsGodotObject;
Godot.GodotObject targetAsGodotObject;
U currentValue;
Func<T, U> monitorFunction;
IEqualityComparer<U> equalityComparer;
Expand All @@ -368,7 +368,7 @@ public static IGDTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqu
}

result.target = target;
result.targetAsGodotObject = target as Godot.Object;
result.targetAsGodotObject = target as Godot.GodotObject;
result.monitorFunction = monitorFunction;
result.currentValue = monitorFunction(target);
result.equalityComparer = equalityComparer ?? GodotEqualityComparer.GetDefault<U>();
Expand Down
10 changes: 5 additions & 5 deletions addons/GDTask/GDTaskCompletionSource.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -314,7 +314,7 @@ private static void CompletionSentinel(object _) // named method to aid debuggin
}
}

public class AutoResetGDTaskCompletionSource : IGDTaskSource, ITaskPoolNode<AutoResetGDTaskCompletionSource>, IPromise
public partial class AutoResetGDTaskCompletionSource : IGDTaskSource, ITaskPoolNode<AutoResetGDTaskCompletionSource>, IPromise
{
static TaskPool<AutoResetGDTaskCompletionSource> pool;
AutoResetGDTaskCompletionSource nextNode;
Expand Down Expand Up @@ -437,7 +437,7 @@ bool TryReturn()
}
}

public class AutoResetGDTaskCompletionSource<T> : IGDTaskSource<T>, ITaskPoolNode<AutoResetGDTaskCompletionSource<T>>, IPromise<T>
public partial class AutoResetGDTaskCompletionSource<T> : IGDTaskSource<T>, ITaskPoolNode<AutoResetGDTaskCompletionSource<T>>, IPromise<T>
{
static TaskPool<AutoResetGDTaskCompletionSource<T>> pool;
AutoResetGDTaskCompletionSource<T> nextNode;
Expand Down Expand Up @@ -565,7 +565,7 @@ bool TryReturn()
}
}

public class GDTaskCompletionSource : IGDTaskSource, IPromise
public partial class GDTaskCompletionSource : IGDTaskSource, IPromise
{
CancellationToken cancellationToken;
ExceptionHolder exception;
Expand Down Expand Up @@ -746,7 +746,7 @@ bool TrySignalCompletion(GDTaskStatus status)
}
}

public class GDTaskCompletionSource<T> : IGDTaskSource<T>, IPromise<T>
public partial class GDTaskCompletionSource<T> : IGDTaskSource<T>, IPromise<T>
{
CancellationToken cancellationToken;
T result;
Expand Down
4 changes: 2 additions & 2 deletions addons/GDTask/GDTaskSynchronizationContext.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using Godot;
using Godot;
using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace Fractural.Tasks
{
public class GDTaskSynchronizationContext : SynchronizationContext
public partial class GDTaskSynchronizationContext : SynchronizationContext
{
const int MaxArrayLength = 0X7FEFFFFF;
const int InitialSize = 16;
Expand Down
Loading

0 comments on commit 69678b2

Please sign in to comment.