Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 49 additions & 13 deletions src/ControllersTree/Core/Utils/ControllerCompositeDisposable.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Pool;

namespace Playtika.Controllers
Expand All @@ -11,14 +10,22 @@ namespace Playtika.Controllers
public class ControllerCompositeDisposable : IDisposable
{
private readonly List<IDisposable> _disposables = ListPool<IDisposable>.Get();
private bool _disposed = false;

/// <summary>
/// Adds a disposable object to the internal list of disposables.
/// </summary>
/// <param name="disposable">The disposable object to add to the list.</param>
public void Add(IDisposable disposable)
{
_disposables.Add(disposable);
if (_disposed)
{
disposable?.Dispose();
}
else
{
_disposables.Add(disposable);
}
}

/// <summary>
Expand All @@ -27,33 +34,62 @@ public void Add(IDisposable disposable)
/// <param name="collection">The collection of disposable objects to add to the list.</param>
public void AddRange(IEnumerable<IDisposable> collection)
{
_disposables.AddRange(collection);
if (collection == null)
{
return;
}
if (_disposed)
{
using var pooledObject = ListPool<IDisposable>.Get(out var disposablesList);
disposablesList.AddRange(collection);
DisposeMany(disposablesList);
}
else
{
_disposables.AddRange(collection);
}
}

public void Dispose()
{
using var pooledObject = ListPool<Exception>.Get(out var exceptionList);
if (_disposed)
{
return;
}

_disposed = true;

try
{
DisposeMany(_disposables);
}
finally
{
ListPool<IDisposable>.Release(_disposables);
}
}

foreach (var disposable in _disposables)
private static void DisposeMany(IEnumerable<IDisposable> disposables)
{
using var pooledObject = ListPool<Exception>.Get(out var exceptionList);
foreach (var disposable in disposables)
{
try
{
disposable.Dispose();
disposable?.Dispose();
}
catch (Exception e)
{
exceptionList.Add(e);
}
}

_disposables.Clear();

ListPool<IDisposable>.Release(_disposables);

if (exceptionList.Any())
switch (exceptionList.Count)
{
throw new AggregateException(exceptionList);
case 0: return;
case 1: throw exceptionList[0];
default: throw new AggregateException(exceptionList);
}
}
}
}
}