Skip to content

Commit

Permalink
Merge pull request #7 from BastianBlokland/feature/keep-executers-whe…
Browse files Browse the repository at this point in the history
…n-work-done

Keep executors after work is done.
  • Loading branch information
BastianBlokland authored Jul 24, 2019
2 parents 519508a + 2394839 commit 4fe2ac8
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 91 deletions.
2 changes: 1 addition & 1 deletion src/ComponentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ internal static ITaskRunner GetTaskRunnerUnchecked(Component component, TaskRunO
foreach (var runner in monoBehaviourRunners)
{
// If there is a runner for that component then return that.
if (!runner.IsFinished && runner.RunOptions == options && runner.ComponentToFollow == component)
if (runner.RunOptions == options && runner.ComponentToFollow == component)
return runner;
}

Expand Down
75 changes: 18 additions & 57 deletions src/ComponentTask/Internal/MonoBehaviourTaskRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,61 +18,33 @@ public MonoBehaviourTaskRunner()

public Component ComponentToFollow { get; set; }

public bool IsFinished { get; private set; }
public Task StartTask(Func<Task> taskCreator) =>
this.taskRunner.StartTask(taskCreator);

public Task StartTask(Func<Task> taskCreator)
{
System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner");
return this.taskRunner.StartTask(taskCreator);
}
public Task StartTask(Func<CancellationToken, Task> taskCreator) =>
this.taskRunner.StartTask(taskCreator);

public Task StartTask(Func<CancellationToken, Task> taskCreator)
{
System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner");
return this.taskRunner.StartTask(taskCreator);
}
public Task StartTask<TIn>(Func<TIn, Task> taskCreator, TIn data) =>
this.taskRunner.StartTask(taskCreator, data);

public Task StartTask<TIn>(Func<TIn, Task> taskCreator, TIn data)
{
System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner");
return this.taskRunner.StartTask(taskCreator, data);
}
public Task StartTask<TIn>(Func<TIn, CancellationToken, Task> taskCreator, TIn data) =>
this.taskRunner.StartTask(taskCreator, data);

public Task StartTask<TIn>(Func<TIn, CancellationToken, Task> taskCreator, TIn data)
{
System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner");
return this.taskRunner.StartTask(taskCreator, data);
}
public Task<TOut> StartTask<TOut>(Func<Task<TOut>> taskCreator) =>
this.taskRunner.StartTask(taskCreator);

public Task<TOut> StartTask<TOut>(Func<Task<TOut>> taskCreator)
{
System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner");
return this.taskRunner.StartTask(taskCreator);
}
public Task<TOut> StartTask<TOut>(Func<CancellationToken, Task<TOut>> taskCreator) =>
this.taskRunner.StartTask(taskCreator);

public Task<TOut> StartTask<TOut>(Func<CancellationToken, Task<TOut>> taskCreator)
{
System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner");
return this.taskRunner.StartTask(taskCreator);
}
public Task<TOut> StartTask<TIn, TOut>(Func<TIn, Task<TOut>> taskCreator, TIn data) =>
this.taskRunner.StartTask(taskCreator, data);

public Task<TOut> StartTask<TIn, TOut>(Func<TIn, Task<TOut>> taskCreator, TIn data)
{
System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner");
return this.taskRunner.StartTask(taskCreator, data);
}

public Task<TOut> StartTask<TIn, TOut>(Func<TIn, CancellationToken, Task<TOut>> taskCreator, TIn data)
{
System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner");
return this.taskRunner.StartTask(taskCreator, data);
}
public Task<TOut> StartTask<TIn, TOut>(Func<TIn, CancellationToken, Task<TOut>> taskCreator, TIn data) =>
this.taskRunner.StartTask(taskCreator, data);

// Dynamically called from the Unity runtime.
private void LateUpdate()
{
System.Diagnostics.Debug.Assert(!this.IsFinished, "Already finished runner was updated");

// Check if we have a 'ComponentToFollow' assigned.
if (this.ComponentToFollow is null)
{
Expand Down Expand Up @@ -106,20 +78,9 @@ private void LateUpdate()
// Dynamically called from the Unity runtime.
private void OnDestroy() => this.taskRunner.Dispose();

private void Execute()
{
var workRemaining = this.taskRunner.Execute();

// If we've finished all the work then destroy ourselves.
if (!workRemaining)
this.Destroy();
}
private void Execute() => this.taskRunner.Execute();

private void Destroy()
{
this.IsFinished = true;
UnityEngine.Object.Destroy(this);
}
private void Destroy() => UnityEngine.Object.Destroy(this);

void IExceptionHandler.Handle(Exception exception)
{
Expand Down
8 changes: 1 addition & 7 deletions src/ComponentTask/LocalTaskRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,11 @@ public Task<TOut> StartTask<TIn, TOut>(Func<TIn, CancellationToken, Task<TOut>>
/// <summary>
/// Execute all the work that was 'scheduled' by the tasks running on this runner.
/// </summary>
/// <returns>True if still running work, False if all work has finished.</returns>
public bool Execute()
public void Execute()
{
if (this.isDisposed)
throw new ObjectDisposedException(nameof(LocalTaskRunner));

bool tasksRemaining;
try
{
// Execute all the work that was scheduled on this runner.
Expand All @@ -194,12 +192,8 @@ public bool Execute()
if (this.runningTasks[i].IsFinished)
this.runningTasks.RemoveAt(i);
}

tasksRemaining = this.runningTasks.Count > 0;
}
}

return tasksRemaining;
}

/// <inheritdoc/>
Expand Down
26 changes: 0 additions & 26 deletions tests/playmode/ComponentExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,32 +372,6 @@ async Task TestAsync()
}
}

[UnityTest]
public IEnumerator RunnerDestroysItselfWhenWorkIsDone()
{
var go = new GameObject("TestGameObject");
var comp = go.AddComponent<MockComponent>();
comp.StartTask(TestAsync);

// Assert that runner was created.
Assert.AreEqual(2, go.GetComponents<MonoBehaviour>().Length);

// Wait for work to finish.
yield return null;

// Assert that runner has destroyed itself.
Assert.AreEqual(1, go.GetComponents<MonoBehaviour>().Length);

// Cleanup.
yield return null;
Object.Destroy(go);

async Task TestAsync()
{
await Task.Yield();
}
}

[UnityTest]
public IEnumerator ThrowsWhenCalledFromNonUnityThread()
{
Expand Down

0 comments on commit 4fe2ac8

Please sign in to comment.