Skip to content

Commit 9cf72f8

Browse files
Merge pull request #26 from CoderGamester/develop
Release 0.15.0
2 parents 79a3c51 + 413e40b commit 9cf72f8

File tree

6 files changed

+190
-64
lines changed

6 files changed

+190
-64
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this package will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [0.15.0] - 2025-01-05
8+
9+
**New**:
10+
- Added *StartDelayCall* method to *ICoroutineService* to allow deferred methods to be safely executed within the bounds of a Unity Coroutine
11+
- Added the possibility to know the current state of an *IAsyncCoroutine*
12+
- Added the access to the Sample Entity used to generete new entites within an *IObjectPool<T>* and destroy it when disposing the object pool
13+
- Added the possibility to reset an *IObjectPool<T>* to a new state
14+
715
## [0.14.1] - 2024-11-30
816

917
**Fixed**:

Runtime/CoroutineService.cs

Lines changed: 97 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using UnityEngine;
4+
using Action = System.Action;
45
using Object = UnityEngine.Object;
56

67
// ReSharper disable once CheckNamespace
@@ -13,6 +14,10 @@ namespace GameLovers.Services
1314
/// </summary>
1415
public interface IAsyncCoroutine
1516
{
17+
/// <summary>
18+
/// Get the execution status of the coroutine
19+
/// </summary>
20+
bool IsRunning { get; }
1621
/// <summary>
1722
/// Get the complete operation status of the coroutine
1823
/// </summary>
@@ -21,30 +26,34 @@ public interface IAsyncCoroutine
2126
/// Get the current coroutine being executed
2227
/// </summary>
2328
Coroutine Coroutine { get; }
29+
/// <summary>
30+
/// The Unity time the coroutine started
31+
/// </summary>
32+
float StartTime { get; }
2433

2534
/// <summary>
2635
/// Sets the action <paramref name="onComplete"/> callback to be invoked when the coroutine is completed
2736
/// </summary>
2837
void OnComplete(Action onComplete);
38+
/// <summary>
39+
/// Stops the execution of this coroutine
40+
/// </summary>
41+
void StopCoroutine(bool triggerOnComplete = false);
2942
}
3043

31-
/// <inheritdoc cref="IAsyncCoroutine"/>
32-
public interface IAsyncCoroutine<T>
44+
/// <inheritdoc />
45+
public interface IAsyncCoroutine<T> : IAsyncCoroutine
3346
{
34-
/// <inheritdoc cref="IAsyncCoroutine.IsCompleted"/>
35-
bool IsCompleted { get; }
36-
/// <inheritdoc cref="IAsyncCoroutine.Coroutine"/>
37-
Coroutine Coroutine { get; }
3847
/// <summary>
3948
/// The data to be returned on the coroutine completion
4049
/// </summary>
41-
T Data { get; }
50+
T Data { get; set; }
4251

4352
/// <summary>
4453
/// Sets the action <paramref name="onComplete"/> callback to be invoked when the coroutine is completed with the
45-
/// <paramref name="data"/> reference in the callback
54+
/// <seealso cref="Data"/> reference in the callback
4655
/// </summary>
47-
void OnComplete(T data, Action<T> onComplete);
56+
void OnComplete(Action<T> onComplete);
4857
}
4958

5059
/// <summary>
@@ -70,9 +79,20 @@ public interface ICoroutineService : IDisposable
7079
IAsyncCoroutine StartAsyncCoroutine(IEnumerator routine);
7180
/// <summary>
7281
/// Follows the same principle and execution of <see cref="MonoBehaviour.StartCoroutine(IEnumerator)"/> but returns
73-
/// a <see cref="IAsyncCoroutine{T}"/> to provide a callback on complete of the coroutine with given <typeparamref name="T"/> type
82+
/// a <see cref="IAsyncCoroutine{T}"/> to provide a callback on complete of the coroutine with given <paramref name="data"/>
7483
/// </summary>
75-
IAsyncCoroutine<T> StartAsyncCoroutine<T>(IEnumerator routine);
84+
IAsyncCoroutine<T> StartAsyncCoroutine<T>(IEnumerator routine, T data);
85+
/// <summary>
86+
/// Executes <paramref name="call"/> in a <see cref="StartAsyncCoroutine"/> with the given <paramref name="delay"/>.
87+
/// Useful for delay callbacks
88+
/// </summary>
89+
IAsyncCoroutine StartDelayCall(Action call, float delay);
90+
/// <summary>
91+
/// Executes <paramref name="call"/> in a <see cref="StartAsyncCoroutine"/> with the given <paramref name="delay"/>
92+
/// and <paramref name="data"/> data type.
93+
/// Useful for delay callbacks
94+
/// </summary>
95+
IAsyncCoroutine<T> StartDelayCall<T>(Action<T> call, T data,float delay);
7696
/// <inheritdoc cref="MonoBehaviour.StopCoroutine(Coroutine)"/>
7797
void StopCoroutine(Coroutine coroutine);
7898
/// <inheritdoc cref="MonoBehaviour.StopAllCoroutines"/>
@@ -86,7 +106,7 @@ public class CoroutineService : ICoroutineService
86106

87107
public CoroutineService()
88108
{
89-
var gameObject = new GameObject(typeof(CoroutineServiceMonoBehaviour).Name);
109+
var gameObject = new GameObject(nameof(CoroutineServiceMonoBehaviour));
90110

91111
_serviceObject = gameObject.AddComponent<CoroutineServiceMonoBehaviour>();
92112

@@ -120,23 +140,45 @@ public Coroutine StartCoroutine(IEnumerator routine)
120140
/// <inheritdoc />
121141
public IAsyncCoroutine StartAsyncCoroutine(IEnumerator routine)
122142
{
123-
var asyncCoroutine = new AsyncCoroutine();
143+
var asyncCoroutine = new AsyncCoroutine(this);
124144

125145
asyncCoroutine.SetCoroutine(_serviceObject.ExternalStartCoroutine(InternalCoroutine(routine, asyncCoroutine)));
126146

127147
return asyncCoroutine;
128148
}
129149

130150
/// <inheritdoc />
131-
public IAsyncCoroutine<T> StartAsyncCoroutine<T>(IEnumerator routine)
151+
public IAsyncCoroutine<T> StartAsyncCoroutine<T>(IEnumerator routine, T data)
132152
{
133-
var asyncCoroutine = new AsyncCoroutine<T>();
153+
var asyncCoroutine = new AsyncCoroutine<T>(this, data);
134154

135155
asyncCoroutine.SetCoroutine(_serviceObject.ExternalStartCoroutine(InternalCoroutine(routine, asyncCoroutine)));
136156

137157
return asyncCoroutine;
138158
}
139-
159+
160+
/// <inheritdoc />
161+
public IAsyncCoroutine StartDelayCall(Action call, float delay)
162+
{
163+
var asyncCoroutine = new AsyncCoroutine(this);
164+
165+
asyncCoroutine.OnComplete(call);
166+
asyncCoroutine.SetCoroutine(_serviceObject.ExternalStartCoroutine(InternalDelayCoroutine(delay, asyncCoroutine)));
167+
168+
return asyncCoroutine;
169+
}
170+
171+
/// <inheritdoc />
172+
public IAsyncCoroutine<T> StartDelayCall<T>(Action<T> call, T data, float delay)
173+
{
174+
var asyncCoroutine = new AsyncCoroutine<T>(this, data);
175+
176+
asyncCoroutine.OnComplete(call);
177+
asyncCoroutine.SetCoroutine(_serviceObject.ExternalStartCoroutine(InternalDelayCoroutine(delay, asyncCoroutine)));
178+
179+
return asyncCoroutine;
180+
}
181+
140182
/// <inheritdoc />
141183
public void StopCoroutine(Coroutine coroutine)
142184
{
@@ -165,22 +207,38 @@ private static IEnumerator InternalCoroutine(IEnumerator routine, ICompleteCorou
165207

166208
completed.Completed();
167209
}
210+
211+
private static IEnumerator InternalDelayCoroutine(float delayInSeconds, ICompleteCoroutine completed)
212+
{
213+
yield return new WaitForSeconds(delayInSeconds);
214+
215+
completed.Completed();
216+
}
168217

169218
#region Private Interfaces
170219

171220
private interface ICompleteCoroutine
172221
{
173222
void Completed();
174-
175-
void SetCoroutine(Coroutine coroutine);
176223
}
177224

178225
private class AsyncCoroutine : IAsyncCoroutine, ICompleteCoroutine
179226
{
227+
private readonly ICoroutineService _coroutineService;
228+
180229
private Action _onComplete;
181230

231+
public bool IsRunning => Coroutine != null;
182232
public bool IsCompleted { get; private set; }
183233
public Coroutine Coroutine { get; private set; }
234+
public float StartTime { get; } = Time.time;
235+
236+
private AsyncCoroutine() {}
237+
238+
public AsyncCoroutine(ICoroutineService coroutineService)
239+
{
240+
_coroutineService = coroutineService;
241+
}
184242

185243
public void SetCoroutine(Coroutine coroutine)
186244
{
@@ -192,6 +250,13 @@ public void OnComplete(Action onComplete)
192250
_onComplete = onComplete;
193251
}
194252

253+
public void StopCoroutine(bool triggerOnComplete = false)
254+
{
255+
_coroutineService.StopCoroutine(Coroutine);
256+
257+
OnCompleteTrigger();
258+
}
259+
195260
public void Completed()
196261
{
197262
if (IsCompleted)
@@ -201,41 +266,35 @@ public void Completed()
201266

202267
IsCompleted = true;
203268
Coroutine = null;
204-
269+
270+
OnCompleteTrigger();
271+
}
272+
273+
protected virtual void OnCompleteTrigger()
274+
{
205275
_onComplete?.Invoke();
206276
}
207277
}
208278

209-
private class AsyncCoroutine<T> : IAsyncCoroutine<T>, ICompleteCoroutine
279+
private class AsyncCoroutine<T> : AsyncCoroutine, IAsyncCoroutine<T>
210280
{
211281
private Action<T> _onComplete;
212-
213-
public bool IsCompleted { get; private set; }
214-
public Coroutine Coroutine { get; private set; }
215-
public T Data { get; private set; }
282+
283+
public T Data { get; set; }
216284

217-
public void SetCoroutine(Coroutine coroutine)
285+
public AsyncCoroutine(ICoroutineService coroutineService, T data) : base(coroutineService)
218286
{
219-
Coroutine = coroutine;
287+
Data = data;
220288
}
221289

222-
public void OnComplete(T data, Action<T> onComplete)
290+
public void OnComplete(Action<T> onComplete)
223291
{
224292
_onComplete = onComplete;
225-
226-
Data = data;
227293
}
228294

229-
public void Completed()
295+
protected override void OnCompleteTrigger()
230296
{
231-
if (IsCompleted)
232-
{
233-
return;
234-
}
235-
236-
IsCompleted = true;
237-
Coroutine = null;
238-
297+
base.OnCompleteTrigger();
239298
_onComplete?.Invoke(Data);
240299
}
241300
}

0 commit comments

Comments
 (0)