Skip to content

Commit

Permalink
Merge pull request #246 from tzachshabtay/ClaimEvent
Browse files Browse the repository at this point in the history
Claim event
  • Loading branch information
tzachshabtay committed Mar 7, 2018
2 parents 2f85d18 + 017c012 commit 375a955
Show file tree
Hide file tree
Showing 10 changed files with 558 additions and 304 deletions.
1 change: 1 addition & 0 deletions Source/AGS.API/AGS.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@
<Compile Include="Graphics\Textures\ITextureConfig.cs" />
<Compile Include="Graphics\Textures\ITextureFactory.cs" />
<Compile Include="Game\IRepeatedlyExecuteEventArgs.cs" />
<Compile Include="Misc\Events\ClaimEventToken.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<ItemGroup />
Expand Down
16 changes: 16 additions & 0 deletions Source/AGS.API/Misc/Events/ClaimEventToken.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace AGS.API
{
/// <summary>
/// This is a token that can be used when you want to claim an event, so that other subscribers which follow you on the subscriber list will not get that event.
/// <seealso cref="ClaimableCallback"/>
/// </summary>
public struct ClaimEventToken
{
/// <summary>
/// Gets or sets a value indicating whether this <see cref="T:AGS.API.ClaimEventToken"/> is claimed.
/// If you claim the event (by setting Claimed = true), this event will not be propogated to the rest of the subscribers.
/// </summary>
/// <value><c>true</c> if claimed; otherwise, <c>false</c>.</value>
public bool Claimed { get; set; }
}
}
102 changes: 96 additions & 6 deletions Source/AGS.API/Misc/Events/IBlockingEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,52 @@

namespace AGS.API
{
/// <summary>
/// This allows you to subscribe to an event with the option of claiming the event, so that other subscribers in the list will not receive the event.
///
/// <example>
/// <code language="lang-csharp">
/// myEvent.Subscribe(onEvent1);
/// myEvent.Subscribe(onEvent2);
///
/// void onEvent1(ref ClaimEventToken token)
/// {
/// token.Claimed = true; //We claimed the event, "onEvent2" will not get called.
/// }
/// </code>
/// </example>
/// </summary>
public delegate void ClaimableCallback(ref ClaimEventToken token);

/// <summary>
/// This allows you to subscribe to an event with the option of claiming the event, so that other subscribers in the list will not receive the event.
///
/// For an example- <see cref="ClaimableCallback"/>.
/// </summary>
public delegate void ClaimableCallbackWithArgs<TEventArgs>(TEventArgs args, ref ClaimEventToken token);

/// <summary>
/// In a scenario where an event has multiple subscribers, the callback priority affects which subscriber gets the callback first.
/// High priority subscribers will receive the event before normal priority (the default) subscribers, and low priority will receive the event last.
///
/// Note: For 2 subscribers with the same callback priority, there's no guarantee regarding who gets the event first.
/// </summary>
public enum CallbackPriority : byte
{
/// <summary>
/// Low priority- will receive the event last.
/// </summary>
Low,
/// <summary>
/// Normal priority.
/// </summary>
Normal,
/// <summary>
/// High priority- will receive the event first.
/// </summary>
High,
}

/// <summary>
/// Represents an event which can be subscribed and invoked synchronously.
/// An event is a notification for something that has happened.
Expand All @@ -21,21 +67,43 @@ public interface IBlockingEvent<TEventArgs>
/// Once subscribed, whenever the event happens this callback will be called.
/// </summary>
/// <param name="callback">Callback.</param>
void Subscribe(Action<TEventArgs> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Subscribe(Action<TEventArgs> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
void Unsubscribe(Action<TEventArgs> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Unsubscribe(Action<TEventArgs> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Subscribe the specified callback to the event.
/// Once subscribed, whenever the event happens this callback will be called.
///
/// In addition, this specific overload allows you to claim the event so that subscribers which follow you on the list will not receive the event.
/// For an example- <see cref="ClaimableCallback"/>.
/// </summary>
/// <param name="callback">Callback.</param>
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Subscribe(ClaimableCallbackWithArgs<TEventArgs> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Unsubscribe(ClaimableCallbackWithArgs<TEventArgs> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Asynchronously wait until the event fires and the specific condition applies.
/// </summary>
/// <returns>The task to be awaited.</returns>
/// <param name="condition">The condition we are waiting to apply before moving on.</param>
Task WaitUntilAsync(Predicate<TEventArgs> condition);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
Task WaitUntilAsync(Predicate<TEventArgs> condition, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Invoke the event synchronously (i.e will wait for all subscribers to process the event before moving on).
Expand All @@ -62,21 +130,43 @@ public interface IBlockingEvent
/// Once subscribed, whenever the event happens this callback will be called.
/// </summary>
/// <param name="callback">Callback.</param>
void Subscribe(Action callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Subscribe(Action callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Unsubscribe(Action callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Subscribe the specified callback to the event.
/// Once subscribed, whenever the event happens this callback will be called.
///
/// In addition, this specific overload allows you to claim the event so that subscribers which follow you on the list will not receive the event.
/// For an example- <see cref="ClaimableCallback"/>.
/// </summary>
/// <param name="callback">Callback.</param>
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Subscribe(ClaimableCallback callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
void Unsubscribe(Action callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Unsubscribe(ClaimableCallback callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Asynchronously wait until the event fires and the specific condition applies.
/// </summary>
/// <returns>The task to be awaited.</returns>
/// <param name="condition">The condition we are waiting to apply before moving on.</param>
Task WaitUntilAsync(Func<bool> condition);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
Task WaitUntilAsync(Func<bool> condition, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Invoke the event synchronously (i.e will wait for all subscribers to process the event before moving on).
Expand Down
42 changes: 28 additions & 14 deletions Source/AGS.API/Misc/Events/IEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,65 +21,74 @@ public interface IEvent<TEventArgs>
/// Once subscribed, whenever the event happens this callback will be called.
/// </summary>
/// <param name="callback">Callback.</param>
void Subscribe(Action<TEventArgs> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Subscribe(Action<TEventArgs> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
void Unsubscribe(Action<TEventArgs> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Unsubscribe(Action<TEventArgs> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Subscribe the specified asynchronous callback to the event.
/// Once subscribed, whenever the event happens this callback will be called.
/// </summary>
/// <param name="callback">Callback.</param>
void SubscribeToAsync(Func<TEventArgs, Task> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void SubscribeToAsync(Func<TEventArgs, Task> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified asynchronous callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
void UnsubscribeToAsync(Func<TEventArgs, Task> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void UnsubscribeToAsync(Func<TEventArgs, Task> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Subscribe the specified callback to the event.
/// Once subscribed, whenever the event happens this callback will be called.
/// This version of Subscribe ignores incoming arguments from the event (if you need the arguments, use the other overload which gets an action of TEventArgs).
/// </summary>
/// <param name="callback">Callback.</param>
void Subscribe(Action callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Subscribe(Action callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
void Unsubscribe(Action callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Unsubscribe(Action callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Subscribe the specified asynchronous callback to the event.
/// Once subscribed, whenever the event happens this callback will be called.
/// This version of Subscribe ignores incoming arguments from the event (if you need the arguments, use the other overload which gets a func of TEventArgs -> Task).
/// </summary>
/// <param name="callback">Callback.</param>
void SubscribeToAsync(Func<Task> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void SubscribeToAsync(Func<Task> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified asynchronous callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
void UnsubscribeToAsync(Func<Task> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void UnsubscribeToAsync(Func<Task> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Asynchronously wait until the event fires and the specific condition applies.
/// </summary>
/// <returns>The task to be awaited.</returns>
/// <param name="condition">The condition we are waiting to apply before moving on.</param>
Task WaitUntilAsync(Predicate<TEventArgs> condition);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
Task WaitUntilAsync(Predicate<TEventArgs> condition, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Invoke the event asynchronously.
Expand All @@ -106,35 +115,40 @@ public interface IEvent
/// Once subscribed, whenever the event happens this callback will be called.
/// </summary>
/// <param name="callback">Callback.</param>
void Subscribe(Action callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Subscribe(Action callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
void Unsubscribe(Action callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void Unsubscribe(Action callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Subscribe the specified asynchronous callback to the event.
/// Once subscribed, whenever the event happens this callback will be called.
/// </summary>
/// <param name="callback">Callback.</param>
void SubscribeToAsync(Func<Task> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void SubscribeToAsync(Func<Task> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Unsubscribe the specified asynchronous callback from the event.
/// This will stops notifications to call this callback.
/// </summary>
/// <param name="callback">Callback.</param>
void UnsubscribeToAsync(Func<Task> callback);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
void UnsubscribeToAsync(Func<Task> callback, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Asynchronously wait until the event fires and the specific condition applies.
/// </summary>
/// <returns>The task to be awaited.</returns>
/// <param name="condition">The condition we are waiting to apply before moving on.</param>
Task WaitUntilAsync(Func<bool> condition);
/// <param name="priority">The callback priority (determines the order in which the subscribers get the events).</param>
Task WaitUntilAsync(Func<bool> condition, CallbackPriority priority = CallbackPriority.Normal);

/// <summary>
/// Invoke the event asynchronously.
Expand Down
Loading

0 comments on commit 375a955

Please sign in to comment.