Skip to content

Commit

Permalink
Add DisposableBag
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Jan 6, 2024
1 parent 5e81edf commit 409b5f4
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/R3/Disposable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public static void AddTo(this IDisposable disposable, ref DisposableBuilder buil
builder.Add(disposable);
}

public static void AddTo(this IDisposable disposable, ref DisposableBag bag)
{
bag.Add(disposable);
}

public static void AddTo(this IDisposable disposable, ICollection<IDisposable> disposables)
{
disposables.Add(disposable);
Expand Down
53 changes: 53 additions & 0 deletions src/R3/DisposableBag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
namespace R3;

public struct DisposableBag : IDisposable
{
IDisposable[]? items;
bool isDisposed;
int count;

public DisposableBag(int capacity)
{
items = new IDisposable[capacity];
}

public void Add(IDisposable item)
{
if (isDisposed)
{
item.Dispose();
return;
}

if (items == null)
{
items = new IDisposable[4];
}
else if (count == items.Length)
{
Array.Resize(ref items, count * 2);
}

items[count++] = item;
}

public void Clear()
{
if (items != null)
{
for (int i = 0; i < count; i++)
{
items[i]?.Dispose();
}

items = null;
count = 0;
}
}

public void Dispose()
{
Clear();
isDisposed = true;
}
}
6 changes: 2 additions & 4 deletions src/R3/ObservableSubscribeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public static class ObservableSubscribeExtensions
[DebuggerStepThrough]
public static IDisposable Subscribe<T>(this Observable<T> source)
{
return source.Subscribe(NopObserver<T>.Instance);
return source.Subscribe(new NopObserver<T>());
}

[DebuggerStepThrough]
Expand Down Expand Up @@ -52,9 +52,7 @@ public static IDisposable Subscribe<T, TState>(this Observable<T> source, TState
[DebuggerStepThrough]
internal sealed class NopObserver<T> : Observer<T>
{
public static readonly NopObserver<T> Instance = new();

private NopObserver()
public NopObserver()
{
}

Expand Down
32 changes: 32 additions & 0 deletions tests/R3.Tests/DisposableBagTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace R3.Tests;

public class DisposableBagTest
{
[Fact]
public void Test()
{
var bag = new DisposableBag();

var disposed = new bool[6];

var subject = new Subject<int>();
subject.Do(onDispose: () => disposed[0] = true).Subscribe().AddTo(ref bag);
subject.Do(onDispose: () => disposed[1] = true).Subscribe().AddTo(ref bag);
subject.Do(onDispose: () => disposed[2] = true).Subscribe().AddTo(ref bag);
subject.Do(onDispose: () => disposed[3] = true).Subscribe().AddTo(ref bag);
subject.Do(onDispose: () => disposed[4] = true).Subscribe().AddTo(ref bag);
subject.Do(onDispose: () => disposed[5] = true).Subscribe().AddTo(ref bag);

disposed.Should().Equal([false, false, false, false, false, false]);

bag.Dispose();

disposed.Should().Equal([true, true, true, true, true, true]);
}
}

0 comments on commit 409b5f4

Please sign in to comment.