// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries,
// repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to [email protected] unless otherwise specified or the original license has
// been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper licenses and/or copyrights.
// If you want to use any of our code in a commercial project, you must contact [email protected] for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin: 1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal: [email protected]
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at [email protected]
// Our software can be found at "https://Protiguous.com/Software/"
// Our GitHub address is "https://github.com/Protiguous".
//
// File "DelegateExtensions.cs" last formatted on 2022-04-07 at 12:38 PM by Protiguous.
public static class DelegateExtensions {
private sealed class ContextCallOnlyXTimes {
internal Int64 CallsAllowed;
public ContextCallOnlyXTimes( Int64 times ) {
if ( times <= 0 ) {
times = 0;
}
this.CallsAllowed = times;
}
}
/// <summary>Only allow a delegate to run X times.</summary>
/// <param name="action"></param>
/// <param name="callsAllowed"></param>
/// <example>var barWithBarrier = ActionBarrier(Bar, remainingCallsAllowed: 2 );</example>
/// <remarks>Calling the delegate more often than <paramref name="callsAllowed" /> should just NOP.</remarks>
public static Action ActionBarrier( this Action action, Int64 callsAllowed = 1 ) {
var context = new ContextCallOnlyXTimes( callsAllowed );
return () => {
if ( Interlocked.Decrement( ref context.CallsAllowed ) >= 1 ) {
action();
}
};
}
/// <summary>Only allow a delegate to run X times.</summary>
/// <param name="action"></param>
/// <param name="parameter"></param>
/// <param name="callsAllowed"></param>
/// <example>var barWithBarrier = ActionBarrier(Bar, remainingCallsAllowed: 2 );</example>
/// <remarks>Calling the delegate more often than <paramref name="callsAllowed" /> should just NOP.</remarks>
public static Action ActionBarrier<T>( this Action<T?> action, T? parameter, Int64 callsAllowed = 1 ) {
var context = new ContextCallOnlyXTimes( callsAllowed );
return () => {
if ( Interlocked.Decrement( ref context.CallsAllowed ) >= 1 ) {
action( parameter );
}
};
}
}