Skip to content

Commit 95cc9b0

Browse files
Merge pull request #3 from CoderGamester/develop
0.3.0
2 parents dc14561 + adf16e0 commit 95cc9b0

9 files changed

Lines changed: 115 additions & 166 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,25 @@ 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+
8+
## [0.3.0] - 2020-02-09
9+
10+
- Now the *MainInstaller* checks the object binding relationship in compile time
11+
- The *CoroutineService* no longer fails on null coroutines
12+
- Improved the *ObjectPools* helper classes with a now static global instatiator for game objects.
13+
14+
**Changed**:
15+
- Now the *PoolService* is only a service container for objects pools and no longer creates/initializes new pools.
16+
- Removed *Pool.Clear* functionality. Use *DespawnAll* or delete the pool instead
17+
718
## [0.2.0] - 2020-01-19
819

920
- Added new *ObjectPool* & *GameObjectPool* pools to allow to allow to use object pools independent from the *PoolService*. This allows to have different pools of the same type in the project in different object controllers
1021
- Added new interface *IPoolEntityClear* that allows a callback method for entities when they are cleared from the pool
1122
- Added new unit tests for the *ObjectPool*
1223

1324
**Changed**:
14-
- Now the PoolService.Clear() does not take any action parameters. To have a callback when the entity is cleared, please have the entity implement the *IPoolEntityClear* interface
25+
- Now the *PoolService.Clear()* does not take any action parameters. To have a callback when the entity is cleared, please have the entity implement the *IPoolEntityClear* interface
1526

1627
## [0.1.1] - 2020-01-06
1728

Runtime/CoroutineService.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,18 @@ public IAsyncCoroutine<T> StartAsyncCoroutine<T>(IEnumerator routine)
140140
/// <inheritdoc />
141141
public void StopCoroutine(Coroutine coroutine)
142142
{
143-
_serviceObject.ExternalStopCoroutine(coroutine);
143+
if (coroutine == null)
144+
{
145+
return;
146+
}
147+
148+
_serviceObject?.ExternalStopCoroutine(coroutine);
144149
}
145150

146151
/// <inheritdoc />
147152
public void StopAllCoroutines()
148153
{
149-
_serviceObject.StopAllCoroutines();
154+
_serviceObject?.StopAllCoroutines();
150155
}
151156

152157
private static IEnumerator InternalCoroutine(IEnumerator routine, ICompleteCoroutine completed)

Runtime/MainInstaller.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public static class MainInstaller
2222
/// <exception cref="ArgumentException">
2323
/// Thrown if the given <paramref name="instance"/> doesn't implement <typeparamref name="T"/> interface
2424
/// </exception>
25-
public static void Bind<T>(object instance) where T : class
25+
public static void Bind<T>(T instance) where T : class
2626
{
2727
var type = typeof(T);
2828

@@ -31,11 +31,6 @@ public static void Bind<T>(object instance) where T : class
3131
throw new ArgumentException($"Cannot bind {instance} because {type} is not an interface");
3232
}
3333

34-
if (!(instance is T))
35-
{
36-
throw new ArgumentException($"Cannot bind the given instance because it doesn't implement the {type} interface");
37-
}
38-
3934
_bindings.Add(type, instance);
4035
}
4136

Runtime/PoolService.cs

Lines changed: 51 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -14,54 +14,60 @@ namespace GameLovers.Services
1414
public interface IPoolService
1515
{
1616
/// <summary>
17-
/// Initializes a new pool with the given <paramref name="initialSize"/>
18-
/// It invokes the <paramref name="instantiator"/> function every time a new entity is created in the pool
17+
/// Adds the given <paramref name="pool"/> of <typeparamref name="T"/> to the service
1918
/// </summary>
20-
void InitPool<T>(int initialSize, Func<T> instantiator) where T : new();
21-
19+
/// <exception cref="ArgumentException">
20+
/// Thrown if the service already has a pool of the given <typeparamref name="T"/> type
21+
/// </exception>
22+
void AddPool<T>(IObjectPool<T> pool);
23+
2224
/// <summary>
23-
/// Initializes a new pool with the given <paramref name="initialSize"/> and a sample entity given back in the <paramref name="instantiator"/>
24-
/// It invokes the <paramref name="instantiator"/> function every time a new entity is created in the pool
25+
/// Removes the pool of the given <typeparamref name="T"/>
2526
/// </summary>
26-
void InitPool<T>(int initialSize, T sampleEntity, Func<T, T> instantiator) where T : Object;
27+
void RemovePool<T>();
2728

2829
/// <summary>
29-
/// Checks if exists a pool of the given type already exists or needs to be initialized with
30-
/// <seealso cref="InitPool{T}(int,System.Func{T})"/> before calling <seealso cref="Spawn{T}"/>
30+
/// Checks if exists a pool of the given type already exists or needs to be added before calling <seealso cref="Spawn{T}"/>
3131
/// </summary>
3232
bool HasPool<T>();
3333

3434
/// <inheritdoc cref="HasPool{T}"/>
3535
bool HasPool(Type type);
3636

3737
/// <inheritdoc cref="IObjectPool{T}.Spawn"/>
38+
/// <exception cref="ArgumentException">
39+
/// Thrown if the service does not contains a pool of the given <typeparamref name="T"/> type
40+
/// </exception>
3841
T Spawn<T>();
3942

4043
/// <inheritdoc cref="IObjectPool{T}.Despawn"/>
44+
/// <exception cref="ArgumentException">
45+
/// Thrown if the service does not contains a pool of the given <typeparamref name="T"/> type
46+
/// </exception>
4147
void Despawn<T>(T entity);
4248

4349
/// <inheritdoc cref="IObjectPool{T}.DespawnAll"/>
50+
/// <exception cref="ArgumentException">
51+
/// Thrown if the service does not contains a pool of the given <typeparamref name="T"/> type
52+
/// </exception>
4453
void DespawnAll<T>();
45-
46-
/// <inheritdoc cref="IObjectPool{T}.Clear"/>
47-
void Clear<T>();
4854
}
4955

5056
/// <inheritdoc />
5157
public class PoolService : IPoolService
5258
{
5359
private readonly Dictionary<Type, IObjectPool> _pools = new Dictionary<Type, IObjectPool>();
54-
60+
5561
/// <inheritdoc />
56-
public void InitPool<T>(int initialSize, Func<T> instantiator) where T : new()
62+
public void AddPool<T>(IObjectPool<T> pool)
5763
{
58-
_pools.Add(typeof(T), new ObjectPool<T>(initialSize, instantiator));
64+
_pools.Add(typeof(T), pool);
5965
}
6066

6167
/// <inheritdoc />
62-
public void InitPool<T>(int initialSize, T sampleEntity, Func<T, T> instantiator) where T : Object
68+
public void RemovePool<T>()
6369
{
64-
_pools.Add(typeof(T), new GameObjectPool<T>(initialSize, sampleEntity, instantiator));
70+
_pools.Remove(typeof(T));
6571
}
6672

6773
/// <inheritdoc />
@@ -94,13 +100,6 @@ public void DespawnAll<T>()
94100
GetPool<T>().DespawnAll();
95101
}
96102

97-
/// <inheritdoc />
98-
public void Clear<T>()
99-
{
100-
GetPool<T>().Clear();
101-
_pools.Remove(typeof(T));
102-
}
103-
104103
private IObjectPool<T> GetPool<T>()
105104
{
106105
if (!_pools.TryGetValue(typeof(T), out IObjectPool pool))
@@ -133,29 +132,12 @@ public interface IPoolEntityDespawn
133132
/// </summary>
134133
void OnDespawn();
135134
}
136-
137-
/// <summary>
138-
/// This interface allows pooled objects to be notified when they are cleared from the pool
139-
/// </summary>
140-
public interface IPoolEntityCleared
141-
{
142-
/// <summary>
143-
/// Invoked when the entity is cleared
144-
/// </summary>
145-
void OnCleared();
146-
}
147135

148136
/// <summary>
149137
/// Simple object pool implementation that can handle any type of entity objects
150138
/// </summary>
151139
public interface IObjectPool
152140
{
153-
/// <summary>
154-
/// Clears the pool
155-
/// This function does not clear the entity. For that, have the entity implement <see cref="IPoolEntityCleared"/> or do it externally
156-
/// </summary>
157-
void Clear();
158-
159141
/// <summary>
160142
/// Despawns all active spawned entities and returns them back to the pool to be used again later
161143
/// This function does not reset the entity. For that, have the entity implement <see cref="IPoolEntityDespawn"/> or do it externally
@@ -198,19 +180,6 @@ protected ObjectPoolBase(int initSize, T sampleEntity, Func<T, T> instantiator)
198180
_stack.Push(instantiator.Invoke(sampleEntity));
199181
}
200182
}
201-
202-
/// <inheritdoc />
203-
public void Clear()
204-
{
205-
for (var i = 0; i < _stack.Count; i++)
206-
{
207-
var entity =_stack.Pop() as IPoolEntityCleared;
208-
209-
entity?.OnCleared();
210-
}
211-
212-
_spawnedEntities.Clear();
213-
}
214183

215184
/// <inheritdoc />
216185
public T Spawn()
@@ -247,21 +216,44 @@ public void DespawnAll()
247216
}
248217

249218
/// <inheritdoc />
250-
public class ObjectPool<T> : ObjectPoolBase<T> where T : new()
219+
public class ObjectPool<T> : ObjectPoolBase<T>
220+
{
221+
public ObjectPool(int initSize, Func<T> instantiator) : base(initSize, instantiator(), entityRef => instantiator.Invoke())
222+
{
223+
}
224+
}/// <inheritdoc />
225+
/// <remarks>
226+
/// Useful to for pools that use object references to create new instances (ex: GameObjects)
227+
/// </remarks>
228+
public class ObjectRefPool<T> : ObjectPoolBase<T>
251229
{
252-
public ObjectPool(int initSize, Func<T> instantiator) : base(initSize, instantiator(), newEntity => instantiator.Invoke())
230+
public ObjectRefPool(int initSize, T sampleEntity, Func<T, T> instantiator) : base(initSize, sampleEntity, instantiator)
253231
{
254232
}
255233
}
256234

257235
/// <inheritdoc />
258236
/// <remarks>
259-
/// <see cref="IObjectPool"/> implementation for objects of type <see cref="Object"/>
237+
/// Useful to for pools that use object references to create new <see cref="GameObject"/>
260238
/// </remarks>
261-
public class GameObjectPool<T> : ObjectPoolBase<T> where T : Object
239+
public class GameObjectPool<T> : ObjectRefPool<T> where T : MonoBehaviour
262240
{
263-
public GameObjectPool(int initSize, T sampleEntity, Func<T, T> instantiator) : base(initSize, sampleEntity, instantiator)
241+
public GameObjectPool(int initSize, T sampleEntity) : base(initSize, sampleEntity, Instantiator)
242+
{
243+
}
244+
245+
/// <summary>
246+
/// Generic instantiator for <see cref="GameObject"/> pools
247+
/// </summary>
248+
/// <param name="entityRef"></param>
249+
/// <returns></returns>
250+
public static T Instantiator(T entityRef)
264251
{
252+
var instance = Object.Instantiate(entityRef, entityRef.transform.parent, true);
253+
254+
instance.gameObject.SetActive(false);
255+
256+
return instance;
265257
}
266258
}
267259
}

Runtime/TimeService.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ public interface ITimeService
5151
float UnityTimeFromUnixTime(long time);
5252
}
5353

54-
/// <summary>
54+
/// <inheritdoc cref="ITimeService"/>
55+
/// <remarks>
5556
/// Manipulates the service's time.
5657
/// This can be useful in cases where we want to speed up the game or to synchronize time with an outside source
57-
/// </summary>
58-
public interface ITimeManipulator
58+
/// </remarks>
59+
public interface ITimeManipulator : ITimeService
5960
{
6061
/// <summary>
6162
/// Adds <paramref name="timeInSeconds"/> to the current game's clock.
@@ -70,7 +71,7 @@ public interface ITimeManipulator
7071
}
7172

7273
/// <inheritdoc cref="ITimeService"/>
73-
public class TimeService : ITimeService, ITimeManipulator
74+
public class TimeService : ITimeManipulator
7475
{
7576
private static readonly DateTime UnixInitialTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
7677

Tests/Editor/MainInstallerTest.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,7 @@ public void Bind_Resolve_Successfully()
3232
[Test]
3333
public void Bind_NotInterface_ThrowsException()
3434
{
35-
Assert.Throws<ArgumentException>(() => MainInstaller.Bind<Implementation>(new Implementation()));
36-
}
37-
38-
[Test]
39-
public void Bind_NotImplementing_ThrowsException()
40-
{
41-
Assert.Throws<ArgumentException>(() => MainInstaller.Bind<IInterface>(new int[0]));
35+
Assert.Throws<ArgumentException>(() => MainInstaller.Bind(new Implementation()));
4236
}
4337

4438
[Test]

Tests/Editor/ObjectPoolTest.cs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ public class ObjectPoolTest
1414
private PoolableEntity _poolableEntity;
1515
private int initialSize = 5;
1616

17-
public class PoolableEntity : IPoolEntitySpawn, IPoolEntityDespawn, IPoolEntityCleared
17+
public class PoolableEntity : IPoolEntitySpawn, IPoolEntityDespawn
1818
{
1919
public void OnSpawn() {}
2020
public void OnDespawn() {}
21-
public void OnCleared() {}
2221
}
2322

2423
[SetUp]
@@ -75,25 +74,5 @@ public void DespawnAll_Successfully()
7574
entity.Received().OnDespawn();
7675
}
7776
}
78-
79-
[Test]
80-
public void Clear_Successfully()
81-
{
82-
_pool.Despawn(_poolableEntity);
83-
_pool.Clear();
84-
85-
_poolableEntity.Received().OnCleared();
86-
87-
Assert.DoesNotThrow(() => _pool.Spawn());
88-
Assert.DoesNotThrow(() => _pool.Despawn(_poolableEntity));
89-
}
90-
91-
[Test]
92-
public void Clear_Twice_NothingHappens()
93-
{
94-
_pool.Clear();
95-
96-
Assert.DoesNotThrow(() => _pool.Clear());
97-
}
9877
}
9978
}

0 commit comments

Comments
 (0)