-
Notifications
You must be signed in to change notification settings - Fork 747
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Concrete versions of StartStopDelegateWrapper
- Loading branch information
1 parent
2c25191
commit a9d3360
Showing
9 changed files
with
144 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#nullable enable | ||
|
||
using System; | ||
|
||
namespace Uno.Helpers | ||
{ | ||
/// <summary> | ||
/// Creates a wrapper around a generic event, which needs to be synchronized | ||
/// and needs to run an action when first subscriber is added and when | ||
/// last subscriber is removed. The operations executed when first subscriber | ||
/// is added and last subscriber is removed will execute within | ||
/// a synchronization lock, so please avoid blocking within the actions. | ||
/// </summary> | ||
internal class StartStopDelegateWrapper<TDelegate> | ||
where TDelegate : Delegate | ||
{ | ||
private readonly object _syncLock; | ||
private readonly Action _onFirst; | ||
private readonly Action _onLast; | ||
|
||
/// <summary> | ||
/// Creates a new instance of start-stop delegate wrapper. | ||
/// </summary> | ||
/// <param name="onFirst">Action to run when first subscriber is added. | ||
/// This will run within a synchronization lock so it should not involve blocking operations.</param> | ||
/// <param name="onLast">Action to run when last subscriber is removed. | ||
/// This will run within a synchronization lock so it should not involve blocking operations.</param> | ||
/// <param name="sharedLock">Optional shared object to lock on (when multiple events | ||
/// rely on the same native platform operation.</param> | ||
public StartStopDelegateWrapper( | ||
Action onFirst, | ||
Action onLast, | ||
object? sharedLock = null) | ||
{ | ||
_onFirst = onFirst; | ||
_onLast = onLast; | ||
_syncLock = sharedLock ?? new object(); | ||
} | ||
|
||
public TDelegate? Event { get; private set; } = null; | ||
|
||
public object SyncLock => _syncLock; | ||
|
||
public void AddHandler(TDelegate handler) | ||
{ | ||
lock (_syncLock) | ||
{ | ||
var firstSubscriber = Event == null; | ||
Event = (TDelegate)Delegate.Combine(Event, handler); | ||
if (firstSubscriber) | ||
{ | ||
_onFirst(); | ||
} | ||
} | ||
} | ||
|
||
public void RemoveHandler(TDelegate handler) | ||
{ | ||
lock (_syncLock) | ||
{ | ||
if (Event != null) | ||
{ | ||
Event = (TDelegate?)Delegate.Remove(Event, handler); | ||
if (Event == null) | ||
{ | ||
_onLast(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public bool IsActive => Event != null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#nullable enable | ||
|
||
using System; | ||
using Windows.Foundation; | ||
|
||
namespace Uno.Helpers | ||
{ | ||
/// <summary> | ||
/// Start stop wrapper for TypedEventHandler<T> events. | ||
/// </summary> | ||
/// <typeparam name="TEventArgs">Event args type.</typeparam> | ||
internal class StartStopTypedEventWrapper<TSender, TResult> : StartStopDelegateWrapper<TypedEventHandler<TSender, TResult>> | ||
{ | ||
/// <summary> | ||
/// Creates a new instance of start-stop event wrapper. | ||
/// </summary> | ||
/// <param name="onFirst">Action to run when first subscriber is added. | ||
/// This will run within a synchronization lock so it should not involve blocking operations.</param> | ||
/// <param name="onLast">Action to run when last subscriber is removed. | ||
/// This will run within a synchronization lock so it should not involve blocking operations.</param> | ||
/// <param name="sharedLock">Optional shared object to lock on (when multiple events | ||
/// rely on the same native platform operation.</param> | ||
public StartStopTypedEventWrapper(Action onFirst, Action onLast, object? sharedLock = null) : | ||
base(onFirst, onLast, sharedLock) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Invokes the event. | ||
/// </summary> | ||
/// <param name="sender">Sender.</param> | ||
/// <param name="args">Args.</param> | ||
public void Invoke(TSender sender, TResult args) => Event?.Invoke(sender, args); | ||
} | ||
} |