// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Threading;
using System.Threading.Channels;
namespace EpicGames.Core
{
///
/// Implements a which signals completion according to a reference count.
///
public class ChannelWithRefCount : Channel
{
int _count = 1;
///
/// Called when the channel is completed
///
public event Action? OnComplete;
///
/// Constructor
///
internal ChannelWithRefCount(Channel inner)
{
Reader = inner.Reader;
Writer = inner.Writer;
}
///
/// Adds a new reference to the channel
///
public ChannelWithRefCount AddRef()
{
Interlocked.Increment(ref _count);
return this;
}
///
/// Releases a reference to the channel
///
public void Release()
{
if (Interlocked.Decrement(ref _count) == 0)
{
OnComplete?.Invoke();
Writer.Complete();
}
}
}
///
/// Extension methods for
///
public static class ChannelExtensions
{
///
/// Creates a channel whose completion state is controlled by a reference count
///
public static ChannelWithRefCount WithRefCount(this Channel channel)
=> new ChannelWithRefCount(channel);
}
}