Skip to content

Commit

Permalink
Merge pull request #530 from dotnet-state-machine/850-internal-transi…
Browse files Browse the repository at this point in the history
…tion-async-if

fix: InternalTransitionAsyncIf guard parameters (update)
  • Loading branch information
mclift authored Jul 4, 2023
2 parents b45b999 + c5ad663 commit dc70a9d
Show file tree
Hide file tree
Showing 3 changed files with 340 additions and 41 deletions.
17 changes: 10 additions & 7 deletions src/Stateless/InternalTriggerBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ public override bool ResultsInTransitionFrom(TState source, object[] args, out T
return false;
}


public class Sync: InternalTriggerBehaviour
public class Sync : InternalTriggerBehaviour
{
public Action<Transition, object[]> InternalAction { get; }

public Sync(TTrigger trigger, Func<object[], bool> guard, Action<Transition, object[]> internalAction, string guardDescription = null) : base(trigger, new TransitionGuard(guard, guardDescription))
{
InternalAction = internalAction;
}

public override void Execute(Transition transition, object[] args)
{
InternalAction(transition, args);
Expand All @@ -45,7 +45,13 @@ public class Async : InternalTriggerBehaviour
{
readonly Func<Transition, object[], Task> InternalAction;

public Async(TTrigger trigger, Func<bool> guard,Func<Transition, object[], Task> internalAction, string guardDescription = null) : base(trigger, new TransitionGuard(guard, guardDescription))
public Async(TTrigger trigger, Func<object[], bool> guard, Func<Transition, object[], Task> internalAction, string guardDescription = null) : base(trigger, new TransitionGuard(guard, guardDescription))
{
InternalAction = internalAction;
}

[Obsolete]
public Async(TTrigger trigger, Func<bool> guard, Func<Transition, object[], Task> internalAction, string guardDescription = null) : base(trigger, new TransitionGuard(guard, guardDescription))
{
InternalAction = internalAction;
}
Expand All @@ -61,10 +67,7 @@ public override Task ExecuteAsync(Transition transition, object[] args)
{
return InternalAction(transition, args);
}

}


}
}
}
}
127 changes: 95 additions & 32 deletions src/Stateless/StateConfiguration.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,95 @@ public partial class StateConfiguration
/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
/// <param name="trigger"></param>
/// <typeparam name="TArg0"></typeparam>
/// <param name="trigger">The accepted trigger</param>
/// <param name="guard">Function that must return true in order for the trigger to be accepted.</param>
/// <param name="entryAction"></param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
public StateConfiguration InternalTransitionAsyncIf(TTrigger trigger, Func<bool> guard, Func<Transition, Task> entryAction)
[Obsolete("Use InternalTransitionAsyncIf(TTrigger, Func<bool>, Func<Task>) instead.")]
public StateConfiguration InternalTransitionAsyncIf<TArg0>(TTrigger trigger, Func<bool> guard, Func<Transition, Task> internalAction)
{
if (entryAction == null) throw new ArgumentNullException(nameof(entryAction));
if (internalAction == null) throw new ArgumentNullException(nameof(internalAction));

_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger, guard, (t, args) => internalAction(t)));
return this;
}

/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
/// <typeparam name="TArg0"></typeparam>
/// <param name="trigger">The accepted trigger</param>
/// <param name="guard">Function that must return true in order for the trigger to be accepted.</param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
[Obsolete("Use InternalTransitionAsyncIf<TArg0>(TriggerWithParameters<TArg0>, Func<TArg0, bool>, Func<TArg0, Transition, Task>) instead.")]
public StateConfiguration InternalTransitionAsyncIf<TArg0>(TriggerWithParameters<TArg0> trigger, Func<bool> guard, Func<TArg0, Transition, Task> internalAction)
{
if (trigger == null) throw new ArgumentNullException(nameof(trigger));
if (internalAction == null) throw new ArgumentNullException(nameof(internalAction));

_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger.Trigger, guard, (t, args) => internalAction(ParameterConversion.Unpack<TArg0>(args, 0), t)));
return this;
}

/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
/// <typeparam name="TArg0"></typeparam>
/// <typeparam name="TArg1"></typeparam>
/// <param name="trigger">The accepted trigger</param>
/// <param name="guard">Function that must return true in order for the trigger to be accepted.</param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
[Obsolete("Use InternalTransitionAsyncIf<TArg0, TArg1>(TriggerWithParameters<TArg0, TArg1>, Func<TArg0, TArg1, bool>, Func<TArg0, TArg1, Transition, Task>) instead.")]
public StateConfiguration InternalTransitionAsyncIf<TArg0, TArg1>(TriggerWithParameters<TArg0, TArg1> trigger, Func<bool> guard, Func<TArg0, TArg1, Transition, Task> internalAction)
{
if (trigger == null) throw new ArgumentNullException(nameof(trigger));
if (internalAction == null) throw new ArgumentNullException(nameof(internalAction));

_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger.Trigger, guard, (t, args) => internalAction(
ParameterConversion.Unpack<TArg0>(args, 0),
ParameterConversion.Unpack<TArg1>(args, 1), t)));
return this;
}

/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
/// <typeparam name="TArg0"></typeparam>
/// <typeparam name="TArg1"></typeparam>
/// <typeparam name="TArg2"></typeparam>
/// <param name="trigger">The accepted trigger</param>
/// <param name="guard">Function that must return true in order for the trigger to be accepted.</param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
[Obsolete("Use InternalTransitionAsyncIf<TArg0, TArg1, TArg2>(TriggerWithParameters<TArg0, TArg1, TArg2>, Func<TArg0, TArg1, TArg2, bool>, Func<TArg0, TArg1, TArg2, Transition, Task>) instead.")]
public StateConfiguration InternalTransitionAsyncIf<TArg0, TArg1, TArg2>(TriggerWithParameters<TArg0, TArg1, TArg2> trigger, Func<bool> guard, Func<TArg0, TArg1, TArg2, Transition, Task> internalAction)
{
if (trigger == null) throw new ArgumentNullException(nameof(trigger));
if (internalAction == null) throw new ArgumentNullException(nameof(internalAction));

_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger, guard, (t, args) => entryAction(t)));
_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger.Trigger, guard, (t, args) => internalAction(
ParameterConversion.Unpack<TArg0>(args, 0),
ParameterConversion.Unpack<TArg1>(args, 1),
ParameterConversion.Unpack<TArg2>(args, 2), t)));
return this;
}

/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
/// <typeparam name="TArg0"></typeparam>
/// <param name="trigger">The accepted trigger</param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
[Obsolete("Use InternalTransitionAsync(TTrigger, Func<Transition, Task>) instead.")]
public StateConfiguration InternalTransitionAsync<TArg0>(TTrigger trigger, Func<Transition, Task> internalAction)
{
return InternalTransitionAsyncIf(trigger, () => true, internalAction);
}

/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
Expand All @@ -35,23 +112,22 @@ public StateConfiguration InternalTransitionAsyncIf(TTrigger trigger, Func<bool>
{
if (internalAction == null) throw new ArgumentNullException(nameof(internalAction));

_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger, guard, (t, args) => internalAction()));
_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger, t => guard(), (t, args) => internalAction()));
return this;
}

/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
/// <typeparam name="TArg0"></typeparam>
/// <param name="trigger">The accepted trigger</param>
/// <param name="guard">Function that must return true in order for the trigger to be accepted.</param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
public StateConfiguration InternalTransitionAsyncIf<TArg0>(TTrigger trigger, Func<bool> guard, Func<Transition, Task> internalAction)
public StateConfiguration InternalTransitionAsyncIf(TTrigger trigger, Func<bool> guard, Func<Transition, Task> internalAction)
{
if (internalAction == null) throw new ArgumentNullException(nameof(internalAction));

_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger, guard, (t, args) => internalAction(t)));
_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger, t => guard(), (t, args) => internalAction(t)));
return this;
}

Expand All @@ -63,12 +139,12 @@ public StateConfiguration InternalTransitionAsyncIf<TArg0>(TTrigger trigger, Fun
/// <param name="guard">Function that must return true in order for the trigger to be accepted.</param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
public StateConfiguration InternalTransitionAsyncIf<TArg0>(TriggerWithParameters<TArg0> trigger, Func<bool> guard, Func<TArg0, Transition, Task> internalAction)
public StateConfiguration InternalTransitionAsyncIf<TArg0>(TriggerWithParameters<TArg0> trigger, Func<TArg0, bool> guard, Func<TArg0, Transition, Task> internalAction)
{
if (trigger == null) throw new ArgumentNullException(nameof(trigger));
if (internalAction == null) throw new ArgumentNullException(nameof(internalAction));

_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger.Trigger, guard, (t, args) => internalAction(ParameterConversion.Unpack<TArg0>(args, 0), t)));
_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger.Trigger, TransitionGuard.ToPackedGuard(guard), (t, args) => internalAction(ParameterConversion.Unpack<TArg0>(args, 0), t)));
return this;
}

Expand All @@ -81,12 +157,12 @@ public StateConfiguration InternalTransitionAsyncIf<TArg0>(TriggerWithParameters
/// <param name="guard">Function that must return true in order for the trigger to be accepted.</param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
public StateConfiguration InternalTransitionAsyncIf<TArg0, TArg1>(TriggerWithParameters<TArg0, TArg1> trigger, Func<bool> guard, Func<TArg0, TArg1, Transition, Task> internalAction)
public StateConfiguration InternalTransitionAsyncIf<TArg0, TArg1>(TriggerWithParameters<TArg0, TArg1> trigger, Func<TArg0, TArg1, bool> guard, Func<TArg0, TArg1, Transition, Task> internalAction)
{
if (trigger == null) throw new ArgumentNullException(nameof(trigger));
if (internalAction == null) throw new ArgumentNullException(nameof(internalAction));

_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger.Trigger, guard, (t, args) => internalAction(
_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger.Trigger, TransitionGuard.ToPackedGuard(guard), (t, args) => internalAction(
ParameterConversion.Unpack<TArg0>(args, 0),
ParameterConversion.Unpack<TArg1>(args, 1), t)));
return this;
Expand All @@ -102,29 +178,18 @@ public StateConfiguration InternalTransitionAsyncIf<TArg0, TArg1>(TriggerWithPar
/// <param name="guard">Function that must return true in order for the trigger to be accepted.</param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
public StateConfiguration InternalTransitionAsyncIf<TArg0, TArg1, TArg2>(TriggerWithParameters<TArg0, TArg1, TArg2> trigger, Func<bool> guard, Func<TArg0, TArg1, TArg2, Transition, Task> internalAction)
public StateConfiguration InternalTransitionAsyncIf<TArg0, TArg1, TArg2>(TriggerWithParameters<TArg0, TArg1, TArg2> trigger, Func<TArg0, TArg1, TArg2, bool> guard, Func<TArg0, TArg1, TArg2, Transition, Task> internalAction)
{
if (trigger == null) throw new ArgumentNullException(nameof(trigger));
if (internalAction == null) throw new ArgumentNullException(nameof(internalAction));

_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger.Trigger, guard, (t, args) => internalAction(
_representation.AddTriggerBehaviour(new InternalTriggerBehaviour.Async(trigger.Trigger, TransitionGuard.ToPackedGuard(guard), (t, args) => internalAction(
ParameterConversion.Unpack<TArg0>(args, 0),
ParameterConversion.Unpack<TArg1>(args, 1),
ParameterConversion.Unpack<TArg2>(args, 2), t)));
return this;
}


/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
/// <param name="trigger"></param>
/// <param name="entryAction"></param>
/// <returns></returns>
public StateConfiguration InternalTransitionAsync(TTrigger trigger, Func<Transition, Task> entryAction)
{
return InternalTransitionAsyncIf(trigger, () => true, entryAction);
}
/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
Expand All @@ -138,11 +203,10 @@ public StateConfiguration InternalTransitionAsync(TTrigger trigger, Func<Task> i
/// <summary>
/// Add an internal transition to the state machine. An internal action does not cause the Exit and Entry actions to be triggered, and does not change the state of the state machine
/// </summary>
/// <typeparam name="TArg0"></typeparam>
/// <param name="trigger">The accepted trigger</param>
/// <param name="internalAction">The asynchronous action performed by the internal transition</param>
/// <returns></returns>
public StateConfiguration InternalTransitionAsync<TArg0>(TTrigger trigger, Func<Transition, Task> internalAction)
public StateConfiguration InternalTransitionAsync(TTrigger trigger, Func<Transition, Task> internalAction)
{
return InternalTransitionAsyncIf(trigger, () => true, internalAction);
}
Expand All @@ -155,7 +219,7 @@ public StateConfiguration InternalTransitionAsync<TArg0>(TTrigger trigger, Func<
/// <returns></returns>
public StateConfiguration InternalTransitionAsync<TArg0>(TriggerWithParameters<TArg0> trigger, Func<TArg0, Transition, Task> internalAction)
{
return InternalTransitionAsyncIf(trigger, () => true, internalAction);
return InternalTransitionAsyncIf(trigger, t => true, internalAction);
}

/// <summary>
Expand All @@ -168,7 +232,7 @@ public StateConfiguration InternalTransitionAsync<TArg0>(TriggerWithParameters<T
/// <returns></returns>
public StateConfiguration InternalTransitionAsync<TArg0, TArg1>(TriggerWithParameters<TArg0, TArg1> trigger, Func<TArg0, TArg1, Transition, Task> internalAction)
{
return InternalTransitionAsyncIf(trigger, () => true, internalAction);
return InternalTransitionAsyncIf(trigger, (t1, t2) => true, internalAction);
}

/// <summary>
Expand All @@ -182,7 +246,7 @@ public StateConfiguration InternalTransitionAsync<TArg0, TArg1>(TriggerWithParam
/// <returns></returns>
public StateConfiguration InternalTransitionAsync<TArg0, TArg1, TArg2>(TriggerWithParameters<TArg0, TArg1, TArg2> trigger, Func<TArg0, TArg1, TArg2, Transition, Task> internalAction)
{
return InternalTransitionAsyncIf(trigger, () => true, internalAction);
return InternalTransitionAsyncIf(trigger, (t1, t2, t3) => true, internalAction);
}

/// <summary>
Expand Down Expand Up @@ -230,7 +294,6 @@ public StateConfiguration OnEntryAsync(Func<Task> entryAction, string entryActio
(t, args) => entryAction(),
Reflection.InvocationInfo.Create(entryAction, entryActionDescription, Reflection.InvocationInfo.Timing.Asynchronous));
return this;

}

/// <summary>
Expand Down
Loading

0 comments on commit dc70a9d

Please sign in to comment.