133 lines
No EOL
3.2 KiB
C#
133 lines
No EOL
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace JD.Kernel.Classes
|
|
{
|
|
/// <summary>
|
|
/// Event that triggers normally but can be suspended. In suspend mode, events are recorded.
|
|
/// </summary>
|
|
/// <typeparam name="TEventArgs">Eventargs of the final event.</typeparam>
|
|
public class SuspendableEvent<TEventArgs>
|
|
{
|
|
#region Variables
|
|
|
|
private readonly Scope m_suspend = new Scope();
|
|
private List<RecordedEvent> m_journal = new List<RecordedEvent>();
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
public SuspendableEvent()
|
|
{
|
|
m_suspend.EndScope += delegate
|
|
{
|
|
FlushJournal();
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// During the activity of the scope, events are recorded.
|
|
/// </summary>
|
|
public Scope Suspend
|
|
{
|
|
get { return m_suspend; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
private void FlushJournal()
|
|
{
|
|
if (m_journal.Count > 0)
|
|
{
|
|
List<RecordedEvent> suspendedEvents = m_journal;
|
|
m_journal = new List<RecordedEvent>();
|
|
suspendedEvents.ForEach(RaiseImpl);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Operators
|
|
|
|
public static SuspendableEvent<TEventArgs> operator +(SuspendableEvent<TEventArgs> @event, EventHandler<TEventArgs> handler)
|
|
{
|
|
SuspendableEvent<TEventArgs> result = @event ?? new SuspendableEvent<TEventArgs>();
|
|
result.Event += handler;
|
|
return result;
|
|
}
|
|
|
|
public static SuspendableEvent<TEventArgs> operator -(SuspendableEvent<TEventArgs> @event, EventHandler<TEventArgs> handler)
|
|
{
|
|
if (@event != null)
|
|
{
|
|
@event.Event -= handler;
|
|
if (@event.Event == null)
|
|
{
|
|
return null;
|
|
}
|
|
return @event;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Triggers the event.
|
|
/// </summary>
|
|
internal void RaiseInternal(object sender, TEventArgs e)
|
|
{
|
|
if (!m_suspend.InScope)
|
|
{
|
|
RaiseImpl(sender, e);
|
|
}
|
|
else
|
|
{
|
|
m_journal.Add(new RecordedEvent(sender, e));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Event
|
|
|
|
/// <summary>
|
|
/// The final triggered event.
|
|
/// </summary>
|
|
private event EventHandler<TEventArgs> Event;
|
|
|
|
private void RaiseImpl(object sender, TEventArgs e)
|
|
{
|
|
Event?.Invoke(sender, e);
|
|
}
|
|
|
|
private void RaiseImpl(RecordedEvent @event)
|
|
{
|
|
RaiseImpl(@event.Sender, @event.EventArgs);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Nested Types
|
|
|
|
private struct RecordedEvent
|
|
{
|
|
public readonly object Sender;
|
|
public readonly TEventArgs EventArgs;
|
|
|
|
public RecordedEvent(object sender, TEventArgs eventArgs)
|
|
{
|
|
Sender = sender;
|
|
EventArgs = eventArgs;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |