diff --git a/Core/Stateflows.Common/Activities/Classes/ActivityLocator.cs b/Core/Stateflows.Common/Activities/Classes/ActivityLocator.cs index 36411008..11a5887a 100644 --- a/Core/Stateflows.Common/Activities/Classes/ActivityLocator.cs +++ b/Core/Stateflows.Common/Activities/Classes/ActivityLocator.cs @@ -11,7 +11,7 @@ public ActivityLocator(IBehaviorLocator locator) Locator = locator; } - public bool TryLocateActivity(ActivityId id, out IActivity activity) + public bool TryLocateActivity(ActivityId id, out IActivityBehavior activity) => Locator.TryLocateActivity(id, out activity); } } diff --git a/Core/Stateflows.Common/Activities/Classes/ActivityWrapper.cs b/Core/Stateflows.Common/Activities/Classes/ActivityWrapper.cs index b6557bc4..4b653129 100644 --- a/Core/Stateflows.Common/Activities/Classes/ActivityWrapper.cs +++ b/Core/Stateflows.Common/Activities/Classes/ActivityWrapper.cs @@ -3,10 +3,11 @@ using System.Collections.Generic; using Stateflows.Activities; using Stateflows.Activities.Events; +using System.Linq; namespace Stateflows.Common.Activities.Classes { - internal class ActivityWrapper : IActivity + internal class ActivityWrapper : IActivityBehavior { BehaviorId IBehavior.Id => Behavior.Id; @@ -17,16 +18,15 @@ public ActivityWrapper(IBehavior consumer) Behavior = consumer; } - public Task> ExecuteAsync(InitializationRequest initializationRequest = null, IEnumerable inputTokens = null) - { - var executionRequest = new ExecutionRequest(initializationRequest ?? new InitializationRequest(), inputTokens ?? new object[0]); - if (initializationRequest != null) + public Task> ExecuteAsync(Event initializationEvent, IEnumerable inputTokens = null) + => Behavior.RequestAsync(new ExecutionRequest() { - executionRequest.Headers.AddRange(initializationRequest.Headers); - } + InitializationEvent = initializationEvent, + InputTokens = inputTokens ?? new object[0], + }); - return Behavior.RequestAsync(executionRequest); - } + public Task> ExecuteAsync(IEnumerable inputTokens = null) + => Behavior.RequestAsync(new ExecutionRequest() { InputTokens = inputTokens ?? new object[0] }); public Task SendAsync(TEvent @event) where TEvent : Event, new() diff --git a/Core/Stateflows/Activities/Tokens/TokenHolder.cs b/Core/Stateflows.Common/Activities/Classes/TokenHolder.cs similarity index 100% rename from Core/Stateflows/Activities/Tokens/TokenHolder.cs rename to Core/Stateflows.Common/Activities/Classes/TokenHolder.cs diff --git a/Core/Stateflows.Common/Activities/Events/ExecutionRequest.cs b/Core/Stateflows.Common/Activities/Events/ExecutionRequest.cs index f2d996c5..c2e23894 100644 --- a/Core/Stateflows.Common/Activities/Events/ExecutionRequest.cs +++ b/Core/Stateflows.Common/Activities/Events/ExecutionRequest.cs @@ -6,13 +6,7 @@ namespace Stateflows.Activities.Events { public sealed class ExecutionRequest : Request { - public ExecutionRequest(InitializationRequest initializationRequest, IEnumerable inputTokens) - { - InitializationRequest = initializationRequest; - InputTokens = inputTokens; - } - - public InitializationRequest InitializationRequest { get; set; } + public Event InitializationEvent { get; set; } = new Initialize(); [JsonProperty(TypeNameHandling = TypeNameHandling.None)] public IEnumerable InputTokens { get; set; } diff --git a/Core/Stateflows.Common/Activities/Events/ExecutionResponse.cs b/Core/Stateflows.Common/Activities/Events/ExecutionResponse.cs index fe15d177..8bf91dcb 100644 --- a/Core/Stateflows.Common/Activities/Events/ExecutionResponse.cs +++ b/Core/Stateflows.Common/Activities/Events/ExecutionResponse.cs @@ -6,8 +6,6 @@ namespace Stateflows.Activities.Events { public sealed class ExecutionResponse : Response { - public bool ExecutionSuccessful { get; set; } - [JsonProperty(TypeNameHandling = TypeNameHandling.None)] public IEnumerable OutputTokens { get; set; } = new List(); } diff --git a/Core/Stateflows.Common/Activities/Extensions/ExecutionResponseExtensions.cs b/Core/Stateflows.Common/Activities/Extensions/ExecutionResponseExtensions.cs index c4708583..8aef591e 100644 --- a/Core/Stateflows.Common/Activities/Extensions/ExecutionResponseExtensions.cs +++ b/Core/Stateflows.Common/Activities/Extensions/ExecutionResponseExtensions.cs @@ -6,18 +6,18 @@ namespace Stateflows.Activities { public static class ExecutionResponseExtensions { - public static IEnumerable GetOutputValues(this ExecutionResponse response) + public static IEnumerable GetOutputTokensOfType(this ExecutionResponse response) => response != null - ? response.OutputTokens.OfType().ToArray() + ? response.OutputTokens.OfType>().Select(t => t.Payload).ToArray() : new T[0]; - public static T GetOutputValueOrDefault(this ExecutionResponse response, T defaultValue = default) + public static bool TryGetOutputTokenOfType(this ExecutionResponse response, out T token) { - var valueTokens = response.GetOutputValues(); + var valueTokens = response.GetOutputTokensOfType(); - return valueTokens.Any() - ? valueTokens.First() - : defaultValue; + token = valueTokens.FirstOrDefault(); + + return valueTokens.Any(); } } } diff --git a/Core/Stateflows.Common/Activities/Extensions/IBehaviorLocatorActivityExtensions.cs b/Core/Stateflows.Common/Activities/Extensions/IBehaviorLocatorActivityExtensions.cs index 8817761a..9445709e 100644 --- a/Core/Stateflows.Common/Activities/Extensions/IBehaviorLocatorActivityExtensions.cs +++ b/Core/Stateflows.Common/Activities/Extensions/IBehaviorLocatorActivityExtensions.cs @@ -5,7 +5,7 @@ namespace Stateflows.Activities { public static class IBehaviorLocatorActivityExtensions { - public static bool TryLocateActivity(this IBehaviorLocator locator, ActivityId id, out IActivity activity) + public static bool TryLocateActivity(this IBehaviorLocator locator, ActivityId id, out IActivityBehavior activity) => ( activity = locator.TryLocateBehavior(id.BehaviorId, out var behavior) ? new ActivityWrapper(behavior) diff --git a/Core/Stateflows.Common/Activities/Interfaces/IActivity.cs b/Core/Stateflows.Common/Activities/Interfaces/IActivity.cs deleted file mode 100644 index 48cf455f..00000000 --- a/Core/Stateflows.Common/Activities/Interfaces/IActivity.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using Stateflows.Common; -using Stateflows.Activities.Events; - -namespace Stateflows.Activities -{ - public interface IActivity : IBehavior - { - Task> ExecuteAsync(InitializationRequest initializationRequest = null, IEnumerable inputTokens = null); - } -} diff --git a/Core/Stateflows.Common/Activities/Interfaces/IActivityBehavior.cs b/Core/Stateflows.Common/Activities/Interfaces/IActivityBehavior.cs new file mode 100644 index 00000000..d656a864 --- /dev/null +++ b/Core/Stateflows.Common/Activities/Interfaces/IActivityBehavior.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; +using System.Collections.Generic; +using Stateflows.Common; +using Stateflows.Activities.Events; + +namespace Stateflows.Activities +{ + public interface IActivityBehavior : IBehavior + { + Task> ExecuteAsync(Event initializationEvent, IEnumerable inputTokens = null); + Task> ExecuteAsync(IEnumerable inputTokens = null); + } +} diff --git a/Core/Stateflows.Common/Activities/Interfaces/IActivityLocator.cs b/Core/Stateflows.Common/Activities/Interfaces/IActivityLocator.cs index 4b68e269..44c31750 100644 --- a/Core/Stateflows.Common/Activities/Interfaces/IActivityLocator.cs +++ b/Core/Stateflows.Common/Activities/Interfaces/IActivityLocator.cs @@ -6,6 +6,6 @@ public interface IActivityLocator { IBehaviorLocator Locator { get; } - bool TryLocateActivity(ActivityId id, out IActivity activity); + bool TryLocateActivity(ActivityId id, out IActivityBehavior activity); } } diff --git a/Core/Stateflows.Common/Attributes/NoImplicitInitialization.cs b/Core/Stateflows.Common/Attributes/NoImplicitInitialization.cs new file mode 100644 index 00000000..c934ca21 --- /dev/null +++ b/Core/Stateflows.Common/Attributes/NoImplicitInitialization.cs @@ -0,0 +1,8 @@ +using System; + +namespace Stateflows.Common +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + public sealed class NoImplicitInitializationAttribute : Attribute + { } +} diff --git a/Core/Stateflows.Common/Classes/SendResult.cs b/Core/Stateflows.Common/Classes/SendResult.cs index 6b87eb07..55328df1 100644 --- a/Core/Stateflows.Common/Classes/SendResult.cs +++ b/Core/Stateflows.Common/Classes/SendResult.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -using System.ComponentModel.DataAnnotations; using System; +using System.ComponentModel.DataAnnotations; namespace Stateflows.Common { diff --git a/Core/Stateflows.Common/Context/StateflowsContext.cs b/Core/Stateflows.Common/Context/StateflowsContext.cs index 3e936267..514a48df 100644 --- a/Core/Stateflows.Common/Context/StateflowsContext.cs +++ b/Core/Stateflows.Common/Context/StateflowsContext.cs @@ -1,26 +1,51 @@ using System; using System.Linq; using System.Collections.Generic; +using Newtonsoft.Json; namespace Stateflows.Common.Context { public class StateflowsContext { + public StateflowsContext() + { + Stored = true; + } + + public StateflowsContext(BehaviorId id) + { + Id = id; + Stored = false; + } + public BehaviorId Id { get; set; } public int Version { get; set; } = 0; + [JsonIgnore] + public bool Deleted { get; set; } + + [JsonIgnore] + public bool Stored { get; set; } + public BehaviorStatus Status { get; set; } = BehaviorStatus.Unknown; public DateTime LastExecutedAt { get; set; } public DateTime? TriggerTime { get; set; } + public bool TriggerOnStartup { get; set; } + public bool ShouldSerializePendingTimeEvents() => PendingTimeEvents.Any(); public Dictionary PendingTimeEvents { get; set; } = new Dictionary(); + public bool ShouldSerializePendingStartupEvents() + => PendingStartupEvents.Any(); + + public Dictionary PendingStartupEvents { get; set; } = new Dictionary(); + public Dictionary> Subscriptions { get; set; } = new Dictionary>(); public bool AddSubscription(BehaviorId subscribeeBehaviorId, string eventName) diff --git a/Core/Stateflows.Common/DependencyInjection.cs b/Core/Stateflows.Common/DependencyInjection.cs index 2bd3443f..d8e8bfd6 100644 --- a/Core/Stateflows.Common/DependencyInjection.cs +++ b/Core/Stateflows.Common/DependencyInjection.cs @@ -1,6 +1,5 @@ using System; using Microsoft.Extensions.DependencyInjection; -using Stateflows.System; using Stateflows.Activities; using Stateflows.StateMachines; using Stateflows.Common; @@ -9,7 +8,6 @@ using Stateflows.Common.Interfaces; using Stateflows.Common.Extensions; using Stateflows.Common.Exceptions; -using Stateflows.Common.System.Classes; using Stateflows.Common.Activities.Classes; using Stateflows.Common.StateMachines.Classes; using Stateflows.Common.Registration.Builders; @@ -34,17 +32,6 @@ public static IServiceCollection AddStateflowsClient(this IServiceCollection ser .AddScoped() .AddScoped() .AddScoped() - .AddScoped((IServiceProvider provider) => - { - if (provider.GetRequiredService().TryLocateBehavior(SystemBehavior.Id, out var behavior)) - { - return new SystemWrapper(behavior); - } - else - { - throw new StateflowsException("System behavior could not be found"); - } - }) .AddSingleton() ; diff --git a/Core/Stateflows.Common/Enums/EventStatus.cs b/Core/Stateflows.Common/Enums/EventStatus.cs index 005a36b5..6fdf0f24 100644 --- a/Core/Stateflows.Common/Enums/EventStatus.cs +++ b/Core/Stateflows.Common/Enums/EventStatus.cs @@ -3,7 +3,15 @@ public enum EventStatus { /// - /// Target behavior not found + /// Event has initialized behavior instance + /// + Initialized, + /// + /// Event has failed to initialize behavior instance + /// + NotInitialized, + /// + /// Event has executed behavior instance /// Undelivered, /// @@ -15,10 +23,6 @@ public enum EventStatus /// Invalid, /// - /// Event was not consumed by behavior - /// - NotConsumed, - /// /// Event was deferred by behavior and can be consumed later /// Deferred, @@ -27,10 +31,18 @@ public enum EventStatus /// Consumed, /// + /// Event was not consumed by behavior + /// + NotConsumed, + /// /// Event was omitted because other events in CompoundRequest were invalid /// Omitted, /// + /// Event caused unhandled exception in behavior + /// + Failed, + /// /// Event was forwarded to embedded behavior /// Forwarded diff --git a/Core/Stateflows.Common/Enums/ExceptionPropagationMode.cs b/Core/Stateflows.Common/Enums/ExceptionPropagationMode.cs new file mode 100644 index 00000000..146d1231 --- /dev/null +++ b/Core/Stateflows.Common/Enums/ExceptionPropagationMode.cs @@ -0,0 +1,9 @@ +namespace Stateflows.Common +{ + public enum ExceptionPropagationMode + { + NoPropagation, + PropagateUnhandled, + PropagateAll + } +} diff --git a/Core/Stateflows.Common/Enums/InitializationStatus.cs b/Core/Stateflows.Common/Enums/InitializationStatus.cs new file mode 100644 index 00000000..b95d9951 --- /dev/null +++ b/Core/Stateflows.Common/Enums/InitializationStatus.cs @@ -0,0 +1,10 @@ +namespace Stateflows.Common +{ + public enum InitializationStatus + { + InitializedExplicitly, + InitializedImplicitly, + NotInitialized, + NoSuitableInitializer + } +} diff --git a/Core/Stateflows.Common/Enums/ResetMode.cs b/Core/Stateflows.Common/Enums/ResetMode.cs new file mode 100644 index 00000000..9c43baa1 --- /dev/null +++ b/Core/Stateflows.Common/Enums/ResetMode.cs @@ -0,0 +1,9 @@ +namespace Stateflows.Common +{ + public enum ResetMode + { + KeepVersionAndSubscriptions, + KeepSubscriptions, + Full + } +} diff --git a/Core/Stateflows.Common/Events/Event.cs b/Core/Stateflows.Common/Events/Event.cs index aeb3a6bd..79350049 100644 --- a/Core/Stateflows.Common/Events/Event.cs +++ b/Core/Stateflows.Common/Events/Event.cs @@ -17,15 +17,15 @@ public class Event public virtual string Name => GetType().GetEventName(); } - public class Event : Event - { - public Event() - { - Payload = default; - } - - public TPayload Payload { get; set; } - } + //public class Event : Event + //{ + // public Event() + // { + // Payload = default; + // } + + // public TPayload Payload { get; set; } + //} public static class EventInfo where TEvent : Event, new() diff --git a/Core/Stateflows.Common/Events/FinalizationRequest.cs b/Core/Stateflows.Common/Events/FinalizationRequest.cs index 0a448e17..43747d6e 100644 --- a/Core/Stateflows.Common/Events/FinalizationRequest.cs +++ b/Core/Stateflows.Common/Events/FinalizationRequest.cs @@ -1,5 +1,6 @@ namespace Stateflows.Common { + [NoImplicitInitialization] public sealed class FinalizationRequest : Request { } } diff --git a/Core/Stateflows.Common/Events/InitializationRequest.cs b/Core/Stateflows.Common/Events/InitializationRequest.cs index 2295f307..cd934632 100644 --- a/Core/Stateflows.Common/Events/InitializationRequest.cs +++ b/Core/Stateflows.Common/Events/InitializationRequest.cs @@ -1,15 +1,15 @@ namespace Stateflows.Common { - public class InitializationRequest : Request - { } + //public class InitializationRequest : Request + //{ } - public sealed class InitializationRequest : InitializationRequest - { - public InitializationRequest() - { - Payload = default; - } + //public sealed class InitializationRequest : InitializationRequest + //{ + // public InitializationRequest() + // { + // Payload = default; + // } - public TPayload Payload { get; set; } - } + // public TPayload Payload { get; set; } + //} } diff --git a/Core/Stateflows.Common/Events/InitializationResponse.cs b/Core/Stateflows.Common/Events/InitializationResponse.cs index a9e3f8cd..8f158819 100644 --- a/Core/Stateflows.Common/Events/InitializationResponse.cs +++ b/Core/Stateflows.Common/Events/InitializationResponse.cs @@ -1,7 +1,7 @@ namespace Stateflows.Common { - public sealed class InitializationResponse : Response - { - public bool InitializationSuccessful { get; set; } - } + //public sealed class InitializationResponse : Response + //{ + // public bool InitializationSuccessful { get; set; } + //} } diff --git a/Core/Stateflows.Common/Events/Initialize.cs b/Core/Stateflows.Common/Events/Initialize.cs new file mode 100644 index 00000000..676db050 --- /dev/null +++ b/Core/Stateflows.Common/Events/Initialize.cs @@ -0,0 +1,15 @@ +namespace Stateflows.Common +{ + public sealed class Initialize : Event + { } + + //public sealed class Initialize : Initialize + //{ + // public Initialize() + // { + // Payload = default; + // } + + // public TPayload Payload { get; set; } + //} +} diff --git a/Core/Stateflows.Common/Events/NotificationsRequest.cs b/Core/Stateflows.Common/Events/NotificationsRequest.cs index 4ac00644..aee9d0ad 100644 --- a/Core/Stateflows.Common/Events/NotificationsRequest.cs +++ b/Core/Stateflows.Common/Events/NotificationsRequest.cs @@ -1,5 +1,6 @@ namespace Stateflows.Common { + [NoImplicitInitialization] public sealed class NotificationsRequest : Request { } } diff --git a/Core/Stateflows.Common/Events/Request.cs b/Core/Stateflows.Common/Events/Request.cs index 59bb50fb..964f49fc 100644 --- a/Core/Stateflows.Common/Events/Request.cs +++ b/Core/Stateflows.Common/Events/Request.cs @@ -3,7 +3,7 @@ namespace Stateflows.Common { public abstract class Request : Event - where TResponse : Response, new() + where TResponse : Event, new() { public void Respond(TResponse response) { @@ -17,14 +17,4 @@ public void Respond(TResponse response) public TResponse Response { get; private set; } } - - public class Request : Request> - { - public Request() - { - Payload = default; - } - - public TRequestPayload Payload { get; set; } - } } diff --git a/Core/Stateflows.Common/Events/ResetRequest.cs b/Core/Stateflows.Common/Events/ResetRequest.cs index 2bc4c446..7c621ff6 100644 --- a/Core/Stateflows.Common/Events/ResetRequest.cs +++ b/Core/Stateflows.Common/Events/ResetRequest.cs @@ -1,7 +1,8 @@ namespace Stateflows.Common { + [NoImplicitInitialization] public class ResetRequest : Request { - public bool KeepVersion { get; set; } = false; + public ResetMode Mode { get; set; } = ResetMode.Full; } } diff --git a/Core/Stateflows.Common/Events/Response.cs b/Core/Stateflows.Common/Events/Response.cs index f1db7bd8..7894c52e 100644 --- a/Core/Stateflows.Common/Events/Response.cs +++ b/Core/Stateflows.Common/Events/Response.cs @@ -5,13 +5,13 @@ public class Response : Event public BehaviorId SenderId { get; set; } } - public sealed class Response : Response - { - public Response() - { - Payload = default; - } + //public sealed class Response : Response + //{ + // public Response() + // { + // Payload = default; + // } - public TPayload Payload { get; set; } - } + // public TPayload Payload { get; set; } + //} } diff --git a/Core/Stateflows.Common/Events/Startup.cs b/Core/Stateflows.Common/Events/Startup.cs new file mode 100644 index 00000000..33138fae --- /dev/null +++ b/Core/Stateflows.Common/Events/Startup.cs @@ -0,0 +1,7 @@ +namespace Stateflows.Common +{ + public sealed class Startup : SystemEvent + { + public string ConsumerSignature { get; set; } + } +} diff --git a/Core/Stateflows.Common/Events/SubscriptionRequest.cs b/Core/Stateflows.Common/Events/SubscriptionRequest.cs index 3b0be0ce..4c8eec61 100644 --- a/Core/Stateflows.Common/Events/SubscriptionRequest.cs +++ b/Core/Stateflows.Common/Events/SubscriptionRequest.cs @@ -3,6 +3,7 @@ namespace Stateflows.Common { + [NoImplicitInitialization] public sealed class SubscriptionRequest : Request { public BehaviorId BehaviorId { get; set; } diff --git a/Core/Stateflows.Common/Events/Command.cs b/Core/Stateflows.Common/Events/SystemEvent.cs similarity index 50% rename from Core/Stateflows.Common/Events/Command.cs rename to Core/Stateflows.Common/Events/SystemEvent.cs index 68ed0f59..6f371b5c 100644 --- a/Core/Stateflows.Common/Events/Command.cs +++ b/Core/Stateflows.Common/Events/SystemEvent.cs @@ -1,5 +1,5 @@ namespace Stateflows.Common { - public abstract class Command : Event + public class SystemEvent : Event { } } diff --git a/Core/Stateflows.Common/Events/TimeEvent.cs b/Core/Stateflows.Common/Events/TimeEvent.cs index 60d2ab1c..fd32e90c 100644 --- a/Core/Stateflows.Common/Events/TimeEvent.cs +++ b/Core/Stateflows.Common/Events/TimeEvent.cs @@ -2,7 +2,7 @@ namespace Stateflows.Common { - public class TimeEvent : Event + public class TimeEvent : SystemEvent { protected virtual DateTime GetTriggerTime(DateTime startedAt) { diff --git a/Core/Stateflows.Common/Events/UnsubscriptionRequest.cs b/Core/Stateflows.Common/Events/UnsubscriptionRequest.cs index 93e5c16f..de39111f 100644 --- a/Core/Stateflows.Common/Events/UnsubscriptionRequest.cs +++ b/Core/Stateflows.Common/Events/UnsubscriptionRequest.cs @@ -3,6 +3,7 @@ namespace Stateflows.Common { + [NoImplicitInitialization] public sealed class UnsubscriptionRequest : Request { public BehaviorId BehaviorId { get; set; } diff --git a/Core/Stateflows.Common/Exceptions/ExecutionException.cs b/Core/Stateflows.Common/Exceptions/ExecutionException.cs new file mode 100644 index 00000000..e9feeef2 --- /dev/null +++ b/Core/Stateflows.Common/Exceptions/ExecutionException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Stateflows.Common.Exceptions +{ +#pragma warning disable S3925 // "ISerializable" should be implemented correctly + public class ExecutionException : StateflowsException + { + public ExecutionException(Exception innerException) : base(string.Empty, innerException) { } + } +#pragma warning restore S3925 // "ISerializable" should be implemented correctly +} diff --git a/Core/Stateflows.Common/Extensions/EventExtensions.cs b/Core/Stateflows.Common/Extensions/EventExtensions.cs index f87d930f..cb0ab971 100644 --- a/Core/Stateflows.Common/Extensions/EventExtensions.cs +++ b/Core/Stateflows.Common/Extensions/EventExtensions.cs @@ -36,11 +36,9 @@ public static EventValidation Validate(this Event @event) } else { - var objectToValidate = @event.GetPayload() ?? @event; + var validationContext = new ValidationContext(@event, serviceProvider: null, items: null); - var validationContext = new ValidationContext(objectToValidate, serviceProvider: null, items: null); - - isValid = Validator.TryValidateObject(objectToValidate, validationContext, validationResults, true); + isValid = Validator.TryValidateObject(@event, validationContext, validationResults, true); } return new EventValidation(isValid, validationResults); @@ -66,18 +64,18 @@ public static TResponse GetResponse(this Event @event) public static Response GetResponse(this Event @event) => @event.GetResponse(); - public static bool IsPayloadEvent(this Event @event) - => @event.GetType().IsSubclassOfRawGeneric(typeof(Event<>)); + //public static bool IsPayloadEvent(this Event @event) + // => @event.GetType().IsSubclassOfRawGeneric(typeof(Event<>)); - public static TPayload GetPayload(this Event @event) - { - if (!@event.IsPayloadEvent()) - { - return default; - } + //public static TPayload GetPayload(this Event @event) + //{ + // if (!@event.IsPayloadEvent()) + // { + // return default; + // } - return (TPayload)@event.GetType().GetProperty("Payload").GetValue(@event); - } + // return (TPayload)@event.GetType().GetProperty("Payload").GetValue(@event); + //} public static void Respond(this Event @event, Response response) { diff --git a/Core/Stateflows.Common/Extensions/IEnumerableExtensions.cs b/Core/Stateflows.Common/Extensions/IEnumerableExtensions.cs index 21818e99..d629aa6a 100644 --- a/Core/Stateflows.Common/Extensions/IEnumerableExtensions.cs +++ b/Core/Stateflows.Common/Extensions/IEnumerableExtensions.cs @@ -24,10 +24,10 @@ public static async Task RunProtected(this IEnumerable enumerable, ActionA } } - public static async Task RunProtected(this IEnumerable enumerable, PredicateAsync action, Action exceptionHandler) + public static async Task RunProtected(this IEnumerable enumerable, PredicateAsync action, Action exceptionHandler, bool defaultResult = true) where T : class { - var result = true; + var result = defaultResult; foreach (var item in enumerable) { try @@ -53,11 +53,12 @@ public static Task RunSafe(this IEnumerable enumerable, ActionAsync act e => logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(T).DeclaringType.FullName, methodName, e.GetType().Name, e.Message) ); - public static Task RunSafe(this IEnumerable enumerable, PredicateAsync action, string methodName, ILogger logger) + public static Task RunSafe(this IEnumerable enumerable, PredicateAsync action, string methodName, ILogger logger, bool defaultResult = true) where T : class => enumerable.RunProtected( action, - e => logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(T).DeclaringType.FullName, methodName, e.GetType().Name, e.Message) + e => logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(T).DeclaringType.FullName, methodName, e.GetType().Name, e.Message), + defaultResult ); } } diff --git a/Core/Stateflows.Common/Extensions/PayloadObjectExtensions.cs b/Core/Stateflows.Common/Extensions/PayloadObjectExtensions.cs index 9fc24cdf..031cdb8a 100644 --- a/Core/Stateflows.Common/Extensions/PayloadObjectExtensions.cs +++ b/Core/Stateflows.Common/Extensions/PayloadObjectExtensions.cs @@ -2,13 +2,13 @@ { public static class PayloadObjectExtensions { - public static Event ToEvent(this T payload) - => new Event() { Payload = payload }; + //public static Event ToEvent(this T payload) + // => new Event() { Payload = payload }; - public static Request ToRequest(this TRequestPayload payload) - => new Request() { Payload = payload }; + //public static Request ToRequest(this TRequestPayload payload) + // => new Request() { Payload = payload }; - public static InitializationRequest ToInitializationRequest(this TPayload payload) - => new InitializationRequest() { Payload = payload }; + //public static Initialize ToInitialize(this TPayload payload) + // => new Initialize() { Payload = payload }; } } diff --git a/Core/Stateflows.Common/Interfaces/IBehavior.cs b/Core/Stateflows.Common/Interfaces/IBehavior.cs index 93417a86..44994400 100644 --- a/Core/Stateflows.Common/Interfaces/IBehavior.cs +++ b/Core/Stateflows.Common/Interfaces/IBehavior.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using System.Threading.Tasks; using Stateflows.Common.Interfaces; @@ -21,27 +20,8 @@ Task> SendCompoundAsync(params Event[] events) Task> RequestAsync(Request request) where TResponse : Response, new(); - Task> InitializeAsync(InitializationRequest initializationRequest = null) - => RequestAsync(initializationRequest ?? new InitializationRequest()); - - Task> FinalizeAsync() - => RequestAsync(new FinalizationRequest()); - - Task> ResetAsync(bool keepVersion = false) - => RequestAsync(new ResetRequest() { KeepVersion = keepVersion }); - - async Task> ReinitializeAsync(InitializationRequest initializationRequest = null, bool keepVersion = true) - { - initializationRequest ??= new InitializationRequest(); - var compoundResult = await SendCompoundAsync( - new ResetRequest() { KeepVersion = keepVersion }, - initializationRequest - ); - - var result = compoundResult.Response.Results.Last(); - - return new RequestResult(initializationRequest, result.Status, result.Validation); - } + Task> ResetAsync(ResetMode resetMode = ResetMode.Full) + => RequestAsync(new ResetRequest() { Mode = resetMode }); Task> GetStatusAsync() => RequestAsync(new BehaviorStatusRequest()); diff --git a/Core/Stateflows.Common/Locator/BehaviorProxy.cs b/Core/Stateflows.Common/Locator/BehaviorProxy.cs index 16ccfae3..adb4467d 100644 --- a/Core/Stateflows.Common/Locator/BehaviorProxy.cs +++ b/Core/Stateflows.Common/Locator/BehaviorProxy.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Threading.Tasks; using Stateflows.Common.Engine; diff --git a/Core/Stateflows.Common/StateMachines/Classes/StateMachineLocator.cs b/Core/Stateflows.Common/StateMachines/Classes/StateMachineLocator.cs index 569e6ba1..3b0672a0 100644 --- a/Core/Stateflows.Common/StateMachines/Classes/StateMachineLocator.cs +++ b/Core/Stateflows.Common/StateMachines/Classes/StateMachineLocator.cs @@ -13,7 +13,7 @@ public StateMachineLocator(IBehaviorLocator locator) Locator = locator; } - public bool TryLocateStateMachine(StateMachineId id, out IStateMachine stateMachine) + public bool TryLocateStateMachine(StateMachineId id, out IStateMachineBehavior stateMachine) => Locator.TryLocateStateMachine(id, out stateMachine); } } diff --git a/Core/Stateflows.Common/StateMachines/Classes/StateMachineWrapper.cs b/Core/Stateflows.Common/StateMachines/Classes/StateMachineWrapper.cs index 3d029187..a97568dd 100644 --- a/Core/Stateflows.Common/StateMachines/Classes/StateMachineWrapper.cs +++ b/Core/Stateflows.Common/StateMachines/Classes/StateMachineWrapper.cs @@ -4,7 +4,7 @@ namespace Stateflows.Common.StateMachines.Classes { - internal class StateMachineWrapper : IStateMachine + internal class StateMachineWrapper : IStateMachineBehavior { public BehaviorId Id => Behavior.Id; diff --git a/Core/Stateflows.Common/StateMachines/Extensions/IBehaviorLocatorStateMachineExtensions.cs b/Core/Stateflows.Common/StateMachines/Extensions/IBehaviorLocatorStateMachineExtensions.cs index 6290c753..32c35fb5 100644 --- a/Core/Stateflows.Common/StateMachines/Extensions/IBehaviorLocatorStateMachineExtensions.cs +++ b/Core/Stateflows.Common/StateMachines/Extensions/IBehaviorLocatorStateMachineExtensions.cs @@ -5,7 +5,7 @@ namespace Stateflows.StateMachines { public static class IBehaviorLocatorStateMachineExtensions { - public static bool TryLocateStateMachine(this IBehaviorLocator locator, StateMachineId id, out IStateMachine stateMachine) + public static bool TryLocateStateMachine(this IBehaviorLocator locator, StateMachineId id, out IStateMachineBehavior stateMachine) { stateMachine = locator.TryLocateBehavior(id, out var behavior) ? new StateMachineWrapper(behavior) diff --git a/Core/Stateflows.Common/StateMachines/Interfaces/IStateMachine.cs b/Core/Stateflows.Common/StateMachines/Interfaces/IStateMachineBehavior.cs similarity index 90% rename from Core/Stateflows.Common/StateMachines/Interfaces/IStateMachine.cs rename to Core/Stateflows.Common/StateMachines/Interfaces/IStateMachineBehavior.cs index d8d9876a..b0fe91ad 100644 --- a/Core/Stateflows.Common/StateMachines/Interfaces/IStateMachine.cs +++ b/Core/Stateflows.Common/StateMachines/Interfaces/IStateMachineBehavior.cs @@ -5,7 +5,7 @@ namespace Stateflows.StateMachines { - public interface IStateMachine : IBehavior + public interface IStateMachineBehavior : IBehavior { Task> GetCurrentStateAsync() => RequestAsync(new CurrentStateRequest()); diff --git a/Core/Stateflows.Common/StateMachines/Interfaces/IStateMachineLocator.cs b/Core/Stateflows.Common/StateMachines/Interfaces/IStateMachineLocator.cs index 39bd1212..60e4a2e2 100644 --- a/Core/Stateflows.Common/StateMachines/Interfaces/IStateMachineLocator.cs +++ b/Core/Stateflows.Common/StateMachines/Interfaces/IStateMachineLocator.cs @@ -2,6 +2,6 @@ { public interface IStateMachineLocator { - bool TryLocateStateMachine(StateMachineId id, out IStateMachine stateMachine); + bool TryLocateStateMachine(StateMachineId id, out IStateMachineBehavior stateMachine); } } diff --git a/Core/Stateflows.Common/System/Classes/SystemBehavior.cs b/Core/Stateflows.Common/System/Classes/SystemBehavior.cs deleted file mode 100644 index c4e9d26f..00000000 --- a/Core/Stateflows.Common/System/Classes/SystemBehavior.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Stateflows.System -{ - public static class SystemBehavior - { - public readonly static BehaviorId Id = new BehaviorId("System", "Stateflows", ""); - } -} diff --git a/Core/Stateflows.Common/System/Classes/SystemWrapper.cs b/Core/Stateflows.Common/System/Classes/SystemWrapper.cs deleted file mode 100644 index 92879366..00000000 --- a/Core/Stateflows.Common/System/Classes/SystemWrapper.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Threading.Tasks; -using Stateflows.System; - -namespace Stateflows.Common.System.Classes -{ - internal class SystemWrapper : ISystem - { - private readonly IBehavior Behavior; - - public SystemWrapper(IBehavior behavior) - { - Behavior = behavior; - } - - public Task> GetAvailableBehaviorClassesAsync() - => Behavior.RequestAsync(new AvailableBehaviorClassesRequest()); - - public Task> GetBehaviorInstancesAsync() - => Behavior.RequestAsync(new BehaviorInstancesRequest()); - } -} diff --git a/Core/Stateflows.Common/System/Events/AvailableBehaviorClassesRequest.cs b/Core/Stateflows.Common/System/Events/AvailableBehaviorClassesRequest.cs deleted file mode 100644 index c4bae941..00000000 --- a/Core/Stateflows.Common/System/Events/AvailableBehaviorClassesRequest.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Stateflows.Common; - -namespace Stateflows.System -{ - public sealed class AvailableBehaviorClassesRequest : Request - { } -} diff --git a/Core/Stateflows.Common/System/Events/AvailableBehaviorClassesResponse.cs b/Core/Stateflows.Common/System/Events/AvailableBehaviorClassesResponse.cs deleted file mode 100644 index f6afab81..00000000 --- a/Core/Stateflows.Common/System/Events/AvailableBehaviorClassesResponse.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Stateflows.Common; -using System.Collections.Generic; - -namespace Stateflows.System -{ - public sealed class AvailableBehaviorClassesResponse : Response - { - public IEnumerable AvailableBehaviorClasses { get; set; } - } -} diff --git a/Core/Stateflows.Common/System/Events/BehaviorInstancesRequest.cs b/Core/Stateflows.Common/System/Events/BehaviorInstancesRequest.cs deleted file mode 100644 index c2ec7a39..00000000 --- a/Core/Stateflows.Common/System/Events/BehaviorInstancesRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Stateflows.Common; -using System.Collections.Generic; - -namespace Stateflows.System -{ - public sealed class BehaviorInstancesRequest : Request - { - public IEnumerable BehaviorClasses { get; set; } - } -} \ No newline at end of file diff --git a/Core/Stateflows.Common/System/Events/BehaviorInstancesResponse.cs b/Core/Stateflows.Common/System/Events/BehaviorInstancesResponse.cs deleted file mode 100644 index d849f425..00000000 --- a/Core/Stateflows.Common/System/Events/BehaviorInstancesResponse.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Stateflows.Common; -using System.Collections.Generic; - -namespace Stateflows.System -{ - public class BehaviorDescriptor - { - public BehaviorId Id { get; set; } - - public BehaviorStatus Status { get; set; } - } - - public sealed class BehaviorInstancesResponse : Response - { - public IEnumerable Behaviors { get; set; } - } -} diff --git a/Core/Stateflows.Common/System/Interfaces/ISystem.cs b/Core/Stateflows.Common/System/Interfaces/ISystem.cs deleted file mode 100644 index 329da3e4..00000000 --- a/Core/Stateflows.Common/System/Interfaces/ISystem.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Threading.Tasks; -using Stateflows.Common; - -namespace Stateflows.System -{ - public interface ISystem - { - Task> GetAvailableBehaviorClassesAsync(); - - Task> GetBehaviorInstancesAsync(); - } -} diff --git a/Core/Stateflows.Common/Utilities/DataBehaviorExtensions.cs b/Core/Stateflows.Common/Utilities/DataBehaviorExtensions.cs index 49f6d0ae..6bda4842 100644 --- a/Core/Stateflows.Common/Utilities/DataBehaviorExtensions.cs +++ b/Core/Stateflows.Common/Utilities/DataBehaviorExtensions.cs @@ -4,16 +4,16 @@ namespace Stateflows.Common.Data { public static class DataBehaviorExtensions { - public static Task> InitializeAsync(this IBehavior behavior, TInitializationPayload payload) - => behavior.InitializeAsync(payload.ToInitializationRequest()); + //public static Task> InitializeAsync(this IBehavior behavior, TInitializationPayload payload) + // => behavior.InitializeAsync(payload.ToInitialize()); - public static Task> ReinitializeAsync(this IBehavior behavior, TPayload payload, bool keepVersion = true) - => behavior.ReinitializeAsync(payload.ToInitializationRequest(), keepVersion); + //public static Task> ReinitializeAsync(this IBehavior behavior, TPayload payload, bool keepVersion = true) + // => behavior.ReinitializeAsync(payload.ToInitialize(), keepVersion); - public static Task SendAsync(this IBehavior behavior, TEventPayload payload) - => behavior.SendAsync(payload.ToEvent()); + //public static Task SendAsync(this IBehavior behavior, TEventPayload payload) + // => behavior.SendAsync(payload.ToEvent()); - public static Task>> RequestAsync(this IBehavior behavior, TRequestPayload payload) - => behavior.RequestAsync(payload.ToRequest()); + //public static Task>> RequestAsync(this IBehavior behavior, TRequestPayload payload) + // => behavior.RequestAsync(payload.ToRequest()); } } \ No newline at end of file diff --git a/Core/Stateflows.Common/Utilities/WaitHandleExtensions.cs b/Core/Stateflows.Common/Utilities/WaitHandleExtensions.cs index de0f45ce..b5f42dd3 100644 --- a/Core/Stateflows.Common/Utilities/WaitHandleExtensions.cs +++ b/Core/Stateflows.Common/Utilities/WaitHandleExtensions.cs @@ -1,10 +1,12 @@ -using System.Threading; +using System.Diagnostics; +using System.Threading; using System.Threading.Tasks; namespace Stateflows.Common.Utilities { public static class WaitHandleExtensions { + [DebuggerHidden] public static Task WaitOneAsync(this WaitHandle waitHandle, int millisecondsTimeout = -1) { waitHandle.ThrowIfNull(nameof(waitHandle)); diff --git a/Core/Stateflows.Testing/Activities/Cradle/Context/ActivityContext.cs b/Core/Stateflows.Testing/Activities/Cradle/Context/ActivityContext.cs deleted file mode 100644 index 5e60ad9a..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/Context/ActivityContext.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Stateflows.Activities; -using Stateflows.Activities.Context.Interfaces; -using Stateflows.Common; -using Stateflows.Common.Context.Interfaces; -using Stateflows.Common.Interfaces; -using System.Threading.Tasks; - -namespace Stateflows.Testing.Activities.Cradle.Context -{ - internal class ActivityContext : IActivityContext - { - public ActivityId Id { get; internal set; } - - public object LockHandle => this; - - public IContextValues Values => throw new global::System.NotImplementedException(); - - BehaviorId IBehaviorContext.Id => Id; - - public void Publish(TNotification notification) where TNotification : Notification, new() - { - throw new global::System.NotImplementedException(); - } - - public void Send(TEvent @event) where TEvent : Event, new() - { - throw new global::System.NotImplementedException(); - } - - public Task> SubscribeAsync(BehaviorId behaviorId) where TNotification : Notification, new() - { - throw new global::System.NotImplementedException(); - } - - public Task> UnsubscribeAsync(BehaviorId behaviorId) where TNotification : Notification, new() - { - throw new global::System.NotImplementedException(); - } - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/Context/NodeContext.cs b/Core/Stateflows.Testing/Activities/Cradle/Context/NodeContext.cs deleted file mode 100644 index de41fe97..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/Context/NodeContext.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Stateflows.Activities; -using Stateflows.Activities.Context.Interfaces; -using System.Collections.Generic; - -namespace Stateflows.Testing.Activities.Cradle.Context -{ - internal class NodeContext : INodeContext - { - public string NodeName { get; internal set; } - - public NodeType NodeType { get; internal set; } - - public INodeContext ParentNode { get; internal set; } - - public IEnumerable IncomingFlows { get; internal set; } - - public IEnumerable OutgoingFlows { get; internal set; } - - public bool TryGetParentNode(out INodeContext parentNodeContext) - => (parentNodeContext = ParentNode) != null; - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/Context/TypedActionContext.cs b/Core/Stateflows.Testing/Activities/Cradle/Context/TypedActionContext.cs deleted file mode 100644 index ced123bc..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/Context/TypedActionContext.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Threading; -using Stateflows.Common; -using Stateflows.Activities.Context.Interfaces; - -namespace Stateflows.Testing.Activities.Cradle.Context -{ - internal class TypedActionContext : ITypedActionContext - { - internal NodeContext currentNode; - public INodeContext CurrentNode => currentNode ??= new NodeContext(); - - internal CancellationToken cancellationToken; - public CancellationToken CancellationToken => cancellationToken; - - internal ActivityContext activity; - public IActivityContext Activity => activity ??= new ActivityContext(); - - public bool TryLocateBehavior(BehaviorId id, out IBehavior behavior) - { - throw new NotImplementedException(); - } - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/FlowTestCradle.cs b/Core/Stateflows.Testing/Activities/Cradle/FlowTestCradle.cs deleted file mode 100644 index ed078745..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/FlowTestCradle.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using Stateflows.Activities; -using Stateflows.Common.Interfaces; - -namespace Stateflows.Testing.Activities.Cradle -{ - internal class FlowTestCradle : ITestCradle - { - private readonly Flow testedFlow; - - private readonly List inputTokens; - - private readonly IContextValues contextValues; - - public FlowTestCradle(Flow flow, List inputTokens, IContextValues contextValues) - { - testedFlow = flow; - this.inputTokens = inputTokens; - this.contextValues = contextValues; - } - - private readonly List outputTokens = new List(); - - async Task ITestCradle.SwingAsync() - { - InputTokensHolder.Tokens.Value = inputTokens; - OutputTokensHolder.Tokens.Value = outputTokens; - - if (await testedFlow.GuardAsync()) - { - } - - InputTokensHolder.Tokens.Value = null; - OutputTokensHolder.Tokens.Value = null; - - return new TestResults(outputTokens, contextValues); - } - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/FlowTestCradleBuilder.cs b/Core/Stateflows.Testing/Activities/Cradle/FlowTestCradleBuilder.cs deleted file mode 100644 index e3050a1b..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/FlowTestCradleBuilder.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using Stateflows.Activities; -using Stateflows.Common.Classes; -using Stateflows.Common.Interfaces; -using Microsoft.Extensions.DependencyInjection; - -namespace Stateflows.Testing.Activities.Cradle -{ - internal class FlowTestCradleBuilder : IFlowTestCradleBuilder, IFlowTestCradleBuilderWithInput - where TActionNode : Flow - { - private readonly IServiceProvider serviceProvider; - - public FlowTestCradleBuilder(IServiceProvider serviceProvider) - { - this.serviceProvider = serviceProvider; - } - - private readonly Dictionary contextValuesCollection = new Dictionary(); - private IContextValues contextValues; - private IContextValues ContextValues - => contextValues ??= new ContextValues(contextValuesCollection); - - private readonly List InputTokens = new List(); - - IFlowTestCradleBuilderWithInput IFlowTestCradleBuilderWithInput.AddGlobalContextValue(string key, T value) - { - ContextValues.Set(key, value); - - return this; - } - - IFlowTestCradleBuilderWithInput IFlowTestCradleBuilder.AddInputToken(TToken token) - { - InputTokens.Add(new TokenHolder() { Payload = token }); - - return this; - } - - ITestCradle IFlowTestCradleBuilderWithInput.Build() - { - ContextValuesHolder.GlobalValues.Value = ContextValues; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = null; - ContextValuesHolder.TargetStateValues.Value = null; - - return new FlowTestCradle(serviceProvider.GetService(), InputTokens, ContextValues); - } - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/IFlowTestCradleBuilder.cs b/Core/Stateflows.Testing/Activities/Cradle/IFlowTestCradleBuilder.cs deleted file mode 100644 index ffd69c31..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/IFlowTestCradleBuilder.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Stateflows.Testing.Activities.Cradle -{ - public interface IFlowTestCradleBuilderWithInput - { - public IFlowTestCradleBuilderWithInput AddGlobalContextValue(string name, T value); - public ITestCradle Build(); - } - - public interface IFlowTestCradleBuilder - { - public IFlowTestCradleBuilderWithInput AddInputToken(TToken token); - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/INodeTestCradleBuilder.cs b/Core/Stateflows.Testing/Activities/Cradle/INodeTestCradleBuilder.cs deleted file mode 100644 index ec07515d..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/INodeTestCradleBuilder.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; - -namespace Stateflows.Testing.Activities.Cradle -{ - public interface INodeTestCradleBuilder - { - public INodeTestCradleBuilder AddGlobalContextValue(string name, T value); - public INodeTestCradleBuilder AddInputToken(T token); - public INodeTestCradleBuilder AddInputTokens(IEnumerable tokens); - public ITestCradle Build(); - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/ITestCradle.cs b/Core/Stateflows.Testing/Activities/Cradle/ITestCradle.cs deleted file mode 100644 index 7ac757aa..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/ITestCradle.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; - -namespace Stateflows.Testing.Activities.Cradle -{ - public interface ITestCradle - { - public Task SwingAsync(); - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/ITestResults.cs b/Core/Stateflows.Testing/Activities/Cradle/ITestResults.cs deleted file mode 100644 index f5c9ad7a..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/ITestResults.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Stateflows.Testing.Activities.Cradle -{ - public interface ITestResults - { - bool IsGlobalContextValueSet(string key); - public bool TryGetGlobalContextValue(string key, out T value); - public IEnumerable GetOutputTokens(); - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/NodeTestCradle.cs b/Core/Stateflows.Testing/Activities/Cradle/NodeTestCradle.cs deleted file mode 100644 index e8e4c5ce..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/NodeTestCradle.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using Stateflows.Activities; -using Stateflows.Common.Interfaces; - -namespace Stateflows.Testing.Activities.Cradle -{ - internal class NodeTestCradle : ITestCradle - { - private readonly ActionNode testedNode; - - private readonly List inputTokens; - - private readonly IContextValues contextValues; - - public NodeTestCradle(ActionNode node, List inputTokens, IContextValues contextValues) - { - testedNode = node; - this.inputTokens = inputTokens; - this.contextValues = contextValues; - } - - private readonly List outputTokens = new List(); - - async Task ITestCradle.SwingAsync() - { - InputTokensHolder.Tokens.Value = inputTokens; - OutputTokensHolder.Tokens.Value = outputTokens; - - await testedNode.ExecuteAsync(); - - InputTokensHolder.Tokens.Value = null; - OutputTokensHolder.Tokens.Value = null; - - return new TestResults(outputTokens, contextValues); - } - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/NodeTestCradleBuilder.cs b/Core/Stateflows.Testing/Activities/Cradle/NodeTestCradleBuilder.cs deleted file mode 100644 index 7f1a17f8..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/NodeTestCradleBuilder.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using Stateflows.Activities; -using Stateflows.Common.Classes; -using Stateflows.Common.Interfaces; -using Microsoft.Extensions.DependencyInjection; - -namespace Stateflows.Testing.Activities.Cradle -{ - internal class NodeTestCradleBuilder : INodeTestCradleBuilder - where TActionNode : ActionNode - { - private readonly IServiceProvider serviceProvider; - - public NodeTestCradleBuilder(IServiceProvider serviceProvider) - { - this.serviceProvider = serviceProvider; - } - - private readonly Dictionary contextValuesCollection = new Dictionary(); - private IContextValues contextValues; - private IContextValues ContextValues - => contextValues ??= new ContextValues(contextValuesCollection); - - private readonly List InputTokens = new List(); - - INodeTestCradleBuilder INodeTestCradleBuilder.AddGlobalContextValue(string key, T value) - { - ContextValues.Set(key, value); - - return this; - } - - INodeTestCradleBuilder INodeTestCradleBuilder.AddInputToken(T token) - { - InputTokens.Add(new TokenHolder() { Payload = token }); - - return this; - } - - INodeTestCradleBuilder INodeTestCradleBuilder.AddInputTokens(IEnumerable tokens) - { - InputTokens.AddRange(tokens.Select(token => new TokenHolder() { Payload = token })); - - return this; - } - - ITestCradle INodeTestCradleBuilder.Build() - { - ContextValuesHolder.GlobalValues.Value = ContextValues; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = null; - ContextValuesHolder.TargetStateValues.Value = null; - - return new NodeTestCradle(serviceProvider.GetService(), InputTokens, ContextValues); - } - } -} diff --git a/Core/Stateflows.Testing/Activities/Cradle/TestResults.cs b/Core/Stateflows.Testing/Activities/Cradle/TestResults.cs deleted file mode 100644 index ac2ccb11..00000000 --- a/Core/Stateflows.Testing/Activities/Cradle/TestResults.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Linq; -using System.Collections.Generic; -using Stateflows.Activities; -using Stateflows.Common.Interfaces; - -namespace Stateflows.Testing.Activities.Cradle -{ - internal class TestResults : ITestResults - { - public TestResults(List outputTokens, IContextValues contextValues) - { - this.outputTokens = outputTokens; - this.contextValues = contextValues; - } - - private readonly List outputTokens; - private readonly IContextValues contextValues; - - bool ITestResults.IsGlobalContextValueSet(string key) - => contextValues.IsSet(key); - - bool ITestResults.TryGetGlobalContextValue(string key, out T value) - => contextValues.TryGet(key, out value); - - IEnumerable ITestResults.GetOutputTokens() - => outputTokens.OfType>().Select(holder => holder.Payload).ToArray(); - } -} diff --git a/Core/Stateflows.Testing/StateMachines/Sequence/ExecutionSequence.cs b/Core/Stateflows.Testing/StateMachines/Sequence/ExecutionSequence.cs index b0ac8087..9d7c7c8e 100644 --- a/Core/Stateflows.Testing/StateMachines/Sequence/ExecutionSequence.cs +++ b/Core/Stateflows.Testing/StateMachines/Sequence/ExecutionSequence.cs @@ -42,11 +42,11 @@ public void ValidateWith(IExecutionSequenceBuilder sequenceBuilder) } } - public IExecutionSequenceBuilder DefaultTransitionEffect(string sourceStateName, string targetVertexName) - => TransitionEffect(EventInfo.Name, sourceStateName, targetVertexName); + public IExecutionSequenceBuilder DefaultTransitionEffect(string sourceStateName, string targetStateName) + => TransitionEffect(EventInfo.Name, sourceStateName, targetStateName); - public IExecutionSequenceBuilder DefaultTransitionGuard(string sourceStateName, string targetVertexName) - => TransitionGuard(EventInfo.Name, sourceStateName, targetVertexName); + public IExecutionSequenceBuilder DefaultTransitionGuard(string sourceStateName, string targetStateName) + => TransitionGuard(EventInfo.Name, sourceStateName, targetStateName); public IExecutionSequenceBuilder InternalTransitionEffect(string eventName, string sourceStateName) => TransitionEffect(eventName, sourceStateName, ""); @@ -90,15 +90,15 @@ public IExecutionSequenceBuilder StateMachineFinalize() return this; } - public IExecutionSequenceBuilder TransitionEffect(string eventName, string sourceStateName, string? targetVertexName) + public IExecutionSequenceBuilder TransitionEffect(string eventName, string sourceStateName, string? targetStateName) { - Sequence.Add($"{sourceStateName}--{eventName}/effect-->{targetVertexName ?? string.Empty}"); + Sequence.Add($"{sourceStateName}--{eventName}/effect-->{targetStateName ?? string.Empty}"); return this; } - public IExecutionSequenceBuilder TransitionGuard(string eventName, string sourceStateName, string? targetVertexName) + public IExecutionSequenceBuilder TransitionGuard(string eventName, string sourceStateName, string? targetStateName) { - Sequence.Add($"{sourceStateName}--{eventName}[guard]-->{targetVertexName ?? string.Empty}"); + Sequence.Add($"{sourceStateName}--{eventName}[guard]-->{targetStateName ?? string.Empty}"); return this; } } diff --git a/Core/Stateflows.Testing/StateMachines/Sequence/ExecutionSequenceObserver.cs b/Core/Stateflows.Testing/StateMachines/Sequence/ExecutionSequenceObserver.cs index 9bbf0ad1..5bd40b80 100644 --- a/Core/Stateflows.Testing/StateMachines/Sequence/ExecutionSequenceObserver.cs +++ b/Core/Stateflows.Testing/StateMachines/Sequence/ExecutionSequenceObserver.cs @@ -50,7 +50,7 @@ Task IStateMachineObserver.AfterStateFinalizeAsync(IStateActionContext context) return Task.CompletedTask; } - Task IStateMachineObserver.AfterStateMachineInitializeAsync(IStateMachineInitializationContext context) + Task IStateMachineObserver.AfterStateMachineInitializeAsync(IStateMachineInitializationContext context, bool initialized) { SequenceBuilder.StateMachineInitialize(); @@ -77,45 +77,5 @@ Task IStateMachineObserver.AfterTransitionGuardAsync(IGuardContext contex return Task.CompletedTask; } - - Task IStateMachineObserver.BeforeStateEntryAsync(IStateActionContext context) - { - return Task.CompletedTask; - } - - Task IStateMachineObserver.BeforeStateExitAsync(IStateActionContext context) - { - return Task.CompletedTask; - } - - Task IStateMachineObserver.BeforeStateInitializeAsync(IStateActionContext context) - { - return Task.CompletedTask; - } - - Task IStateMachineObserver.BeforeStateFinalizeAsync(IStateActionContext context) - { - return Task.CompletedTask; - } - - Task IStateMachineObserver.BeforeStateMachineInitializeAsync(IStateMachineInitializationContext context) - { - return Task.CompletedTask; - } - - Task IStateMachineObserver.BeforeStateMachineFinalizeAsync(IStateMachineActionContext context) - { - return Task.CompletedTask; - } - - Task IStateMachineObserver.BeforeTransitionEffectAsync(ITransitionContext context) - { - return Task.CompletedTask; - } - - Task IStateMachineObserver.BeforeTransitionGuardAsync(IGuardContext context) - { - return Task.CompletedTask; - } } } diff --git a/Core/Stateflows.Testing/StateMachines/Sequence/IExecutionSequenceBuilder.cs b/Core/Stateflows.Testing/StateMachines/Sequence/IExecutionSequenceBuilder.cs index ec670bae..b3d6a73c 100644 --- a/Core/Stateflows.Testing/StateMachines/Sequence/IExecutionSequenceBuilder.cs +++ b/Core/Stateflows.Testing/StateMachines/Sequence/IExecutionSequenceBuilder.cs @@ -12,13 +12,13 @@ public interface IExecutionSequenceBuilder IExecutionSequenceBuilder StateEntry(string stateName); IExecutionSequenceBuilder StateExit(string stateName); - IExecutionSequenceBuilder TransitionGuard(string eventName, string sourceStateName, string? targetVertexName); - IExecutionSequenceBuilder TransitionEffect(string eventName, string sourceStateName, string? targetVertexName); + IExecutionSequenceBuilder TransitionGuard(string eventName, string sourceStateName, string? targetStateName); + IExecutionSequenceBuilder TransitionEffect(string eventName, string sourceStateName, string? targetStateName); IExecutionSequenceBuilder InternalTransitionGuard(string eventName, string sourceStateName); IExecutionSequenceBuilder InternalTransitionEffect(string eventName, string sourceStateName); - IExecutionSequenceBuilder DefaultTransitionGuard(string sourceStateName, string targetVertexName); - IExecutionSequenceBuilder DefaultTransitionEffect(string sourceStateName, string targetVertexName); + IExecutionSequenceBuilder DefaultTransitionGuard(string sourceStateName, string targetStateName); + IExecutionSequenceBuilder DefaultTransitionEffect(string sourceStateName, string targetStateName); } } diff --git a/Core/Stateflows.Testing/StateflowsTestClass.cs b/Core/Stateflows.Testing/StateflowsTestClass.cs index 12792bdf..71f77264 100644 --- a/Core/Stateflows.Testing/StateflowsTestClass.cs +++ b/Core/Stateflows.Testing/StateflowsTestClass.cs @@ -10,31 +10,23 @@ using Stateflows.Activities; using Stateflows.StateMachines; using Stateflows.Common.Registration.Interfaces; -using Stateflows.Testing.Activities.Cradle; using Stateflows.Testing.StateMachines.Sequence; +using Stateflows.Common.Classes; namespace StateMachine.IntegrationTests.Utils { public abstract class StateflowsTestClass { private IServiceCollection _serviceCollection; - protected IServiceCollection ServiceCollection => _serviceCollection ?? (_serviceCollection = new ServiceCollection()); + protected IServiceCollection ServiceCollection => _serviceCollection ??= new ServiceCollection(); private IServiceProvider _serviceProvider; - protected IServiceProvider ServiceProvider => _serviceProvider ?? (_serviceProvider = ServiceCollection.BuildServiceProvider()); + protected IServiceProvider ServiceProvider => _serviceProvider ??= ServiceCollection.BuildServiceProvider(); protected IStateMachineLocator StateMachineLocator => ServiceProvider.GetRequiredService(); protected IActivityLocator ActivityLocator => ServiceProvider.GetRequiredService(); - //protected IFlowTestCradleBuilder SetupCradle() - // where TFlow : Flow - // => new FlowTestCradleBuilder(ServiceProvider); - - protected INodeTestCradleBuilder SetupCradle() - where TActionNode : ActionNode - => new NodeTestCradleBuilder(ServiceProvider); - protected ExecutionSequenceObserver ExecutionSequence => ServiceProvider.GetRequiredService(); public virtual void Initialize() @@ -45,6 +37,11 @@ public virtual void Initialize() var hostedServices = ServiceProvider.GetRequiredService>(); Task.WaitAll(hostedServices.Select(s => s.StartAsync(new CancellationToken())).ToArray()); + + ContextValues.GlobalValues.Clear(); + ContextValues.StateValues.Clear(); + ContextValues.SourceStateValues.Clear(); + ContextValues.TargetStateValues.Clear(); } public virtual void Cleanup() diff --git a/Core/Stateflows.Transport.Common/Stateflows.Common.Transport.csproj b/Core/Stateflows.Transport.Common/Stateflows.Common.Transport.csproj index 3b3de483..bb2faf7a 100644 --- a/Core/Stateflows.Transport.Common/Stateflows.Common.Transport.csproj +++ b/Core/Stateflows.Transport.Common/Stateflows.Common.Transport.csproj @@ -35,4 +35,8 @@ + + + + diff --git a/Core/Stateflows/Activities/ActivitiesDependencyInjection.cs b/Core/Stateflows/Activities/ActivitiesDependencyInjection.cs index bf6952d4..06b164e0 100644 --- a/Core/Stateflows/Activities/ActivitiesDependencyInjection.cs +++ b/Core/Stateflows/Activities/ActivitiesDependencyInjection.cs @@ -2,13 +2,15 @@ using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; using Stateflows.Common.Interfaces; -using Stateflows.Common.Initializer; using Stateflows.Common.Registration.Interfaces; using Stateflows.Activities.Engine; using Stateflows.Activities.Registration; using Stateflows.Activities.EventHandlers; using Stateflows.Activities.Registration.Builders; using Stateflows.Activities.Registration.Interfaces; +using System; +using Stateflows.Activities.Context; +using Stateflows.Activities.Context.Interfaces; namespace Stateflows.Activities { @@ -24,12 +26,6 @@ public static IStateflowsBuilder AddActivities(this IStateflowsBuilder stateflow return stateflowsBuilder; } - [DebuggerHidden] - public static IStateflowsBuilder AddDefaultInstance(this IStateflowsBuilder stateflowsBuilder, DefaultInstanceInitializationRequestFactoryAsync initializationRequestFactoryAsync = null) - where TActivity: Activity - => stateflowsBuilder.AddDefaultInstance(new ActivityClass(ActivityInfo.Name).BehaviorClass, initializationRequestFactoryAsync); - - private static ActivitiesRegister EnsureActivitiesServices(this IStateflowsBuilder stateflowsBuilder) { if (!Registers.TryGetValue(stateflowsBuilder, out var register)) @@ -46,13 +42,32 @@ private static ActivitiesRegister EnsureActivitiesServices(this IStateflowsBuild .AddScoped() .AddTransient() .AddSingleton() - .AddSingleton() - .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() + .AddTransient(provider => + ContextHolder.ActivityContext.Value ?? + throw new InvalidOperationException($"No service for type '{typeof(IActivityContext).FullName}' is available in this context.") + ) + .AddTransient(provider => + ContextHolder.NodeContext.Value ?? + throw new InvalidOperationException($"No service for type '{typeof(INodeContext).FullName}' is available in this context.") + ) + .AddTransient(provider => + ContextHolder.FlowContext.Value ?? + throw new InvalidOperationException($"No service for type '{typeof(IFlowContext).FullName}' is available in this context.") + ) + .AddTransient(provider => + ContextHolder.ExecutionContext.Value ?? + throw new InvalidOperationException($"No service for type '{typeof(IExecutionContext).FullName}' is available in this context.") + ) + .AddTransient(provider => + ContextHolder.ExceptionContext.Value ?? + throw new InvalidOperationException($"No service for type '{typeof(IExceptionContext).FullName}' is available in this context.") + ) ; } diff --git a/Core/Stateflows/Activities/Classes/AcceptEventActionNode.cs b/Core/Stateflows/Activities/Classes/AcceptEventActionNode.cs index 324b7e09..b5b663ba 100644 --- a/Core/Stateflows/Activities/Classes/AcceptEventActionNode.cs +++ b/Core/Stateflows/Activities/Classes/AcceptEventActionNode.cs @@ -1,12 +1,15 @@ -using Stateflows.Common; -using Stateflows.Activities.Context.Interfaces; +using System.Threading; +using System.Threading.Tasks; +using Stateflows.Common; namespace Stateflows.Activities { - public abstract class AcceptEventActionNode : BaseActionNode + public sealed class AcceptEventActionNode : IAcceptEventActionNode where TEvent : Event, new() { - public new IAcceptEventActionContext Context - => (IAcceptEventActionContext)base.Context; + public Task ExecuteAsync(TEvent @event, CancellationToken cancellationToken) + => Task.CompletedTask; + + public static string Name => ActivityNode>.Name; } } diff --git a/Core/Stateflows/Activities/Classes/ActionNode.cs b/Core/Stateflows/Activities/Classes/ActionNode.cs deleted file mode 100644 index 47d2742d..00000000 --- a/Core/Stateflows/Activities/Classes/ActionNode.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Threading.Tasks; - -namespace Stateflows.Activities -{ - public abstract class BaseActionNode : ActivityNode - { - public abstract Task ExecuteAsync(); - } - - public abstract class ActionNode : BaseActionNode - { } -} diff --git a/Core/Stateflows/Activities/Classes/Activity.cs b/Core/Stateflows/Activities/Classes/Activity.cs deleted file mode 100644 index 310cc40d..00000000 --- a/Core/Stateflows/Activities/Classes/Activity.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Reflection; -using System.Threading.Tasks; -using Stateflows.Common; -using Stateflows.Activities.Attributes; -using Stateflows.Activities.Context.Interfaces; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities -{ - public abstract class Activity - { - public IActivityActionContext Context { get; internal set; } - - public virtual Task OnInitializeAsync() - => Task.FromResult(true); - - public virtual Task OnFinalizeAsync() - => Task.CompletedTask; - - public abstract void Build(ITypedActivityBuilder builder); - } - - public abstract class Activity : Activity, IInitializedBy - where TInitializationRequest : InitializationRequest, new() - { - public abstract Task OnInitializeAsync(TInitializationRequest initializationRequest); - } - - public abstract class Activity : Activity, IInitializedBy - where TInitializationRequest1 : InitializationRequest, new() - where TInitializationRequest2 : InitializationRequest, new() - { - public abstract Task OnInitializeAsync(TInitializationRequest2 initializationRequest); - } - - public abstract class Activity : Activity, IInitializedBy - where TInitializationRequest1 : InitializationRequest, new() - where TInitializationRequest2 : InitializationRequest, new() - where TInitializationRequest3 : InitializationRequest, new() - { - public abstract Task OnInitializeAsync(TInitializationRequest3 initializationRequest); - } - - public static class ActivityInfo - where TActivity : Activity - { - public static string Name - { - get - { - var stateMachineType = typeof(TActivity); - var attribute = stateMachineType.GetCustomAttribute(); - return attribute != null && attribute.Name != null - ? attribute.Name - : stateMachineType.FullName; - } - } - - public static BehaviorClass ToClass() - => new BehaviorClass(BehaviorType.Activity, Name); - - public static BehaviorId ToId(string instance) - => new BehaviorId(ToClass(), instance); - } -} diff --git a/Core/Stateflows/Activities/Classes/ActivityNode.cs b/Core/Stateflows/Activities/Classes/ActivityNode.cs index 16def715..7b72f99a 100644 --- a/Core/Stateflows/Activities/Classes/ActivityNode.cs +++ b/Core/Stateflows/Activities/Classes/ActivityNode.cs @@ -1,18 +1,5 @@ -using Stateflows.Common.Extensions; -using Stateflows.Activities.Context.Classes; -using Stateflows.Activities.Context.Interfaces; - -namespace Stateflows.Activities +namespace Stateflows.Activities { - public abstract class ActivityNode - { - public ITypedActionContext Context - => (ITypedActionContext)ActivityNodeContextAccessor.Context.Value; - } - - public static class ActivityNodeInfo - where TNode : ActivityNode - { - public static string Name => typeof(TNode).GetReadableName(); - } + public abstract class ActivityNode : IActivityNode + { } } diff --git a/Core/Stateflows/Activities/Classes/ControlDecisionNode.cs b/Core/Stateflows/Activities/Classes/ControlDecisionNode.cs index 8be9676b..949e68ca 100644 --- a/Core/Stateflows/Activities/Classes/ControlDecisionNode.cs +++ b/Core/Stateflows/Activities/Classes/ControlDecisionNode.cs @@ -1,9 +1,7 @@ -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities +namespace Stateflows.Activities { public sealed class ControlDecisionNode : ActivityNode { - public static string Name => typeof(DecisionNode).GetReadableName(); + public static string Name => ActivityNode.Name; } } diff --git a/Core/Stateflows/Activities/Classes/DataStoreNode.cs b/Core/Stateflows/Activities/Classes/DataStoreNode.cs new file mode 100644 index 00000000..fe90d10d --- /dev/null +++ b/Core/Stateflows/Activities/Classes/DataStoreNode.cs @@ -0,0 +1,7 @@ +namespace Stateflows.Activities +{ + public sealed class DataStoreNode : ActivityNode + { + public static string Name => ActivityNode.Name; + } +} diff --git a/Core/Stateflows/Activities/Classes/DecisionNode.cs b/Core/Stateflows/Activities/Classes/DecisionNode.cs index c8955b55..3ae96c64 100644 --- a/Core/Stateflows/Activities/Classes/DecisionNode.cs +++ b/Core/Stateflows/Activities/Classes/DecisionNode.cs @@ -1,9 +1,7 @@ -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities +namespace Stateflows.Activities { public sealed class DecisionNode : ActivityNode { - public static string Name => typeof(DecisionNode).GetReadableName(); + public static string Name => ActivityNode>.Name; } } diff --git a/Core/Stateflows/Activities/Classes/ElseFlow.cs b/Core/Stateflows/Activities/Classes/ElseFlow.cs deleted file mode 100644 index 46fb09d3..00000000 --- a/Core/Stateflows/Activities/Classes/ElseFlow.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; - -namespace Stateflows.Activities -{ - //public abstract class ElseControlFlow : BaseControlFlow - //{ - // public override sealed Task GuardAsync() - // => Task.FromResult(true); - //} - - //public abstract class ElseFlow : BaseFlow - //{ - // public override sealed Task GuardAsync() - // => Task.FromResult(true); - //} - - public abstract class ElseTransformationFlow : BaseTransformationFlow - { - public override sealed Task GuardAsync() - => Task.FromResult(true); - } -} diff --git a/Core/Stateflows/Activities/Classes/ExceptionHandlerNode.cs b/Core/Stateflows/Activities/Classes/ExceptionHandlerNode.cs deleted file mode 100644 index 7d27ce22..00000000 --- a/Core/Stateflows/Activities/Classes/ExceptionHandlerNode.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Threading.Tasks; -using Stateflows.Activities.Context.Interfaces; - -namespace Stateflows.Activities -{ - public abstract class ExceptionHandlerNode : ActivityNode - where TException : Exception - { - new public IExceptionHandlerContext Context => base.Context as IExceptionHandlerContext; - - public abstract Task HandleAsync(); - } - - public abstract class ExceptionHandler : ExceptionHandlerNode - { } -} diff --git a/Core/Stateflows/Activities/Classes/FinalNode.cs b/Core/Stateflows/Activities/Classes/FinalNode.cs index 24c31844..2059b42a 100644 --- a/Core/Stateflows/Activities/Classes/FinalNode.cs +++ b/Core/Stateflows/Activities/Classes/FinalNode.cs @@ -1,9 +1,7 @@ -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities +namespace Stateflows.Activities { public sealed class FinalNode : ActivityNode { - public static string Name => typeof(FinalNode).GetReadableName(); + public static string Name => ActivityNode.Name; } } diff --git a/Core/Stateflows/Activities/Classes/Flow.cs b/Core/Stateflows/Activities/Classes/Flow.cs deleted file mode 100644 index c6a84422..00000000 --- a/Core/Stateflows/Activities/Classes/Flow.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Threading.Tasks; -using Stateflows.Activities.Context.Classes; -using Stateflows.Activities.Context.Interfaces; - -namespace Stateflows.Activities -{ - public abstract class BaseControlFlow - { - public IActivityFlowContext Context => ActivityFlowContextAccessor.Context.Value; - - public virtual Task GuardAsync() - => Task.FromResult(true); - } - - public abstract class ControlFlow : BaseControlFlow - { } - - public abstract class BaseFlow : BaseControlFlow - { - public virtual int Weight => 1; - - new public IActivityFlowContext Context - => (IActivityFlowContext)base.Context; - } - - public abstract class Flow : BaseFlow - { } - - public abstract class BaseTransformationFlow : BaseControlFlow - { - public virtual int Weight => 1; - - new public IActivityFlowContext Context - => (IActivityFlowContext)base.Context; - - public abstract Task TransformAsync(); - } - - public abstract class TransformationFlow : BaseTransformationFlow - { } -} diff --git a/Core/Stateflows/Activities/Classes/ForkNode.cs b/Core/Stateflows/Activities/Classes/ForkNode.cs index d790774b..da5357e3 100644 --- a/Core/Stateflows/Activities/Classes/ForkNode.cs +++ b/Core/Stateflows/Activities/Classes/ForkNode.cs @@ -1,9 +1,7 @@ -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities +namespace Stateflows.Activities { public sealed class ForkNode : ActivityNode { - public static string Name => typeof(ForkNode).GetReadableName(); + public static string Name => ActivityNode.Name; } } diff --git a/Core/Stateflows/Activities/Classes/IterativeActivityNode.cs b/Core/Stateflows/Activities/Classes/IterativeActivityNode.cs index 7bd26709..3786c936 100644 --- a/Core/Stateflows/Activities/Classes/IterativeActivityNode.cs +++ b/Core/Stateflows/Activities/Classes/IterativeActivityNode.cs @@ -1,9 +1,7 @@ -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities +namespace Stateflows.Activities { - public abstract class IterativeActivityNode : StructuredActivityNode + public sealed class IterativeActivityNode : IBaseStructuredActivityNode { - public static string Name => typeof(IterativeActivityNode).GetReadableName(); + public static string Name => ActivityNode>.Name; } } diff --git a/Core/Stateflows/Activities/Classes/JoinNode.cs b/Core/Stateflows/Activities/Classes/JoinNode.cs index 0b436578..3fb4f2b0 100644 --- a/Core/Stateflows/Activities/Classes/JoinNode.cs +++ b/Core/Stateflows/Activities/Classes/JoinNode.cs @@ -1,9 +1,7 @@ -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities +namespace Stateflows.Activities { public sealed class JoinNode : ActivityNode { - public static string Name => typeof(JoinNode).GetReadableName(); + public static string Name => ActivityNode.Name; } } diff --git a/Core/Stateflows/Activities/Classes/MergeNode.cs b/Core/Stateflows/Activities/Classes/MergeNode.cs index c0f2a082..471713d2 100644 --- a/Core/Stateflows/Activities/Classes/MergeNode.cs +++ b/Core/Stateflows/Activities/Classes/MergeNode.cs @@ -1,9 +1,7 @@ -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities +namespace Stateflows.Activities { public sealed class MergeNode : ActivityNode { - public static string Name => typeof(MergeNode).GetReadableName(); + public static string Name => ActivityNode.Name; } } diff --git a/Core/Stateflows/Activities/Classes/OutputNode.cs b/Core/Stateflows/Activities/Classes/OutputNode.cs index 944f3481..4fd00ad8 100644 --- a/Core/Stateflows/Activities/Classes/OutputNode.cs +++ b/Core/Stateflows/Activities/Classes/OutputNode.cs @@ -1,9 +1,7 @@ -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities +namespace Stateflows.Activities { public sealed class OutputNode : ActivityNode { - public static string Name => typeof(OutputNode).GetReadableName(); + public static string Name => ActivityNode.Name; } } diff --git a/Core/Stateflows/Activities/Classes/ParalellActivityNode.cs b/Core/Stateflows/Activities/Classes/ParalellActivityNode.cs index 1eb81ea2..8dd41d15 100644 --- a/Core/Stateflows/Activities/Classes/ParalellActivityNode.cs +++ b/Core/Stateflows/Activities/Classes/ParalellActivityNode.cs @@ -1,9 +1,7 @@ -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities +namespace Stateflows.Activities { - public abstract class ParallelActivityNode : StructuredActivityNode + public sealed class ParallelActivityNode : IBaseStructuredActivityNode { - public static string Name => typeof(ParallelActivityNode).GetReadableName(); + public static string Name => ActivityNode>.Name; } } diff --git a/Core/Stateflows/Activities/Classes/SendEventActionNode.cs b/Core/Stateflows/Activities/Classes/SendEventActionNode.cs deleted file mode 100644 index 91c98c13..00000000 --- a/Core/Stateflows/Activities/Classes/SendEventActionNode.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Threading.Tasks; -using Stateflows.Common; - -namespace Stateflows.Activities -{ - public abstract class SendEventActionNode : ActivityNode - where TEvent : Event, new() - { - public abstract Task GenerateEventAsync(); - - public abstract Task SelectTargetAsync(); - } -} diff --git a/Core/Stateflows/Activities/Classes/StructuredActivityNode.cs b/Core/Stateflows/Activities/Classes/StructuredActivityNode.cs index 5ef4f84f..485457a1 100644 --- a/Core/Stateflows/Activities/Classes/StructuredActivityNode.cs +++ b/Core/Stateflows/Activities/Classes/StructuredActivityNode.cs @@ -1,19 +1,7 @@ -using System.Threading.Tasks; -using Stateflows.Activities.Context.Interfaces; - -namespace Stateflows.Activities +namespace Stateflows.Activities { - public abstract class StructuredActivityNode : ActivityNode + public sealed class StructuredActivityNode : ActivityNode, IBaseStructuredActivityNode { - public virtual Task OnInitializeAsync() - => Task.CompletedTask; - - public virtual Task OnFinalizeAsync() - => Task.CompletedTask; - } - - public abstract class StructuredActivityNode : StructuredActivityNode - { - public new IActionContext Context => base.Context as IActionContext; + public static string Name => ActivityNode.Name; } } diff --git a/Core/Stateflows/Activities/Classes/TimeEventActionNode.cs b/Core/Stateflows/Activities/Classes/TimeEventActionNode.cs new file mode 100644 index 00000000..d4fb1454 --- /dev/null +++ b/Core/Stateflows/Activities/Classes/TimeEventActionNode.cs @@ -0,0 +1,15 @@ +using System.Threading; +using System.Threading.Tasks; +using Stateflows.Common; + +namespace Stateflows.Activities +{ + public sealed class TimeEventActionNode : IAcceptEventActionNode + where TEvent : TimeEvent, new() + { + public Task ExecuteAsync(TEvent @event, CancellationToken cancellationToken) + => Task.CompletedTask; + + public static string Name => ActivityNode>.Name; + } +} diff --git a/Core/Stateflows/Activities/Classes/TokensAccessor.cs b/Core/Stateflows/Activities/Classes/TokensAccessor.cs index 13b6e91e..c9e7920e 100644 --- a/Core/Stateflows/Activities/Classes/TokensAccessor.cs +++ b/Core/Stateflows/Activities/Classes/TokensAccessor.cs @@ -1,20 +1,20 @@ using Stateflows.Activities.Interfaces; using System.Collections.Generic; -namespace Stateflows.Activities +namespace Stateflows.Activities.Classes { public class TokensAccessor : ITokensAccessor { public List InputTokens { - get => InputTokensHolder.Tokens.Value; - set => InputTokensHolder.Tokens.Value = value; + get => Activities.InputTokens.TokensHolder.Value; + set => Activities.InputTokens.TokensHolder.Value = value; } public List OutputTokens { - get => OutputTokensHolder.Tokens.Value; - set => OutputTokensHolder.Tokens.Value = value; + get => Activities.OutputTokens.TokensHolder.Value; + set => Activities.OutputTokens.TokensHolder.Value = value; } } } diff --git a/Core/Stateflows/Activities/Collections/Input.cs b/Core/Stateflows/Activities/Collections/Input.cs index f2981aad..0c45f8fa 100644 --- a/Core/Stateflows/Activities/Collections/Input.cs +++ b/Core/Stateflows/Activities/Collections/Input.cs @@ -1,21 +1,28 @@ -using System; -using System.Linq; +using System.Linq; using System.Threading; using System.Collections; using System.Collections.Generic; namespace Stateflows.Activities { - public static class InputTokensHolder + public static class InputTokens { - public static readonly AsyncLocal> Tokens = new AsyncLocal>(); + internal static readonly AsyncLocal> TokensHolder = new AsyncLocal>(); + + internal static List Tokens + => TokensHolder.Value ??= new List(); + + public static void Add(TToken token) + => Tokens.Add(new TokenHolder() { Payload = token }); + + public static void AddRange(IEnumerable tokens) + => Tokens.AddRange(tokens.Select(token => new TokenHolder() { Payload = token })); } - [Serializable] public struct Input : IEnumerable { private readonly IEnumerable Tokens - => InputTokensHolder.Tokens.Value.OfType>().Select(t => t.Payload); + => InputTokens.Tokens.OfType>().Select(t => t.Payload); public readonly IEnumerator GetEnumerator() => Tokens.GetEnumerator(); @@ -27,21 +34,19 @@ public readonly void PassAllOn() => new Output().AddRange(Tokens); } - [Serializable] public struct SingleInput { public readonly TToken Token - => InputTokensHolder.Tokens.Value.OfType>().Select(t => t.Payload).First(); + => InputTokens.Tokens.OfType>().Select(t => t.Payload).First(); public readonly void PassOn() => new Output().Add(Token); } - [Serializable] public struct OptionalInput : IEnumerable { private readonly IEnumerable Tokens - => InputTokensHolder.Tokens.Value.OfType>().Select(t => t.Payload); + => InputTokens.Tokens.OfType>().Select(t => t.Payload); public readonly IEnumerator GetEnumerator() => Tokens.GetEnumerator(); @@ -53,11 +58,10 @@ public readonly void PassAllOn() => new Output().AddRange(Tokens); } - [Serializable] public struct OptionalSingleInput { public readonly TToken Token - => InputTokensHolder.Tokens.Value.OfType>().Select(t => t.Payload).First(); + => InputTokens.Tokens.OfType>().Select(t => t.Payload).First(); public readonly void PassOn() => new Output().Add(Token); diff --git a/Core/Stateflows/Activities/Collections/Output.cs b/Core/Stateflows/Activities/Collections/Output.cs index 6061bbfc..4c5e55ff 100644 --- a/Core/Stateflows/Activities/Collections/Output.cs +++ b/Core/Stateflows/Activities/Collections/Output.cs @@ -6,42 +6,48 @@ namespace Stateflows.Activities { - public static class OutputTokensHolder + public static class OutputTokens { - public static readonly AsyncLocal> Tokens = new AsyncLocal>(); + internal static readonly AsyncLocal> TokensHolder = new AsyncLocal>(); + + internal static List Tokens + => TokensHolder.Value ??= new List(); + + public static List Get() + => Tokens.OfType>().FromTokens().ToList(); + + public static int Count => Tokens.Count; + + public static bool Contains(TToken item) + => Tokens.Contains(item.ToTokenHolder()); } public struct Output : ICollection { private readonly List GetTokens() - => OutputTokensHolder.Tokens.Value.OfType>().FromTokens().ToList(); + => OutputTokens.Tokens.OfType>().FromTokens().ToList(); public readonly int Count => GetTokens().Count; public readonly bool IsReadOnly => false; public readonly void Add(TToken item) - => OutputTokensHolder.Tokens.Value.Add(item.ToTokenHolder()); + => OutputTokens.Tokens.Add(item.ToTokenHolder()); public readonly void AddRange(IEnumerable items) - { - foreach (var item in items) - { - OutputTokensHolder.Tokens.Value.Add(item.ToTokenHolder()); - } - } + => OutputTokens.Tokens.AddRange(items.Select(item => item.ToTokenHolder())); public readonly void Clear() - => OutputTokensHolder.Tokens.Value.RemoveAll(token => token is TToken); + => OutputTokens.Tokens.RemoveAll(token => token is TToken); public readonly bool Contains(TToken item) - => OutputTokensHolder.Tokens.Value.Contains(item.ToTokenHolder()); + => OutputTokens.Tokens.Contains(item.ToTokenHolder()); public readonly void CopyTo(TToken[] array, int arrayIndex) - => OutputTokensHolder.Tokens.Value.CopyTo(array.ToTokens().ToArray(), arrayIndex); + => OutputTokens.Tokens.CopyTo(array.ToTokens().ToArray(), arrayIndex); public readonly bool Remove(TToken item) - => OutputTokensHolder.Tokens.Value.Remove(item.ToTokenHolder()); + => OutputTokens.Tokens.Remove(item.ToTokenHolder()); public readonly IEnumerator GetEnumerator() => GetTokens().GetEnumerator(); diff --git a/Core/Stateflows/Activities/Context/Classes/ActivityContext.cs b/Core/Stateflows/Activities/Context/Classes/ActivityContext.cs index 6a9393f7..8f9e82af 100644 --- a/Core/Stateflows/Activities/Context/Classes/ActivityContext.cs +++ b/Core/Stateflows/Activities/Context/Classes/ActivityContext.cs @@ -25,7 +25,7 @@ private BehaviorSubscriber Subscriber public ActivityContext(RootContext context, NodeScope nodeScope) : base(context, nodeScope) { - Values = new ContextValues(Context.GlobalValues); + Values = new ContextValuesCollection(Context.GlobalValues); } public IActivityInspection Inspection => Context.Executor.Inspector.Inspection; diff --git a/Core/Stateflows/Activities/Context/Classes/ActivityInitializationContext.cs b/Core/Stateflows/Activities/Context/Classes/ActivityInitializationContext.cs index 3199179e..2bccbb27 100644 --- a/Core/Stateflows/Activities/Context/Classes/ActivityInitializationContext.cs +++ b/Core/Stateflows/Activities/Context/Classes/ActivityInitializationContext.cs @@ -5,40 +5,40 @@ namespace Stateflows.Activities.Context.Classes { - internal class ActivityInitializationContext : + internal class ActivityInitializationContext : BaseContext, - IActivityInitializationContext, + IActivityInitializationContext, IRootContext - where TInitializationRequest : InitializationRequest + where TInitializationEvent : Event, new() { - public ActivityInitializationContext(RootContext context, NodeScope nodeScope, TInitializationRequest initializationRequest) + public ActivityInitializationContext(RootContext context, NodeScope nodeScope, TInitializationEvent initializationEvent) : base(context, nodeScope) { - InitializationRequest = initializationRequest; + InitializationEvent = initializationEvent; } - public ActivityInitializationContext(BaseContext context, TInitializationRequest initializationRequest) + public ActivityInitializationContext(BaseContext context, TInitializationEvent initializationEvent) : base(context) { - InitializationRequest = initializationRequest; + InitializationEvent = initializationEvent; } IActivityContext IActivityActionContext.Activity => Activity; - public TInitializationRequest InitializationRequest { get; } + public TInitializationEvent InitializationEvent { get; } } internal class ActivityInitializationContext : - ActivityInitializationContext, + ActivityInitializationContext, IActivityInitializationInspectionContext, IRootContext { - public ActivityInitializationContext(BaseContext context, InitializationRequest initializationRequest) - : base(context, initializationRequest) + public ActivityInitializationContext(BaseContext context, Event initializationEvent) + : base(context, initializationEvent) { } - public ActivityInitializationContext(RootContext context, NodeScope nodeScope, InitializationRequest initializationRequest) - : base(context, nodeScope, initializationRequest) + public ActivityInitializationContext(RootContext context, NodeScope nodeScope, Event initializationEvent) + : base(context, nodeScope, initializationEvent) { } IActivityInspectionContext IActivityInitializationInspectionContext.Activity => Activity; diff --git a/Core/Stateflows/Activities/Context/Classes/BaseContext.cs b/Core/Stateflows/Activities/Context/Classes/BaseContext.cs index f52285be..4ac61968 100644 --- a/Core/Stateflows/Activities/Context/Classes/BaseContext.cs +++ b/Core/Stateflows/Activities/Context/Classes/BaseContext.cs @@ -29,6 +29,8 @@ public IServiceProvider ServiceProvider public NodeScope NodeScope { get; } + public Event ExecutionTrigger { get; set; } + public CancellationToken CancellationToken => NodeScope.CancellationToken; private ActivityContext activity; diff --git a/Core/Stateflows/Activities/Context/Classes/RootContext.cs b/Core/Stateflows/Activities/Context/Classes/RootContext.cs index 2ba8acb6..28d087c0 100644 --- a/Core/Stateflows/Activities/Context/Classes/RootContext.cs +++ b/Core/Stateflows/Activities/Context/Classes/RootContext.cs @@ -240,6 +240,31 @@ public Dictionary NodeTimeEvents } } + private Dictionary nodeStartupEvents = null; + public Dictionary NodeStartupEvents + { + get + { + lock (Context.Values) + { + if (nodeStartupEvents == null) + { + if (!Context.Values.TryGetValue(Constants.NodeStartupEvents, out var nodesStartupEventsObj)) + { + nodeStartupEvents = new Dictionary(); + Context.Values[Constants.NodeStartupEvents] = nodeStartupEvents; + } + else + { + nodeStartupEvents = nodesStartupEventsObj as Dictionary; + } + } + } + + return nodeStartupEvents; + } + } + [JsonIgnore] internal LockedList NodesToExecute { get; set; } = new LockedList(); @@ -288,6 +313,12 @@ public bool Initialized set => Context.Values[Constants.Initialized] = value; } + public bool Finalized + { + get => Context.Values.TryGetValue(Constants.Finalized, out var consumed) && (bool)consumed; + set => Context.Values[Constants.Finalized] = value; + } + public bool ForceConsumed { get => Context.Values.TryGetValue(Constants.ForceConsumed, out var consumed) && (bool)consumed; @@ -310,7 +341,7 @@ public void ClearEvent() ? EventsStack.Peek() : null; - internal Exception Exception { get; set; } + public readonly List Exceptions = new List(); internal Node NodeOfOrigin { get; set; } @@ -318,7 +349,13 @@ internal bool IsNodeCompleted(Node node, NodeScope nodeScope) => nodeScope.IsTerminated || (nodeScope.ChildScope?.IsTerminated ?? false) || ( - !node.Nodes.Values.Any(node => node.Type == NodeType.AcceptEventAction && !node.IncomingEdges.Any()) && + !node.Nodes.Values.Any(node => + ( + node.Type == NodeType.AcceptEventAction || + node.Type == NodeType.TimeEventAction + ) && + !node.IncomingEdges.Any() + ) && !ActiveNodes.Any() ); diff --git a/Core/Stateflows/Activities/Context/ContextHolder.cs b/Core/Stateflows/Activities/Context/ContextHolder.cs new file mode 100644 index 00000000..1f448a31 --- /dev/null +++ b/Core/Stateflows/Activities/Context/ContextHolder.cs @@ -0,0 +1,14 @@ +using System.Threading; +using Stateflows.Activities.Context.Interfaces; + +namespace Stateflows.Activities.Context +{ + public static class ContextHolder + { + public static readonly AsyncLocal ActivityContext = new AsyncLocal(); + public static readonly AsyncLocal NodeContext = new AsyncLocal(); + public static readonly AsyncLocal FlowContext = new AsyncLocal(); + public static readonly AsyncLocal ExecutionContext = new AsyncLocal(); + public static readonly AsyncLocal ExceptionContext = new AsyncLocal(); + } +} diff --git a/Core/Stateflows/Activities/Context/Interfaces/IActivityActionContext.cs b/Core/Stateflows/Activities/Context/Interfaces/IActivityActionContext.cs index 161ab4d3..49f8b39f 100644 --- a/Core/Stateflows/Activities/Context/Interfaces/IActivityActionContext.cs +++ b/Core/Stateflows/Activities/Context/Interfaces/IActivityActionContext.cs @@ -2,7 +2,7 @@ namespace Stateflows.Activities.Context.Interfaces { - public interface IActivityActionContext : IBehaviorLocator + public interface IActivityActionContext : IBehaviorLocator, IExecutionContext { /// /// Information about activity diff --git a/Core/Stateflows/Activities/Context/Interfaces/IActivityInitializationContext.cs b/Core/Stateflows/Activities/Context/Interfaces/IActivityInitializationContext.cs index b9854d05..0f566dfb 100644 --- a/Core/Stateflows/Activities/Context/Interfaces/IActivityInitializationContext.cs +++ b/Core/Stateflows/Activities/Context/Interfaces/IActivityInitializationContext.cs @@ -3,11 +3,11 @@ namespace Stateflows.Activities.Context.Interfaces { public interface IActivityInitializationContext : IActivityActionContext - where TInitializationRequest : InitializationRequest + where TInitializationRequest : Event { - TInitializationRequest InitializationRequest { get; } + TInitializationRequest InitializationEvent { get; } } - public interface IActivityInitializationContext : IActivityInitializationContext + public interface IActivityInitializationContext : IActivityInitializationContext { } } diff --git a/Core/Stateflows/Activities/Context/Interfaces/IExceptionHandlerContext.cs b/Core/Stateflows/Activities/Context/Interfaces/IExceptionHandlerContext.cs index 0317d019..511b3cfc 100644 --- a/Core/Stateflows/Activities/Context/Interfaces/IExceptionHandlerContext.cs +++ b/Core/Stateflows/Activities/Context/Interfaces/IExceptionHandlerContext.cs @@ -2,13 +2,16 @@ namespace Stateflows.Activities.Context.Interfaces { - public interface IExceptionHandlerContext : IActivityNodeContext, IOutput - where TException : Exception + public interface IExceptionContext { - TException Exception { get; } - INodeContext ProtectedNode { get; } INodeContext NodeOfOrigin { get; } } + + public interface IExceptionHandlerContext : IExceptionContext, IActivityNodeContext, IOutput + where TException : Exception + { + TException Exception { get; } + } } diff --git a/Core/Stateflows/Activities/Context/Interfaces/IExecutionContext.cs b/Core/Stateflows/Activities/Context/Interfaces/IExecutionContext.cs new file mode 100644 index 00000000..02ea5e45 --- /dev/null +++ b/Core/Stateflows/Activities/Context/Interfaces/IExecutionContext.cs @@ -0,0 +1,10 @@ +using Stateflows.Common; + +namespace Stateflows.Activities.Context.Interfaces +{ + + public interface IExecutionContext + { + Event ExecutionTrigger { get; } + } +} diff --git a/Core/Stateflows/Activities/Engine/Executor.cs b/Core/Stateflows/Activities/Engine/Executor.cs index 99039f23..6fdf88de 100644 --- a/Core/Stateflows/Activities/Engine/Executor.cs +++ b/Core/Stateflows/Activities/Engine/Executor.cs @@ -13,12 +13,30 @@ using Stateflows.Activities.Streams; using Stateflows.Activities.Registration; using Stateflows.Activities.Context.Classes; +using System.Net; namespace Stateflows.Activities.Engine { internal class Executor : IDisposable { private static readonly object lockHandle = new object(); + private static readonly object nodesLockHandle = new object(); + private readonly Dictionary nodeLockHandles = new Dictionary(); + + private object GetLock(Node node) + { + object result = null; + lock (nodesLockHandle) + { + if (!nodeLockHandles.TryGetValue(node, out result)) + { + result = new object(); + nodeLockHandles[node] = result; + } + } + + return result; + } public readonly Graph Graph; public readonly ActivitiesRegister Register; @@ -34,6 +52,7 @@ internal class Executor : IDisposable NodeType.Merge, NodeType.SendEventAction, NodeType.AcceptEventAction, + NodeType.TimeEventAction, NodeType.StructuredActivity, NodeType.ParallelActivity, NodeType.IterativeActivity, @@ -48,6 +67,19 @@ internal class Executor : IDisposable NodeType.IterativeActivity }; + public static readonly NodeType[] SystemTypes = new NodeType[] + { + NodeType.Initial, + NodeType.Input, + NodeType.Output + }; + + public static readonly NodeType[] interactiveNodeTypes = new NodeType[] + { + NodeType.AcceptEventAction, + NodeType.TimeEventAction, + }; + public Executor(ActivitiesRegister register, Graph graph, IServiceProvider serviceProvider) { Register = register; @@ -65,7 +97,15 @@ public Inspector Inspector private EventWaitHandle FinalizationEvent { get; } = new EventWaitHandle(false, EventResetMode.AutoReset); - private bool Finalized { get; set; } = false; + private bool Finalized + { + get + { + Debug.Assert(Context != null, $"Context is unavailable. Is activity '{Graph.Name}' hydrated?"); + + return Context.Finalized; + } + } public IEnumerable GetActiveNodes() => Context.ActiveNodes.Keys @@ -89,7 +129,7 @@ public Task HydrateAsync(RootContext context) public async Task DehydrateAsync() { - Debug.Assert(Context != null, $"Context is unavailable. Is state machine '{Graph.Name}' already dehydrated?"); + Debug.Assert(Context != null, $"Context is unavailable. Is activity '{Graph.Name}' already dehydrated?"); await Inspector.BeforeDehydrateAsync(new ActivityActionContext(Context, NodeScope.CreateChildScope())); @@ -121,30 +161,53 @@ public bool Initialized } } - public async Task InitializeAsync(InitializationRequest @event) + public async Task InitializeAsync(Event @event) { Debug.Assert(Context != null, $"Context is unavailable. Is activity '{Graph.Name}' hydrated?"); - if (!Initialized && await DoInitializeActivityAsync(@event)) + if (!Initialized) { - Context.Initialized = true; + var result = await DoInitializeActivityAsync(@event); - await ExecuteGraphAsync(); + if ( + result == InitializationStatus.InitializedImplicitly || + result == InitializationStatus.InitializedExplicitly + ) + { + Context.Initialized = true; - return true; - } + await ExecuteGraphAsync(); - if (Initialized) - { - Logger.LogInformation("Behavior \"{id}\" is already initialized.", $"{Context.Id.BehaviorId.Type}:{Context.Id.Name}:{Context.Id.Instance}"); + if (result == InitializationStatus.InitializedExplicitly) + { + return EventStatus.Initialized; + } + else + { + if (@event is Initialize) + { + return EventStatus.Initialized; + } + else + { + return EventStatus.Consumed; + } + } + } + else + { + return result == InitializationStatus.NoSuitableInitializer + ? EventStatus.Rejected + : EventStatus.NotInitialized; + } } - return false; + return EventStatus.NotInitialized; } public async Task CancelAsync() { - Debug.Assert(Context != null, $"Context is unavailable. Is state machine '{Graph.Name}' hydrated?"); + Debug.Assert(Context != null, $"Context is unavailable. Is activity '{Graph.Name}' hydrated?"); if (Initialized) { @@ -155,6 +218,7 @@ public async Task CancelAsync() Context.GlobalValues.Clear(); Context.Streams.Clear(); Context.Context.PendingTimeEvents.Clear(); + Context.Context.PendingStartupEvents.Clear(); Context.Context.TriggerTime = null; await DoFinalizeAsync(); @@ -165,16 +229,22 @@ public async Task CancelAsync() return false; } - public void Reset(bool keepVersion) + public void Reset(ResetMode resetMode) { - Debug.Assert(Context != null, $"Context is unavailable. Is state machine '{Graph.Name}' hydrated?"); + Debug.Assert(Context != null, $"Context is unavailable. Is activity '{Graph.Name}' hydrated?"); if (Initialized) { Context.Context.Values.Clear(); - if (!keepVersion) + + if (resetMode != ResetMode.KeepVersionAndSubscriptions) // KeepSubscriptions || Full { Context.Context.Version = 0; + + if (resetMode != ResetMode.KeepSubscriptions) // Full + { + Context.Context.Deleted = true; + } } } } @@ -251,7 +321,7 @@ public async Task DoFinalizeAsync(IEnumerable outputTokens = null) { if (Finalized) return; - Finalized = true; + Context.Finalized = true; if (Graph.OutputNode != null && outputTokens != null) { @@ -439,7 +509,7 @@ private async Task DoExecuteStructureAsync(Node node, NodeScope nodeScope, } await Task.WhenAll( - nodes.Select(n => DoHandleNodeAsync(n, nodeScope, n == node.InputNode ? input : null, selectionTokens)).ToArray() + nodes.Select(n => DoHandleNodeAsync(n, null, nodeScope, n == node.InputNode ? input : null, selectionTokens)).ToArray() ); var result = Context.IsNodeCompleted(node, nodeScope); @@ -447,35 +517,48 @@ await Task.WhenAll( return result; } - public async Task DoInitializeActivityAsync(InitializationRequest @event) + public async Task DoInitializeActivityAsync(Event @event) { - var result = false; + InitializationStatus result; - if ( - Graph.Initializers.TryGetValue(@event.Name, out var initializer) || - ( - @event.Name == EventInfo.Name && - !Graph.Initializers.Any() - ) - ) - { - var context = new ActivityInitializationContext(Context, NodeScope, @event); - await Inspector.BeforeActivityInitializationAsync(context); + var initializer = Graph.Initializers.ContainsKey(@event.Name) + ? Graph.Initializers[@event.Name] + : Graph.DefaultInitializer; + + var context = new ActivityInitializationContext(Context, NodeScope, @event); + await Inspector.BeforeActivityInitializationAsync(context); + if (initializer != null) + { try { - result = (initializer == null) || await initializer.WhenAll(context); + result = await initializer.WhenAll(context) + ? initializer == Graph.DefaultInitializer + ? InitializationStatus.InitializedImplicitly + : InitializationStatus.InitializedExplicitly + : InitializationStatus.NotInitialized; } catch (Exception e) { await Inspector.OnActivityInitializationExceptionAsync(context, @event, e); - result = false; + result = InitializationStatus.NotInitialized; + } + } + else + { + if (Graph.Initializers.Any()) + { + result = InitializationStatus.NotInitialized; + } + else + { + result = InitializationStatus.InitializedImplicitly; } - - await Inspector.AfterActivityInitializationAsync(context); } + await Inspector.AfterActivityInitializationAsync(context, Initialized); + return result; } @@ -512,7 +595,7 @@ public async Task> HandleExceptionAsync(Node node, Exce if (handler != null) { var exceptionName = exception.GetType().Name; - Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}': handling '{exceptionName}'"); + Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}:{context.Activity.Id.Instance}': handling '{exceptionName}'"); var exceptionContext = new ActionContext( context.Context, @@ -521,7 +604,7 @@ public async Task> HandleExceptionAsync(Node node, Exce new TokenHolder[] { exception.ToExceptionHolder(exception.GetType()), - new NodeReference() { Node = node }.ToTokenHolder(), + new NodeReferenceToken() { Node = node }.ToTokenHolder(), } ); @@ -529,7 +612,7 @@ public async Task> HandleExceptionAsync(Node node, Exce DoHandleOutput(exceptionContext); - ReportExceptionHandled(node, exceptionName, exceptionContext.OutputTokens.Where(t => t is TokenHolder).ToArray()); + ReportExceptionHandled(node, exceptionName, exceptionContext.OutputTokens.Where(t => t is TokenHolder).ToArray(), Context); return exceptionContext.OutputTokens; } @@ -537,7 +620,7 @@ public async Task> HandleExceptionAsync(Node node, Exce return new TokenHolder[0]; } - public async Task DoHandleNodeAsync(Node node, NodeScope nodeScope, IEnumerable input = null, IEnumerable selectionTokens = null) + public async Task DoHandleNodeAsync(Node node, Edge upstreamEdge, NodeScope nodeScope, IEnumerable input = null, IEnumerable selectionTokens = null) { if (CancellableTypes.Contains(node.Type) && nodeScope.CancellationToken.IsCancellationRequested) { @@ -548,7 +631,7 @@ public async Task DoHandleNodeAsync(Node node, NodeScope nodeScope, IEnumerable< IEnumerable inputTokens = Array.Empty(); - lock (node) + lock (GetLock(node)) { var streams = !Context.NodesToExecute.Contains(node) ? Context.GetActivatedStreams(node, nodeScope.ThreadId) @@ -576,19 +659,22 @@ public async Task DoHandleNodeAsync(Node node, NodeScope nodeScope, IEnumerable< inputTokens = input ?? streams.SelectMany(stream => stream.Tokens).Distinct().ToArray(); - if (activated) + if (streams.Any()) { - foreach (var stream in streams) + if (activated) { - if (!stream.IsPersistent) + foreach (var stream in streams) { - Context.ClearStream(stream.EdgeIdentifier, nodeScope.ThreadId); + if (!stream.IsPersistent) + { + Context.ClearStream(stream.EdgeIdentifier, nodeScope.ThreadId); + } } } - } - else - { - ReportNodeAttemptedExecution(node, streams); + else + { + ReportNodeAttemptedExecution(node, upstreamEdge, streams, Context); + } } } @@ -601,7 +687,7 @@ public async Task DoHandleNodeAsync(Node node, NodeScope nodeScope, IEnumerable< if (activated) { if ( - node.Type == NodeType.AcceptEventAction && + interactiveNodeTypes.Contains(node.Type) && ( Context.Event == null || Context.Event.GetType() != node.EventType @@ -612,22 +698,20 @@ public async Task DoHandleNodeAsync(Node node, NodeScope nodeScope, IEnumerable< if (Debugger.IsAttached) { - Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}': AcceptEvent node '{node.Name}' registered and waiting for event"); + Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}:{Context.Id.Instance}': AcceptEvent node '{node.Name}' registered and waiting for event"); } return; } - ReportNodeExecuting(node, inputTokens); + ReportNodeExecuting(node, upstreamEdge, inputTokens, Context); await node.Action.WhenAll(actionContext); - if (node.Type == NodeType.AcceptEventAction) + if (interactiveNodeTypes.Contains(node.Type)) { var @event = Context.Event; - Context.ClearEvent(); - if (@event is TimeEvent) { Inspector.AcceptEventsPlugin.UnregisterAcceptEventNode(node); @@ -658,33 +742,38 @@ public async Task DoHandleNodeAsync(Node node, NodeScope nodeScope, IEnumerable< !actionContext.OutputTokens.Any() ) { - actionContext.OutputTokens.Add(new Control().ToTokenHolder()); + actionContext.OutputTokens.Add(new ControlToken().ToTokenHolder()); } - List outputTokens; + TokenHolder[] outputTokens; lock (actionContext.OutputTokens) { - outputTokens = actionContext.OutputTokens.ToList(); + outputTokens = actionContext.OutputTokens.ToArray(); } - ReportNodeExecuted(node, outputTokens.Where(t => t is TokenHolder).ToArray()); + ReportNodeExecuted(node, outputTokens.Where(t => t is TokenHolder).ToArray(), Context); - if (outputTokens.Any(t => t is TokenHolder)) + if (outputTokens.Any(t => t is TokenHolder)) { var tokenNames = outputTokens.Select(token => token.Name).Distinct().ToArray(); - var edges = node.Edges - .Where(edge => tokenNames.Contains(edge.TokenType.GetTokenName()) || edge.Weight == 0) - .OrderBy(edge => edge.IsElse) - .ToArray(); - foreach (var edge in edges) - { - _ = await DoHandleEdgeAsync(edge, actionContext); - } - - var nodes = edges.Select(edge => edge.Target).Distinct().ToArray(); + var nodes = ( + await Task.WhenAll( + node.Edges + .Where(edge => tokenNames.Contains(edge.TokenType.GetTokenName()) || edge.Weight == 0) + .OrderBy(edge => edge.IsElse) + .Select(async edge => ( + Edge: edge, + Activated: await DoHandleEdgeAsync(edge, actionContext)) + ) + ) + ) + .Where(x => x.Activated) + .Select(x => x.Edge) + .GroupBy(edge => edge.Target) + .ToArray(); - await Task.WhenAll(nodes.Select(n => DoHandleNodeAsync(n, nodeScope)).ToArray()); + await Task.WhenAll(nodes.Select(n => DoHandleNodeAsync(n.Key, n.First(), nodeScope)).ToArray()); } } } @@ -692,49 +781,57 @@ public async Task DoHandleNodeAsync(Node node, NodeScope nodeScope, IEnumerable< await Inspector.AfterNodeActivateAsync(null); } - private static void ReportNodeExecuting(Node node, IEnumerable inputTokens) + private static void ReportNodeExecuting(Node node, Edge upstreamEdge, IEnumerable inputTokens, RootContext context) { - if (Debugger.IsAttached) + if (Debugger.IsAttached && !SystemTypes.Contains(node.Type)) { lock (lockHandle) { - Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}': executing '{node.Name}'{(!inputTokens.Any() ? ", no input" : "")}"); - ReportTokens(inputTokens); + Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}:{context.Id.Instance}': executing '{node.Name}'{(!inputTokens.Any() ? ", no input" : "")}"); + if (upstreamEdge != null) + { + Trace.WriteLine($" Triggered by {((upstreamEdge.TokenType == typeof(ControlToken)) ? "control" : "'" + upstreamEdge.TokenType.GetTokenName() + "'")} flow from '{upstreamEdge.Source.Name}'"); + } + ReportTokens(inputTokens); } } } - private static void ReportNodeExecuted(Node node, IEnumerable outputTokens) + private static void ReportNodeExecuted(Node node, IEnumerable outputTokens, RootContext context) { - if (Debugger.IsAttached) + if (Debugger.IsAttached && !SystemTypes.Contains(node.Type)) { lock (lockHandle) { - Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}': executed '{node.Name}'{(!outputTokens.Any() ? ", no output" : "")}"); + Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}:{context.Id.Instance}': executed '{node.Name}'{(!outputTokens.Any() ? ", no output" : "")}"); ReportTokens(outputTokens, false); } } } - private static void ReportExceptionHandled(Node node, string exceptionName, IEnumerable outputTokens) + private static void ReportExceptionHandled(Node node, string exceptionName, IEnumerable outputTokens, RootContext context) { if (Debugger.IsAttached) { lock (lockHandle) { - Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}': '{exceptionName}' handled{(!outputTokens.Any() ? ", no output" : "")}"); + Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}:{context.Id.Instance}': '{exceptionName}' handled{(!outputTokens.Any() ? ", no output" : "")}"); ReportTokens(outputTokens, false); } } } - private static void ReportNodeAttemptedExecution(Node node, IEnumerable streams) + private static void ReportNodeAttemptedExecution(Node node, Edge upstreamEdge, IEnumerable streams, RootContext context) { - if (Debugger.IsAttached) + if (Debugger.IsAttached && !SystemTypes.Contains(node.Type)) { lock (lockHandle) { - Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}': omitting '{node.Name}'"); + Trace.WriteLine($"⦗→s⦘ Activity '{node.Graph.Name}:{context.Id.Instance}': omitting '{node.Name}'"); + if (upstreamEdge != null) + { + Trace.WriteLine($" Triggered by {((upstreamEdge.TokenType == typeof(ControlToken)) ? "control" : "'" + upstreamEdge.TokenType.GetTokenName() + "'")} flow from '{upstreamEdge.Source.Name}'"); + } ReportTokens(streams.SelectMany(stream => stream.Tokens).Distinct().ToArray()); var activatedFlows = streams.Select(s => s.EdgeIdentifier).ToArray(); var missingFlows = node.IncomingEdges.Where(e => !activatedFlows.Contains(e.Identifier)); @@ -746,6 +843,7 @@ private static void ReportNodeAttemptedExecution(Node node, IEnumerable private static void ReportTokens(IEnumerable inputTokens, bool input = true) { var inputDigest = inputTokens + .Where(t => t.Name != typeof(ControlToken).GetTokenName()) .GroupBy(t => t.Name) .Select(g => new { @@ -772,7 +870,7 @@ private static void ReportMissingFlows(IEnumerable flows) foreach (var flow in flows) { var tokenName = flow.TargetTokenType.GetTokenName(); - if (tokenName == typeof(Control).GetTokenName()) + if (tokenName == typeof(ControlToken).GetTokenName()) { Trace.WriteLine($" - control flow from '{flow.SourceName}' "); } @@ -821,9 +919,9 @@ private async Task DoHandleEdgeAsync(Edge edge, ActionContext context) { var stream = Context.GetStream(edge.Identifier, context.NodeScope.ThreadId); - if (edgeTokenName != typeof(Control).GetTokenName()) + if (edgeTokenName != typeof(ControlToken).GetTokenName()) { - processedTokens.Add(new Control().ToTokenHolder()); + processedTokens.Add(new ControlToken().ToTokenHolder()); } if (!edge.Source.Options.HasFlag(NodeOptions.ImplicitFork) && consumedTokens.Any()) @@ -856,17 +954,9 @@ protected virtual void Dispose(bool disposing) NodeScope.Dispose(); } - private readonly IDictionary Activities = new Dictionary(); - - public Activity GetActivity(Type activityType, RootContext context) + public IActivity GetActivity(Type activityType) { - if (!Activities.TryGetValue(activityType, out var activity)) - { - activity = NodeScope.ServiceProvider.GetService(activityType) as Activity; - activity.Context = new ActivityActionContext(context, NodeScope); - - Activities.Add(activityType, activity); - } + var activity = NodeScope.ServiceProvider.GetService(activityType) as IActivity; return activity; } diff --git a/Core/Stateflows/Activities/Engine/Inspector.cs b/Core/Stateflows/Activities/Engine/Inspector.cs index 30ca3c7c..350c494d 100644 --- a/Core/Stateflows/Activities/Engine/Inspector.cs +++ b/Core/Stateflows/Activities/Engine/Inspector.cs @@ -91,7 +91,7 @@ public async Task BeforeDehydrateAsync(ActivityActionContext context) await Plugins.RunSafe(p => p.BeforeDehydrateAsync(context), nameof(BeforeDehydrateAsync), Logger); } - public async Task BeforeProcessEventAsync(Context.Classes.EventContext context) + public async Task BeforeProcessEventAsync(EventContext context) where TEvent : Event, new() { var plugin = await Plugins.RunSafe(i => i.BeforeProcessEventAsync(context), nameof(BeforeProcessEventAsync), Logger); @@ -103,7 +103,7 @@ public async Task BeforeProcessEventAsync(Context.Classes.EventCon return global && local && plugin; } - public async Task AfterProcessEventAsync(Context.Classes.EventContext context) + public async Task AfterProcessEventAsync(EventContext context) where TEvent : Event, new() { await Interceptors.RunSafe(i => i.AfterProcessEventAsync(context), nameof(AfterProcessEventAsync), Logger); @@ -118,11 +118,11 @@ public async Task BeforeActivityInitializationAsync(ActivityInitializationContex await Observers.RunSafe(o => o.BeforeActivityInitializeAsync(context), nameof(BeforeActivityInitializationAsync), Logger); } - public async Task AfterActivityInitializationAsync(ActivityInitializationContext context) + public async Task AfterActivityInitializationAsync(ActivityInitializationContext context, bool initialized) { - await Observers.RunSafe(o => o.AfterActivityInitializeAsync(context), nameof(AfterActivityInitializationAsync), Logger); - await Inspectors.RunSafe(i => i.AfterActivityInitializeAsync(context), nameof(AfterActivityInitializationAsync), Logger); - await Plugins.RunSafe(p => p.AfterActivityInitializeAsync(context), nameof(AfterActivityInitializationAsync), Logger); + await Observers.RunSafe(o => o.AfterActivityInitializeAsync(context, initialized), nameof(AfterActivityInitializationAsync), Logger); + await Inspectors.RunSafe(i => i.AfterActivityInitializeAsync(context, initialized), nameof(AfterActivityInitializationAsync), Logger); + await Plugins.RunSafe(p => p.AfterActivityInitializeAsync(context, initialized), nameof(AfterActivityInitializationAsync), Logger); } public async Task BeforeActivityFinalizationAsync(ActivityActionContext context) @@ -195,47 +195,82 @@ public async Task AfterNodeActivateAsync(ActionContext context) await Plugins.RunSafe(p => p.AfterNodeActivateAsync(context), nameof(AfterNodeActivateAsync), Logger); } - public async Task OnActivityInitializationExceptionAsync(BaseContext context, InitializationRequest initializationRequest, Exception exception) + public async Task OnActivityInitializationExceptionAsync(BaseContext context, Event initializationEvent, Exception exception) { - var exceptionContext = new ActivityInitializationContext(context, initializationRequest); + var exceptionContext = new ActivityInitializationContext(context, initializationEvent); await ExceptionHandlers.RunSafe(h => h.OnActivityInitializationExceptionAsync(exceptionContext, exception), nameof(OnActivityInitializationExceptionAsync), Logger); await Inspectors.RunSafe(i => i.OnActivityInitializationExceptionAsync(exceptionContext, exception), nameof(OnActivityInitializationExceptionAsync), Logger); + + if (!ExceptionHandlers.Any()) + { + context.Context.Exceptions.Add(exception); + } } public async Task OnActivityFinalizationExceptionAsync(ActivityActionContext context, Exception exception) { await ExceptionHandlers.RunSafe(h => h.OnActivityFinalizationExceptionAsync(context, exception), nameof(OnActivityFinalizationExceptionAsync), Logger); await Inspectors.RunSafe(i => i.OnActivityFinalizationExceptionAsync(context, exception), nameof(OnActivityFinalizationExceptionAsync), Logger); + + if (!ExceptionHandlers.Any()) + { + context.Context.Exceptions.Add(exception); + } } - public async Task OnNodeInitializationExceptionAsync(IActivityNodeInspectionContext context, Exception exception) + public async Task OnNodeInitializationExceptionAsync(ActivityNodeContext context, Exception exception) { await ExceptionHandlers.RunSafe(h => h.OnNodeInitializationExceptionAsync(context, exception), nameof(OnNodeInitializationExceptionAsync), Logger); await Inspectors.RunSafe(i => i.OnNodeInitializationExceptionAsync(context, exception), nameof(OnNodeInitializationExceptionAsync), Logger); + + if (!ExceptionHandlers.Any()) + { + context.Context.Exceptions.Add(exception); + } } - public async Task OnNodeFinalizationExceptionAsync(IActivityNodeInspectionContext context, Exception exception) + public async Task OnNodeFinalizationExceptionAsync(ActivityNodeContext context, Exception exception) { await ExceptionHandlers.RunSafe(h => h.OnNodeFinalizationExceptionAsync(context, exception), nameof(OnNodeFinalizationExceptionAsync), Logger); await Inspectors.RunSafe(i => i.OnNodeFinalizationExceptionAsync(context, exception), nameof(OnNodeFinalizationExceptionAsync), Logger); + + if (!ExceptionHandlers.Any()) + { + context.Context.Exceptions.Add(exception); + } } - public async Task OnNodeExecutionExceptionAsync(IActivityNodeInspectionContext context, Exception exception) + public async Task OnNodeExecutionExceptionAsync(ActivityNodeContext context, Exception exception) { await ExceptionHandlers.RunSafe(h => h.OnNodeExecutionExceptionAsync(context, exception), nameof(OnNodeExecutionExceptionAsync), Logger); await Inspectors.RunSafe(i => i.OnNodeExecutionExceptionAsync(context, exception), nameof(OnNodeExecutionExceptionAsync), Logger); + + if (!ExceptionHandlers.Any()) + { + context.Context.Exceptions.Add(exception); + } } public async Task OnFlowGuardExceptionAsync(IGuardInspectionContext context, Exception exception) { await ExceptionHandlers.RunSafe(h => h.OnFlowGuardExceptionAsync(context, exception), nameof(OnFlowGuardExceptionAsync), Logger); await Inspectors.RunSafe(i => i.OnFlowGuardExceptionAsync(context, exception), nameof(OnFlowGuardExceptionAsync), Logger); + + //if (!ExceptionHandlers.Any()) + //{ + // context.Exceptions.Add(exception); + //} } public async Task OnFlowTransformationExceptionAsync(ITransformationInspectionContext context, Exception exception) { - await ExceptionHandlers.RunSafe(h => h.OnFlowTransformationExceptionAsync(context, exception), nameof(OnFlowGuardExceptionAsync), Logger); - await Inspectors.RunSafe(i => i.OnFlowTransformationExceptionAsync(context, exception), nameof(OnFlowGuardExceptionAsync), Logger); + await ExceptionHandlers.RunSafe(h => h.OnFlowTransformationExceptionAsync(context, exception), nameof(OnFlowTransformationExceptionAsync), Logger); + await Inspectors.RunSafe(i => i.OnFlowTransformationExceptionAsync(context, exception), nameof(OnFlowTransformationExceptionAsync), Logger); + + //if (!ExceptionHandlers.Any()) + //{ + // context.Exceptions.Add(exception); + //} } } } diff --git a/Core/Stateflows/Activities/Engine/NodeScope.cs b/Core/Stateflows/Activities/Engine/NodeScope.cs index afe15e8e..86b3f99e 100644 --- a/Core/Stateflows/Activities/Engine/NodeScope.cs +++ b/Core/Stateflows/Activities/Engine/NodeScope.cs @@ -4,6 +4,7 @@ using Stateflows.Common; using Stateflows.Common.Classes; using Stateflows.Activities.Models; +using Stateflows.Activities.Context; using Stateflows.Activities.Context.Interfaces; namespace Stateflows.Activities.Engine @@ -73,88 +74,141 @@ public NodeScope CreateChildScope(Node node = null, Guid? threadId = null) => ChildScope = new NodeScope(this, node ?? Node, threadId ?? ThreadId); public TAction GetAction(IActionContext context) - where TAction : ActionNode + where TAction : class, IActionNode { - ContextValuesHolder.GlobalValues.Value = context.Activity.Values; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = null; - ContextValuesHolder.TargetStateValues.Value = null; + ContextValues.GlobalValuesHolder.Value = context.Activity.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.NodeContext.Value = context.CurrentNode; + ContextHolder.FlowContext.Value = null; + ContextHolder.ActivityContext.Value = context.Activity; + ContextHolder.ExecutionContext.Value = context; + ContextHolder.ExceptionContext.Value = null; return ServiceProvider.GetService(); } public TAcceptEventAction GetAcceptEventAction(IAcceptEventActionContext context) where TEvent : Event, new() - where TAcceptEventAction : AcceptEventActionNode + where TAcceptEventAction : class, IAcceptEventActionNode { - ContextValuesHolder.GlobalValues.Value = context.Activity.Values; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = null; - ContextValuesHolder.TargetStateValues.Value = null; + ContextValues.GlobalValuesHolder.Value = context.Activity.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.NodeContext.Value = context.CurrentNode; + ContextHolder.FlowContext.Value = null; + ContextHolder.ActivityContext.Value = context.Activity; + ContextHolder.ExecutionContext.Value = context; + ContextHolder.ExceptionContext.Value = null; return ServiceProvider.GetService(); } + public TTimeEventAction GetTimeEventAction(IActionContext context) + where TTimeEventAction : class, ITimeEventActionNode + { + ContextValues.GlobalValuesHolder.Value = context.Activity.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.NodeContext.Value = context.CurrentNode; + ContextHolder.FlowContext.Value = null; + ContextHolder.ActivityContext.Value = context.Activity; + ContextHolder.ExecutionContext.Value = context; + ContextHolder.ExceptionContext.Value = null; + + return ServiceProvider.GetService(); + } + public TSendEventAction GetSendEventAction(IActionContext context) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode + where TSendEventAction : class, ISendEventActionNode { - ContextValuesHolder.GlobalValues.Value = context.Activity.Values; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = null; - ContextValuesHolder.TargetStateValues.Value = null; + ContextValues.GlobalValuesHolder.Value = context.Activity.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.NodeContext.Value = context.CurrentNode; + ContextHolder.FlowContext.Value = null; + ContextHolder.ActivityContext.Value = context.Activity; + ContextHolder.ExecutionContext.Value = context; + ContextHolder.ExceptionContext.Value = null; return ServiceProvider.GetService(); } public TStructuredActivity GetStructuredActivity(IActionContext context) - where TStructuredActivity : StructuredActivityNode + where TStructuredActivity : class, IBaseStructuredActivityNode { - ContextValuesHolder.GlobalValues.Value = context.Activity.Values; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = null; - ContextValuesHolder.TargetStateValues.Value = null; + ContextValues.GlobalValuesHolder.Value = context.Activity.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.NodeContext.Value = context.CurrentNode; + ContextHolder.FlowContext.Value = null; + ContextHolder.ActivityContext.Value = context.Activity; + ContextHolder.ExecutionContext.Value = context; + ContextHolder.ExceptionContext.Value = null; return ServiceProvider.GetService(); } public TExceptionHandler GetExceptionHandler(IExceptionHandlerContext context) where TException : Exception - where TExceptionHandler : ExceptionHandlerNode + where TExceptionHandler : class, IExceptionHandlerNode { - ContextValuesHolder.GlobalValues.Value = context.Activity.Values; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = null; - ContextValuesHolder.TargetStateValues.Value = null; + ContextValues.GlobalValuesHolder.Value = context.Activity.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.NodeContext.Value = context.CurrentNode; + ContextHolder.FlowContext.Value = null; + ContextHolder.ActivityContext.Value = context.Activity; + ContextHolder.ExecutionContext.Value = context; + ContextHolder.ExceptionContext.Value = context; return ServiceProvider.GetService(); } public TFlow GetFlow(IActivityFlowContext context) - where TFlow : BaseControlFlow + where TFlow : IBaseFlow { - ContextValuesHolder.GlobalValues.Value = context.Activity.Values; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = null; - ContextValuesHolder.TargetStateValues.Value = null; + ContextValues.GlobalValuesHolder.Value = context.Activity.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.NodeContext.Value = null; + ContextHolder.FlowContext.Value = context; + ContextHolder.ActivityContext.Value = context.Activity; + ContextHolder.ExecutionContext.Value = context; + ContextHolder.ExceptionContext.Value = null; return ServiceProvider.GetService(); } public TControlFlow GetControlFlow(IActivityFlowContext context) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow => GetFlow(context); public TFlow GetObjectFlow(IActivityFlowContext context) - where TFlow : Flow + where TFlow : class, IBaseFlow => GetFlow(context); public TTransformationFlow GetObjectTransformationFlow(IActivityFlowContext context) - where TTransformationFlow : TransformationFlow + where TTransformationFlow : class, IFlowTransformation => GetFlow(context); public TElseTransformationFlow GetElseObjectTransformationFlow(IActivityFlowContext context) - where TElseTransformationFlow : ElseTransformationFlow + where TElseTransformationFlow : class, IFlowTransformation => GetFlow(context); public void Dispose() diff --git a/Core/Stateflows/Activities/Engine/Plugins/AcceptEvents.cs b/Core/Stateflows/Activities/Engine/Plugins/AcceptEvents.cs index ebbe8b7e..b5680865 100644 --- a/Core/Stateflows/Activities/Engine/Plugins/AcceptEvents.cs +++ b/Core/Stateflows/Activities/Engine/Plugins/AcceptEvents.cs @@ -6,6 +6,7 @@ using Stateflows.Activities.Models; using Stateflows.Activities.Context.Classes; using Stateflows.Activities.Context.Interfaces; +using System.Diagnostics; namespace Stateflows.Activities.Engine { @@ -27,7 +28,6 @@ private void RegisterTimeEvent(Node node) Context.NodeTimeEvents[node.Identifier] = timeEvent.Id; } - private void ClearTimeEvent(Node node) { if (Context.NodeTimeEvents.TryGetValue(node.Identifier, out var timeEventId)) @@ -37,6 +37,28 @@ private void ClearTimeEvent(Node node) } } + private void RegisterStartupEvent(Node node) + { + if (Context.NodeStartupEvents.ContainsKey(node.Identifier)) + { + return; + } + + var startupEvent = Activator.CreateInstance(node.EventType) as Startup; + startupEvent.ConsumerSignature = node.Identifier; + Context.Context.PendingStartupEvents.Add(startupEvent.Id, startupEvent); + Context.NodeStartupEvents[node.Identifier] = startupEvent.Id; + } + + private void ClearStartupEvent(Node node) + { + if (Context.NodeStartupEvents.TryGetValue(node.Identifier, out var startupEventId)) + { + Context.Context.PendingStartupEvents.Remove(startupEventId); + Context.NodeStartupEvents.Remove(node.Identifier); + } + } + public void RegisterAcceptEventNodes(IEnumerable<(Node Node, Guid ThreadId)> nodes) { lock (Context) @@ -54,6 +76,11 @@ public void RegisterAcceptEventNodes(IEnumerable<(Node Node, Guid ThreadId)> nod { RegisterTimeEvent(node); } + + if (node.EventType == typeof(Startup)) + { + RegisterStartupEvent(node); + } } } } @@ -73,6 +100,11 @@ public void RegisterAcceptEventNode(Node node, Guid threadId) { RegisterTimeEvent(node); } + + if (node.EventType == typeof(Startup)) + { + RegisterStartupEvent(node); + } } } @@ -85,6 +117,8 @@ public void UnregisterAcceptEventNodes(IEnumerable nodes) Context.ActiveNodes.Remove(node.Identifier); ClearTimeEvent(node); + + ClearStartupEvent(node); } } } @@ -96,10 +130,12 @@ public void UnregisterAcceptEventNode(Node node) Context.ActiveNodes.Remove(node.Identifier); ClearTimeEvent(node); + + ClearStartupEvent(node); } } - Task IActivityObserver.AfterActivityInitializeAsync(IActivityInitializationContext context) + Task IActivityObserver.AfterActivityInitializeAsync(IActivityInitializationContext context, bool initialized) => Task.CompletedTask; Task IActivityObserver.AfterActivityFinalizeAsync(IActivityFinalizationContext context) @@ -121,6 +157,8 @@ Task IActivityObserver.AfterNodeInitializeAsync(IActivityNodeContext context) Task IActivityInterceptor.AfterProcessEventAsync(IEventContext context) { + Trace.WriteLine($"⦗→s⦘ Activity '{context.Activity.Id.Name}:{context.Activity.Id.Instance}': processed event '{context.Event.Name}'"); + Context = (context as BaseContext).Context; if (Context.Context.PendingTimeEvents.Any()) @@ -135,6 +173,8 @@ Task IActivityInterceptor.AfterProcessEventAsync(IEventContext context) Context.Context.TriggerTime = null; } + Context.Context.TriggerOnStartup = Context.Context.PendingStartupEvents.Any(); + return Task.CompletedTask; } @@ -170,6 +210,16 @@ Task IActivityInterceptor.BeforeProcessEventAsync(IEventContext con result = Context.Context.PendingTimeEvents.ContainsKey(timeEvent.Id); } + if (context.Event is Startup startupEvent) + { + result = Context.Context.PendingStartupEvents.ContainsKey(startupEvent.Id); + } + + if (result) + { + Trace.WriteLine($"⦗→s⦘ Activity '{context.Activity.Id.Name}:{context.Activity.Id.Instance}': received event '{context.Event.Name}', trying to process it"); + } + return Task.FromResult(result); } } diff --git a/Core/Stateflows/Activities/Engine/Plugins/Tracer.cs b/Core/Stateflows/Activities/Engine/Plugins/Tracer.cs deleted file mode 100644 index 40ea65d4..00000000 --- a/Core/Stateflows/Activities/Engine/Plugins/Tracer.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using System.Threading; -using System.Reflection; -using System.Diagnostics; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Stateflows.Common; -using Stateflows.Common.Interfaces; -using Stateflows.Common.Trace.Models; -using Stateflows.Activities.Context.Interfaces; - -namespace Stateflows.Activities.Engine -{ - internal class Tracer : IActivityPlugin - { - private readonly IServiceProvider ServiceProvider; - - private BehaviorTrace Trace { get; set; } = new BehaviorTrace(); - - private AsyncLocal ExceptionHolder { get; set; } = new AsyncLocal(); - - private Exception Exception - { - get => ExceptionHolder.Value; - set => ExceptionHolder.Value = value; - } - - private AsyncLocal StopwatchHolder { get; set; } = new AsyncLocal(); - - private Stopwatch Stopwatch => StopwatchHolder.Value ?? (StopwatchHolder.Value = new Stopwatch()); - - private Stopwatch OverallStopwatch { get; set; } = new Stopwatch(); - - public Tracer(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider.CreateScope().ServiceProvider; - } - - private Task StartMeasureAsync() - { - if (Trace.Event != null) - { - Exception = null; - - Stopwatch.Reset(); - } - - return Task.CompletedTask; - } - - private Task StopMeasureAsync(string actionName, string elementName) - { - if (Trace.Event != null) - { - Stopwatch.Stop(); - - Trace - .AddStep(actionName, elementName, Stopwatch.Elapsed) - .Exceptions - .Add(Exception); - } - - return Task.CompletedTask; - } - - private Task SetExceptionAsync(Exception exception) - { - Exception = exception; - return Task.CompletedTask; - } - - public Task BeforeActivityInitializeAsync(IActivityInitializationContext context) - => StartMeasureAsync(); - - public Task AfterActivityInitializeAsync(IActivityInitializationContext context) - => StopMeasureAsync("ActivityInitialization", context.Activity.Id.Name); - - public Task BeforeActivityFinalizeAsync(IActivityFinalizationContext context) - => StartMeasureAsync(); - - public Task AfterActivityFinalizeAsync(IActivityFinalizationContext context) - => StopMeasureAsync("ActivityFinalization", context.Activity.Id.Name); - - public Task BeforeNodeInitializeAsync(IActivityNodeContext context) - => StartMeasureAsync(); - - public Task AfterNodeInitializeAsync(IActivityNodeContext context) - => StopMeasureAsync("NodeInitialization", context.CurrentNode.NodeName); - - public Task BeforeNodeFinalizeAsync(IActivityNodeContext context) - => StartMeasureAsync(); - - public Task AfterNodeFinalizeAsync(IActivityNodeContext context) - => StopMeasureAsync("NodeFinalization", context.CurrentNode.NodeName); - - public Task BeforeNodeExecuteAsync(IActivityNodeContext context) - => StartMeasureAsync(); - - public Task AfterNodeExecuteAsync(IActivityNodeContext context) - { - if (Trace.Event != null) - { - Stopwatch.Stop(); - - Trace - .AddStep( - "Execute", - context.CurrentNode.NodeName, - Stopwatch.Elapsed - //(context as IActionContext)?.Input ?? Array.Empty() - ) - .Exceptions - .Add(Exception); - } - - return Task.CompletedTask; - } - - public Task BeforeFlowGuardAsync(IGuardContext context) - => StartMeasureAsync(); - - public Task AfterFlowGuardAsync(IGuardContext context, bool guardResult) - => StopMeasureAsync("Guard", $"{context.SourceNode.NodeName}-{context.Token.GetType().GetTokenName()}->{context.TargetNode.NodeName}"); - - public Task BeforeFlowTransformAsync(ITransformationContext context) - => StartMeasureAsync(); - - public Task AfterFlowTransformAsync(ITransformationContext context) - => StopMeasureAsync("Transformation", $"{context.SourceNode.NodeName}-{context.Token.GetType().GetTokenName()}->{context.TargetNode.NodeName}"); - - public Task OnActivityInitializationExceptionAsync(IActivityInitializationContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnActivityFinalizationExceptionAsync(IActivityFinalizationContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnNodeInitializationExceptionAsync(IActivityNodeContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnNodeFinalizationExceptionAsync(IActivityNodeContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnNodeExecutionExceptionAsync(IActivityNodeContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnFlowGuardExceptionAsync(IGuardContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnFlowTransformationExceptionAsync(ITransformationContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task BeforeProcessEventAsync(IEventContext context) - { - var eventType = context.Event.GetType(); - var attribute = eventType.GetCustomAttribute(); - if (attribute == null) - { - Trace.Event = context.Event; - OverallStopwatch.Start(); - } - - return Task.FromResult(true); - } - - public Task AfterProcessEventAsync(IEventContext context) - { - if (Trace.Event != null) - { - OverallStopwatch.Stop(); - Trace.ExecutedAt = DateTime.Now; - Trace.Duration = OverallStopwatch.Elapsed; - Trace.Context = ((IStateflowsContextProvider)context).Context; - Trace.BehaviorId = Trace.Context.Id; - _ = Task.Run(() => ServiceProvider.GetRequiredService().SaveTraceAsync(Trace)); - } - - return Task.CompletedTask; - } - } -} diff --git a/Core/Stateflows/Activities/Engine/Processor.cs b/Core/Stateflows/Activities/Engine/Processor.cs index a7261ed4..9b747c48 100644 --- a/Core/Stateflows/Activities/Engine/Processor.cs +++ b/Core/Stateflows/Activities/Engine/Processor.cs @@ -2,16 +2,18 @@ using System.Linq; using System.Threading.Tasks; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Microsoft.Extensions.DependencyInjection; using Stateflows.Common; +using Stateflows.Common.Context; using Stateflows.Common.Interfaces; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Models; using Stateflows.Activities.Registration; using Stateflows.Activities.Context.Classes; -using Microsoft.Extensions.DependencyInjection; -using Stateflows.Common.Context; -using Stateflows.Activities.Models; -using Stateflows.Common.Extensions; -using System.ComponentModel.DataAnnotations; -using Stateflows.Common.Initializer; +using Stateflows.Activities.EventHandlers; +using Stateflows.Activities.Events; +using System.Reflection; namespace Stateflows.Activities.Engine { @@ -44,7 +46,7 @@ private Task TryHandleEventAsync(EventContext conte : Task.FromResult(EventStatus.NotConsumed); } - public async Task ProcessEventAsync(BehaviorId id, TEvent @event, IServiceProvider serviceProvider) + public async Task ProcessEventAsync(BehaviorId id, TEvent @event, IServiceProvider serviceProvider, List exceptions) where TEvent : Event, new() { var result = EventStatus.Undelivered; @@ -81,23 +83,29 @@ public async Task ProcessEventAsync(BehaviorId id, TEvent @ results.Add(new RequestResult(ev, ev.GetResponse(), status, new EventValidation(true, new List()))); } - compoundRequest.Respond(new CompoundResponse() + if (compoundRequest.Response == null) { - Results = results - }); + compoundRequest.Respond(new CompoundResponse() + { + Results = results + }); + } } else { result = await ExecuteBehaviorAsync(@event, result, stateflowsContext, graph, executor, context); } + exceptions.AddRange(context.Exceptions); + await storage.DehydrateAsync((await executor.DehydrateAsync()).Context); } return result; } - private async Task ExecuteBehaviorAsync(TEvent @event, EventStatus result, StateflowsContext stateflowsContext, Graph graph, Executor executor, RootContext context) where TEvent : Event, new() + private async Task ExecuteBehaviorAsync(TEvent @event, EventStatus result, StateflowsContext stateflowsContext, Graph graph, Executor executor, RootContext context) + where TEvent : Event, new() { context.SetEvent(@event); @@ -105,26 +113,56 @@ public async Task ProcessEventAsync(BehaviorId id, TEvent @ if (await executor.Inspector.BeforeProcessEventAsync(eventContext)) { - if (!executor.Initialized) - { - var token = BehaviorClassesInitializations.Instance.AutoInitializationTokens.Find(token => token.BehaviorClass == executor.Context.Id.ActivityClass); + Event currentEvent = @event; - InitializationRequest initializationRequest; - if (token != null && (initializationRequest = await token.InitializationRequestFactory.Invoke(executor.NodeScope.ServiceProvider, executor.Context.Id)) != null) + if (@event is ExecutionRequest executionRequest) + { + if (executor.Graph.Interactive || executor.BehaviorStatus != BehaviorStatus.NotInitialized) { - context.SetEvent(initializationRequest); + return EventStatus.NotConsumed; + } - await executor.InitializeAsync(initializationRequest); + context.SetEvent(executionRequest.InitializationEvent); + + currentEvent = executionRequest.InitializationEvent; + } + + var attributes = currentEvent.GetType().GetCustomAttributes(); + if (!executor.Initialized && !attributes.Any()) + { + result = await executor.InitializeAsync(currentEvent); + } - context.ClearEvent(); + if (result != EventStatus.Initialized) + { + var handlingResult = await TryHandleEventAsync(eventContext); + + if (executor.Initialized) + { + if (handlingResult != EventStatus.Consumed && handlingResult != EventStatus.NotInitialized) + { + result = await executor.ProcessAsync(currentEvent); + } + else + { + result = handlingResult; + } + } + else + { + result = result == EventStatus.NotInitialized + ? EventStatus.NotInitialized + : attributes.Any() + ? handlingResult + : EventStatus.Rejected; } } - result = await TryHandleEventAsync(eventContext); - - if (result != EventStatus.Consumed) + if (@event is ExecutionRequest executionRequest2) { - result = await executor.ProcessAsync(@event); + context.ClearEvent(); + + executionRequest2.Respond(new ExecutionResponse() { OutputTokens = await executor.GetResultAsync() }); } await executor.Inspector.AfterProcessEventAsync(eventContext); diff --git a/Core/Stateflows/Activities/EventHandlers/ExecutionHandler.cs b/Core/Stateflows/Activities/EventHandlers/ExecutionHandler.cs index b382238e..ba664930 100644 --- a/Core/Stateflows/Activities/EventHandlers/ExecutionHandler.cs +++ b/Core/Stateflows/Activities/EventHandlers/ExecutionHandler.cs @@ -18,13 +18,18 @@ public async Task TryHandleEventAsync(IEventInspectionConte { var executor = context.Activity.GetExecutor(); - var initialized = await executor.InitializeAsync(executionRequest.InitializationRequest ?? new InitializationRequest()); + if (executor.Graph.Interactive || executor.BehaviorStatus != BehaviorStatus.NotInitialized) + { + return EventStatus.NotConsumed; + } + + var status = await executor.InitializeAsync(executionRequest.InitializationEvent ?? new Initialize()); executionRequest.Respond( new ExecutionResponse() { - ExecutionSuccessful = initialized, - OutputTokens = initialized + //ExecutionStatus = status, + OutputTokens = status == EventStatus.Initialized ? await executor.GetResultAsync() : null } diff --git a/Core/Stateflows/Activities/EventHandlers/InitializationHandler.cs b/Core/Stateflows/Activities/EventHandlers/InitializationHandler.cs deleted file mode 100644 index a5ddfd13..00000000 --- a/Core/Stateflows/Activities/EventHandlers/InitializationHandler.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Threading.Tasks; -using Stateflows.Common; -using Stateflows.Activities.Extensions; -using Stateflows.Activities.Inspection.Interfaces; - -namespace Stateflows.Activities.EventHandlers -{ - internal class InitializationHandler : IActivityEventHandler - { - public Type EventType => typeof(InitializationRequest); - - public async Task TryHandleEventAsync(IEventInspectionContext context) - where TEvent : Event, new() - { - if (context.Event is InitializationRequest request) - { - var executor = context.Activity.GetExecutor(); - - var initialized = await executor.InitializeAsync(request); - - request.Respond(new InitializationResponse() { InitializationSuccessful = initialized }); - - return EventStatus.Consumed; - } - - return EventStatus.NotConsumed; - } - } -} diff --git a/Core/Stateflows/Activities/EventHandlers/InitializeHandler.cs b/Core/Stateflows/Activities/EventHandlers/InitializeHandler.cs new file mode 100644 index 00000000..118a92b5 --- /dev/null +++ b/Core/Stateflows/Activities/EventHandlers/InitializeHandler.cs @@ -0,0 +1,20 @@ +using System; +using System.Threading.Tasks; +using Stateflows.Common; +using Stateflows.Activities.Inspection.Interfaces; + +namespace Stateflows.Activities.EventHandlers +{ + internal class InitializeHandler : IActivityEventHandler + { + public Type EventType => typeof(Initialize); + + public Task TryHandleEventAsync(IEventInspectionContext context) + where TEvent : Event, new() + => Task.FromResult( + context.Event is Initialize + ? EventStatus.NotInitialized + : EventStatus.NotConsumed + ); + } +} diff --git a/Core/Stateflows/Activities/EventHandlers/ResetHandler.cs b/Core/Stateflows/Activities/EventHandlers/ResetHandler.cs index 93811546..31201871 100644 --- a/Core/Stateflows/Activities/EventHandlers/ResetHandler.cs +++ b/Core/Stateflows/Activities/EventHandlers/ResetHandler.cs @@ -15,7 +15,7 @@ public Task TryHandleEventAsync(IEventInspectionContext - { - var context = (c as IRootContext).Context; - return context.Executor.GetActivity(activityType, context)?.OnInitializeAsync(); - }); - } - - if (typeof(Activity).GetMethod(nameof(Activity.OnFinalizeAsync)).IsOverridenIn(activityType)) - { - builder.AddOnFinalize(c => - { - var context = (c as IRootContext).Context; - return context.Executor.GetActivity(activityType, context)?.OnFinalizeAsync(); - }); - } - - var baseInterfaceType = typeof(IInitializedBy<>); - foreach (var interfaceType in activityType.GetInterfaces()) - { - if (interfaceType.GetGenericTypeDefinition() == baseInterfaceType) - { - var methodInfo = interfaceType.GetMethods().First(m => m.Name == "OnInitializeAsync"); - var requestType = interfaceType.GenericTypeArguments[0]; - var requestName = requestType.GetEventName(); - (builder as ActivityBuilder).AddInitializer(requestType, requestName, c => - { - var activity = c.Context.Executor.GetActivity(activityType, c.Context); - return methodInfo.Invoke(activity, new object[] { c.Context.Event is ExecutionRequest executionRequest ? executionRequest.InitializationRequest : c.Context.Event }) as Task; - }); - } - } - } - public static void AddStructuredActivityEvents(this StructuredActivityBuilder builder) - where TStructuredActivity : StructuredActivityNode + where TStructuredActivity : class, IBaseStructuredActivityNode { - if (typeof(StructuredActivityNode).GetMethod(nameof(StructuredActivityNode.OnInitializeAsync)).IsOverridenIn()) + if (typeof(IStructuredActivityNodeInitialization).IsAssignableFrom(typeof(TStructuredActivity))) { builder.AddOnInitialize(async c => { @@ -63,13 +21,13 @@ public static void AddStructuredActivityEvents(this Structu if (node != null) { ActivityNodeContextAccessor.Context.Value = c; - await node?.OnInitializeAsync(); + await (node as IStructuredActivityNodeInitialization)?.OnInitializeAsync(); ActivityNodeContextAccessor.Context.Value = null; } }); } - if (typeof(StructuredActivityNode).GetMethod(nameof(StructuredActivityNode.OnFinalizeAsync)).IsOverridenIn()) + if (typeof(IStructuredActivityNodeFinalization).IsAssignableFrom(typeof(TStructuredActivity))) { builder.AddOnFinalize(async c => { @@ -78,50 +36,33 @@ public static void AddStructuredActivityEvents(this Structu if (node != null) { ActivityNodeContextAccessor.Context.Value = c; - await node?.OnFinalizeAsync(); + await (node as IStructuredActivityNodeFinalization)?.OnFinalizeAsync(); ActivityNodeContextAccessor.Context.Value = null; } }); } } - public static void AddTransformationFlowEvents(this IObjectFlowBuilder builder) - where TTransformationFlow : TransformationFlow + public static void AddObjectFlowEvents(this IObjectFlowBuilder builder) + where TFlow : class, IBaseFlow { - if (typeof(BaseTransformationFlow).GetProperty(nameof(BaseTransformationFlow.Weight)).IsOverridenIn()) + if (typeof(IBaseFlow).GetProperty(nameof(IBaseFlow.Weight)).IsImplementedIn()) { - var objectFlow = FormatterServices.GetUninitializedObject(typeof(TTransformationFlow)) as TTransformationFlow; + var objectFlow = FormatterServices.GetUninitializedObject(typeof(TFlow)) as TFlow; builder.SetWeight(objectFlow.Weight); } - if (typeof(BaseControlFlow).GetMethod(nameof(BaseControlFlow.GuardAsync)).IsOverridenIn()) + if (typeof(IFlowGuard).IsAssignableFrom(typeof(TFlow))) { builder.AddGuard(async c => { var result = false; - var flow = (c as BaseContext).NodeScope.GetObjectTransformationFlow(c); + var flow = (c as BaseContext).NodeScope.GetFlow(c); if (flow != null) { ActivityFlowContextAccessor.Context.Value = c; - result = await flow?.GuardAsync(); - ActivityFlowContextAccessor.Context.Value = null; - } - - return result; - }); - } - - if (typeof(BaseTransformationFlow).GetMethod(nameof(BaseTransformationFlow.TransformAsync)).IsOverridenIn()) - { - builder.AddTransformation(async c => - { - TTransformedToken result = default; - var flow = (c as BaseContext).NodeScope.GetObjectTransformationFlow(c); - if (flow != null) - { - ActivityFlowContextAccessor.Context.Value = c; - result = await flow?.TransformAsync(); + result = await (flow as IFlowGuard)?.GuardAsync(c.Token); ActivityFlowContextAccessor.Context.Value = null; } @@ -130,26 +71,26 @@ public static void AddTransformationFlowEvents(this IObjectFlowBuilder builder) - where TElseTransformationFlow : ElseTransformationFlow + public static void AddObjectTransformationFlowEvents(this IObjectFlowBuilder builder) + where TTransformationFlow : class, IFlowTransformation { - if (typeof(BaseTransformationFlow).GetProperty(nameof(BaseTransformationFlow.Weight)).IsOverridenIn()) + if (typeof(IBaseFlow).GetProperty(nameof(IBaseFlow.Weight)).IsImplementedIn()) { - var objectFlow = FormatterServices.GetUninitializedObject(typeof(TElseTransformationFlow)) as TElseTransformationFlow; + var objectFlow = FormatterServices.GetUninitializedObject(typeof(TTransformationFlow)) as TTransformationFlow; builder.SetWeight(objectFlow.Weight); } - if (typeof(BaseControlFlow).GetMethod(nameof(BaseControlFlow.GuardAsync)).IsOverridenIn()) + if (typeof(IFlowGuard).IsAssignableFrom(typeof(TTransformationFlow))) { builder.AddGuard(async c => { var result = false; - var flow = (c as BaseContext).NodeScope.GetElseObjectTransformationFlow(c); + var flow = (c as BaseContext).NodeScope.GetObjectTransformationFlow(c); if (flow != null) { ActivityFlowContextAccessor.Context.Value = c; - result = await flow?.GuardAsync(); + result = await (flow as IFlowGuard)?.GuardAsync(c.Token); ActivityFlowContextAccessor.Context.Value = null; } @@ -157,16 +98,16 @@ public static void AddElseTransformationFlowEvents).GetMethod(nameof(BaseTransformationFlow.TransformAsync)).IsOverridenIn()) + if (typeof(IFlowTransformation).IsAssignableFrom(typeof(TTransformationFlow))) { builder.AddTransformation(async c => { TTransformedToken result = default; - var flow = (c as BaseContext).NodeScope.GetElseObjectTransformationFlow(c); + var flow = (c as BaseContext).NodeScope.GetObjectTransformationFlow(c); if (flow != null) { ActivityFlowContextAccessor.Context.Value = c; - result = await flow?.TransformAsync(); + result = await (flow as IFlowTransformation)?.TransformAsync(c.Token); ActivityFlowContextAccessor.Context.Value = null; } @@ -175,26 +116,26 @@ public static void AddElseTransformationFlowEvents(this IObjectFlowBuilder builder) - where TFlow : Flow + public static void AddElseObjectTransformationFlowEvents(this IObjectFlowBuilder builder) + where TTransformationFlow : class, IFlowTransformation { - if (typeof(BaseFlow).GetProperty(nameof(BaseFlow.Weight)).IsOverridenIn()) + if (typeof(IBaseFlow).GetProperty(nameof(IBaseFlow.Weight)).IsImplementedIn()) { - var objectFlow = FormatterServices.GetUninitializedObject(typeof(TFlow)) as TFlow; + var objectFlow = FormatterServices.GetUninitializedObject(typeof(TTransformationFlow)) as TTransformationFlow; builder.SetWeight(objectFlow.Weight); } - if (typeof(BaseControlFlow).GetMethod(nameof(BaseControlFlow.GuardAsync)).IsOverridenIn()) + if (typeof(IFlowTransformation).IsAssignableFrom(typeof(TTransformationFlow))) { - builder.AddGuard(async c => + builder.AddTransformation(async c => { - var result = false; - var flow = (c as BaseContext).NodeScope.GetObjectFlow(c); + TTransformedToken result = default; + var flow = (c as BaseContext).NodeScope.GetObjectTransformationFlow(c); if (flow != null) { ActivityFlowContextAccessor.Context.Value = c; - result = await flow?.GuardAsync(); + result = await (flow as IFlowTransformation)?.TransformAsync(c.Token); ActivityFlowContextAccessor.Context.Value = null; } @@ -203,19 +144,26 @@ public static void AddObjectFlowEvents(this IObjectFlowBuilder(this IControlFlowBuilder builder) - where TControlFlow : ControlFlow + public static void AddControlFlowEvents(this IControlFlowBuilder builder) + where TFlow : class, IBaseControlFlow { - if (typeof(BaseControlFlow).GetMethod(nameof(BaseControlFlow.GuardAsync)).IsOverridenIn()) + if (typeof(IBaseFlow).GetProperty(nameof(IBaseFlow.Weight)).IsImplementedIn()) + { + var objectFlow = FormatterServices.GetUninitializedObject(typeof(TFlow)) as TFlow; + + builder.SetWeight(objectFlow.Weight); + } + + if (typeof(IControlFlowGuard).IsAssignableFrom(typeof(TFlow))) { builder.AddGuard(async c => { var result = false; - var flow = (c as BaseContext).NodeScope.GetControlFlow(c); + var flow = (c as BaseContext).NodeScope.GetFlow(c); if (flow != null) { ActivityFlowContextAccessor.Context.Value = c; - result = await flow?.GuardAsync(); + result = await (flow as IControlFlowGuard)?.GuardAsync(); ActivityFlowContextAccessor.Context.Value = null; } diff --git a/Core/Stateflows/Activities/Extensions/IServiceCollectionExtensions.cs b/Core/Stateflows/Activities/Extensions/IServiceCollectionExtensions.cs deleted file mode 100644 index d15f38e0..00000000 --- a/Core/Stateflows/Activities/Extensions/IServiceCollectionExtensions.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using Stateflows.Common.Extensions; - -namespace Stateflows.Activities.Extensions -{ - internal static class IServiceCollectionExtensions - { - //public static IServiceCollection RegisterActivity(this IServiceCollection services) - // where TActivity : Activity - // => services?.AddServiceType(); - - public static IServiceCollection RegisterActivity(this IServiceCollection services, Type activityType) - => services?.AddServiceType(activityType); - - public static IServiceCollection RegisterAction(this IServiceCollection services) - where TAction : ActivityNode - => services?.AddServiceType(); - - public static IServiceCollection RegisterStructuredActivity(this IServiceCollection services) - where TStructuredActivity : StructuredActivityNode - => services?.AddServiceType(); - - public static IServiceCollection RegisterExceptionHandlerAction(this IServiceCollection services) - where TException : Exception - where TExceptionHandler : ExceptionHandlerNode - => services?.AddServiceType(); - - public static IServiceCollection RegisterObjectFlow(this IServiceCollection services) - where TFlow : Flow - => services?.AddServiceType(); - - //public static IServiceCollection RegisterElseObjectFlow(this IServiceCollection services) - // where TFlow : ElseFlow - // => services?.AddServiceType(); - - public static IServiceCollection RegisterTransformationFlow(this IServiceCollection services) - where TObjectTransformationFlow : TransformationFlow - => services?.AddServiceType(); - - public static IServiceCollection RegisterElseTransformationFlow(this IServiceCollection services) - where TObjectTransformationFlow : ElseTransformationFlow - => services?.AddServiceType(); - - public static IServiceCollection RegisterControlFlow(this IServiceCollection services) - where TControlFlow : ControlFlow - => services?.AddServiceType(); - - //public static IServiceCollection RegisterElseControlFlow(this IServiceCollection services) - // where TControlFlow : ElseControlFlow - // => services?.AddServiceType(); - - public static IServiceCollection RegisterObserver(this IServiceCollection services) - where TObserver : class, IActivityObserver - => services?.AddServiceType(); - - public static IServiceCollection RegisterInterceptor(this IServiceCollection services) - where TInterceptor : class, IActivityInterceptor - => services?.AddServiceType(); - - public static IServiceCollection RegisterExceptionHandler(this IServiceCollection services) - where TExceptionHandler : class, IActivityExceptionHandler - => services?.AddServiceType(); - } -} diff --git a/Core/Stateflows/Activities/Inspection/Classes/FlowInspection.cs b/Core/Stateflows/Activities/Inspection/Classes/FlowInspection.cs index f0a722b7..2931de20 100644 --- a/Core/Stateflows/Activities/Inspection/Classes/FlowInspection.cs +++ b/Core/Stateflows/Activities/Inspection/Classes/FlowInspection.cs @@ -59,7 +59,7 @@ public INodeInspection Target public string TokenName => Edge.TokenType.GetTokenName(); - public FlowType Type => Edge.TokenType == typeof(Control) + public FlowType Type => Edge.TokenType == typeof(ControlToken) ? FlowType.ControlFlow : FlowType.ObjectFlow; } diff --git a/Core/Stateflows/Activities/Inspection/Interfaces/IGuardInspectionContext.cs b/Core/Stateflows/Activities/Inspection/Interfaces/IGuardInspectionContext.cs index 3c799748..ce399ec9 100644 --- a/Core/Stateflows/Activities/Inspection/Interfaces/IGuardInspectionContext.cs +++ b/Core/Stateflows/Activities/Inspection/Interfaces/IGuardInspectionContext.cs @@ -1,5 +1,4 @@ using Stateflows.Activities.Context.Interfaces; -using Stateflows.Common; namespace Stateflows.Activities.Inspection.Interfaces { diff --git a/Core/Stateflows/Activities/Inspection/Interfaces/ITransformationInspectionContext.cs b/Core/Stateflows/Activities/Inspection/Interfaces/ITransformationInspectionContext.cs index e26514bd..0484491b 100644 --- a/Core/Stateflows/Activities/Inspection/Interfaces/ITransformationInspectionContext.cs +++ b/Core/Stateflows/Activities/Inspection/Interfaces/ITransformationInspectionContext.cs @@ -1,5 +1,4 @@ using Stateflows.Activities.Context.Interfaces; -using Stateflows.Common; namespace Stateflows.Activities.Inspection.Interfaces { diff --git a/Core/Stateflows/Activities/Interfaces/IActivitiesBuilder.cs b/Core/Stateflows/Activities/Interfaces/IActivitiesBuilder.cs index 0e505ed5..208659df 100644 --- a/Core/Stateflows/Activities/Interfaces/IActivitiesBuilder.cs +++ b/Core/Stateflows/Activities/Interfaces/IActivitiesBuilder.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; using System.Collections.Generic; using Stateflows.Activities.Registration.Interfaces; @@ -8,13 +9,14 @@ public interface IActivitiesBuilder { IActivitiesBuilder AddFromAssembly(Assembly assembly); IActivitiesBuilder AddFromAssemblies(IEnumerable assemblies); + [Obsolete("AddFromLoadedAssemblies() is deprecated, use AddFromAssembly(), AddFromAssemblies() or AddActivity() instead.")] IActivitiesBuilder AddFromLoadedAssemblies(); IActivitiesBuilder AddActivity(string activityName, ReactiveActivityBuildAction buildAction); IActivitiesBuilder AddActivity(string activityName, int version, ReactiveActivityBuildAction buildAction); IActivitiesBuilder AddActivity(string activityName = null, int version = 1) - where TActivity : Activity; + where TActivity : class, IActivity; IActivitiesBuilder AddActivity(int version) - where TActivity : Activity; + where TActivity : class, IActivity; IActivitiesBuilder AddInterceptor() where TInterceptor : class, IActivityInterceptor; IActivitiesBuilder AddInterceptor(ActivityInterceptorFactory interceptorFactory); diff --git a/Core/Stateflows/Activities/Interfaces/IActivity.cs b/Core/Stateflows/Activities/Interfaces/IActivity.cs deleted file mode 100644 index b4f955e2..00000000 --- a/Core/Stateflows/Activities/Interfaces/IActivity.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using Stateflows.Common; - -namespace Stateflows.Activities.Interfaces -{ - public interface IActivity : IBehavior - { - Task> Execute(IEnumerable input); - - Task Execute(IDictionary parameters); - - Task Execute(IDictionary parameters); - } -} diff --git a/Core/Stateflows/Activities/Interfaces/IActivityInspector.cs b/Core/Stateflows/Activities/Interfaces/IActivityInspector.cs index e2e0765e..a6ee5a7b 100644 --- a/Core/Stateflows/Activities/Interfaces/IActivityInspector.cs +++ b/Core/Stateflows/Activities/Interfaces/IActivityInspector.cs @@ -9,7 +9,7 @@ public interface IActivityInspector { Task BeforeActivityInitializeAsync(IActivityInitializationInspectionContext context) => Task.CompletedTask; - Task AfterActivityInitializeAsync(IActivityInitializationInspectionContext context) + Task AfterActivityInitializeAsync(IActivityInitializationInspectionContext context, bool initialized) => Task.CompletedTask; Task BeforeActivityFinalizeAsync(IActivityFinalizationInspectionContext context) diff --git a/Core/Stateflows/Activities/Interfaces/IActivityObserver.cs b/Core/Stateflows/Activities/Interfaces/IActivityObserver.cs index 555aa339..f5950907 100644 --- a/Core/Stateflows/Activities/Interfaces/IActivityObserver.cs +++ b/Core/Stateflows/Activities/Interfaces/IActivityObserver.cs @@ -7,7 +7,7 @@ public interface IActivityObserver { Task BeforeActivityInitializeAsync(IActivityInitializationContext context) => Task.CompletedTask; - Task AfterActivityInitializeAsync(IActivityInitializationContext context) + Task AfterActivityInitializeAsync(IActivityInitializationContext context, bool initialized) => Task.CompletedTask; Task BeforeActivityFinalizeAsync(IActivityFinalizationContext context) diff --git a/Core/Stateflows/Activities/Interfaces/Model/IAcceptEventActionNode.cs b/Core/Stateflows/Activities/Interfaces/Model/IAcceptEventActionNode.cs new file mode 100644 index 00000000..e22ed619 --- /dev/null +++ b/Core/Stateflows/Activities/Interfaces/Model/IAcceptEventActionNode.cs @@ -0,0 +1,12 @@ +using Stateflows.Common; +using System.Threading; +using System.Threading.Tasks; + +namespace Stateflows.Activities +{ + public interface IAcceptEventActionNode : IActivityNode + where TEvent : Event, new() + { + Task ExecuteAsync(TEvent @event, CancellationToken cancellationToken); + } +} diff --git a/Core/Stateflows/Activities/Interfaces/Model/IActionNode.cs b/Core/Stateflows/Activities/Interfaces/Model/IActionNode.cs new file mode 100644 index 00000000..4eda5be9 --- /dev/null +++ b/Core/Stateflows/Activities/Interfaces/Model/IActionNode.cs @@ -0,0 +1,11 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Stateflows.Activities +{ + public interface IActionNode : IActivityNode + { + Task ExecuteAsync(CancellationToken cancellationToken); + } +} diff --git a/Core/Stateflows/Activities/Interfaces/Model/IActivity.cs b/Core/Stateflows/Activities/Interfaces/Model/IActivity.cs new file mode 100644 index 00000000..2f6adca9 --- /dev/null +++ b/Core/Stateflows/Activities/Interfaces/Model/IActivity.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using Stateflows.Activities.Attributes; +using Stateflows.Activities.Registration.Interfaces; + +namespace Stateflows.Activities +{ + public interface IActivity + { + void Build(IActivityBuilder builder); + } + + public static class Activity + where TActivity : class, IActivity + { + public static string Name + { + get + { + var activityType = typeof(TActivity); + var attribute = activityType.GetCustomAttribute(); + return attribute != null && attribute.Name != null + ? attribute.Name + : activityType.FullName; + } + } + + public static BehaviorClass ToClass() + => new BehaviorClass(BehaviorType.Activity, Name); + + public static BehaviorId ToId(string instance) + => new BehaviorId(ToClass(), instance); + } +} diff --git a/Core/Stateflows/Activities/Interfaces/Model/IActivityNode.cs b/Core/Stateflows/Activities/Interfaces/Model/IActivityNode.cs new file mode 100644 index 00000000..7dbe2caa --- /dev/null +++ b/Core/Stateflows/Activities/Interfaces/Model/IActivityNode.cs @@ -0,0 +1,13 @@ +using Stateflows.Common.Extensions; + +namespace Stateflows.Activities +{ + public interface IActivityNode + { } + + public static class ActivityNode + where TActivityNode : class, IActivityNode + { + public static string Name => typeof(TActivityNode).GetReadableName(); + } +} diff --git a/Core/Stateflows/Activities/Interfaces/Model/IExceptionHandlerNode.cs b/Core/Stateflows/Activities/Interfaces/Model/IExceptionHandlerNode.cs new file mode 100644 index 00000000..2a1fca48 --- /dev/null +++ b/Core/Stateflows/Activities/Interfaces/Model/IExceptionHandlerNode.cs @@ -0,0 +1,12 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Stateflows.Activities +{ + public interface IExceptionHandlerNode : IActivityNode + where TException : Exception + { + Task HandleAsync(TException exception, CancellationToken cancellationToken); + } +} diff --git a/Core/Stateflows/Activities/Interfaces/Model/IFlow.cs b/Core/Stateflows/Activities/Interfaces/Model/IFlow.cs new file mode 100644 index 00000000..406904ff --- /dev/null +++ b/Core/Stateflows/Activities/Interfaces/Model/IFlow.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; + +namespace Stateflows.Activities +{ + public interface IBaseFlow + { + int Weight => 1; + } + + public interface IBaseFlow : IBaseFlow + { } + + public interface IFlowGuard : IBaseFlow + { + Task GuardAsync(TToken token); + } + + public interface IFlowTransformation : IBaseFlow + { + Task TransformAsync(TToken token); + } + + public interface IBaseControlFlow : IBaseFlow + { } + + public interface IControlFlowGuard : IBaseControlFlow + { + Task GuardAsync(); + } +} diff --git a/Core/Stateflows/Activities/Interfaces/Model/ISendEventActionNode.cs b/Core/Stateflows/Activities/Interfaces/Model/ISendEventActionNode.cs new file mode 100644 index 00000000..2bcdf3fe --- /dev/null +++ b/Core/Stateflows/Activities/Interfaces/Model/ISendEventActionNode.cs @@ -0,0 +1,13 @@ +using Stateflows.Common; +using System.Threading.Tasks; + +namespace Stateflows.Activities +{ + public interface ISendEventActionNode : IActivityNode + where TEvent : Event, new() + { + Task GenerateEventAsync(); + + Task SelectTargetAsync(); + } +} diff --git a/Core/Stateflows/Activities/Interfaces/Model/IStructuredActivityNode.cs b/Core/Stateflows/Activities/Interfaces/Model/IStructuredActivityNode.cs new file mode 100644 index 00000000..0c05fad1 --- /dev/null +++ b/Core/Stateflows/Activities/Interfaces/Model/IStructuredActivityNode.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; + +namespace Stateflows.Activities +{ + public interface IBaseStructuredActivityNode : IActivityNode + { } + + public interface IStructuredActivityNodeInitialization : IBaseStructuredActivityNode + { + Task OnInitializeAsync(); + } + + public interface IStructuredActivityNodeFinalization : IBaseStructuredActivityNode + { + Task OnFinalizeAsync(); + } +} diff --git a/Core/Stateflows/Activities/Interfaces/Model/ITimeEventActionNode.cs b/Core/Stateflows/Activities/Interfaces/Model/ITimeEventActionNode.cs new file mode 100644 index 00000000..6132e1e6 --- /dev/null +++ b/Core/Stateflows/Activities/Interfaces/Model/ITimeEventActionNode.cs @@ -0,0 +1,10 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace Stateflows.Activities +{ + public interface ITimeEventActionNode : IActivityNode + { + Task ExecuteAsync(CancellationToken cancellationToken); + } +} diff --git a/Core/Stateflows/Activities/Models/Graph.cs b/Core/Stateflows/Activities/Models/Graph.cs index cb7ddd54..e7e2f7f0 100644 --- a/Core/Stateflows/Activities/Models/Graph.cs +++ b/Core/Stateflows/Activities/Models/Graph.cs @@ -21,6 +21,7 @@ public Graph(string name, int version) public int Version { get; } public Type ActivityType { get; set; } + public bool Interactive { get; set; } = false; public readonly Dictionary AllNodes = new Dictionary(); public readonly Dictionary AllNamedNodes = new Dictionary(); public readonly List AllEdgesList = new List(); @@ -28,6 +29,8 @@ public Graph(string name, int version) public readonly Dictionary> Initializers = new Dictionary>(); public readonly List InitializerTypes = new List(); + public Logic DefaultInitializer = null; + public readonly List ExceptionHandlerFactories = new List(); public readonly List InterceptorFactories = new List(); public readonly List ObserverFactories = new List(); @@ -59,6 +62,7 @@ public void Build() NodeType.Initial, NodeType.Input, NodeType.AcceptEventAction, + NodeType.TimeEventAction, }; var danglingNodes = AllNodes.Values.Where(node => !autoNodeTypes.Contains(node.Type) && !node.IncomingEdges.Any()).ToArray(); diff --git a/Core/Stateflows/Activities/Models/Node.cs b/Core/Stateflows/Activities/Models/Node.cs index 056aa615..db1dad1a 100644 --- a/Core/Stateflows/Activities/Models/Node.cs +++ b/Core/Stateflows/Activities/Models/Node.cs @@ -8,7 +8,6 @@ using Stateflows.Common.Models; using Stateflows.Activities.Registration; using Stateflows.Activities.Context.Classes; -using System.Xml.Linq; namespace Stateflows.Activities.Models { @@ -52,13 +51,13 @@ public Logic Action public IEnumerable GetIncomingTokenTypes() => IncomingEdges .Select(e => e.TargetTokenType) - .Where(t => t != typeof(Control) && t != typeof(NodeReference) && !typeof(Exception).IsAssignableFrom(t)) + .Where(t => t != typeof(ControlToken) && t != typeof(NodeReferenceToken) && !typeof(Exception).IsAssignableFrom(t)) .Distinct(); public IEnumerable GetOutgoingTokenTypes() => Edges .Select(e => e.TokenType) - .Where(t => t != typeof(Control) && t != typeof(NodeReference) && !typeof(Exception).IsAssignableFrom(t)) + .Where(t => t != typeof(ControlToken) && t != typeof(NodeReferenceToken) && !typeof(Exception).IsAssignableFrom(t)) .Distinct(); public void ScanForDeclaredTypes(Type nodeType) @@ -151,7 +150,7 @@ public Node OutputNode private IEnumerable acceptEventActionNodes = null; public IEnumerable AcceptEventActionNodes => acceptEventActionNodes ??= Nodes.Values - .Where(n => n.Type == NodeType.AcceptEventAction); + .Where(n => n.Type == NodeType.AcceptEventAction || n.Type == NodeType.TimeEventAction); private IEnumerable danglingTimeEventActionNodes = null; public IEnumerable DanglingTimeEventActionNodes @@ -200,7 +199,7 @@ public async Task> HandleExceptionAsync(Exception exception, new TokenHolder[] { exception.ToExceptionHolder(), - new NodeReference() { Node = this }.ToTokenHolder(), + new NodeReferenceToken() { Node = this }.ToTokenHolder(), } ); diff --git a/Core/Stateflows/Activities/Registration/ActivitiesRegister.cs b/Core/Stateflows/Activities/Registration/ActivitiesRegister.cs index a5b0aa8c..dec3b080 100644 --- a/Core/Stateflows/Activities/Registration/ActivitiesRegister.cs +++ b/Core/Stateflows/Activities/Registration/ActivitiesRegister.cs @@ -3,8 +3,8 @@ using System.Collections.Generic; using System.Runtime.Serialization; using Microsoft.Extensions.DependencyInjection; +using Stateflows.Common.Extensions; using Stateflows.Activities.Models; -using Stateflows.Activities.Extensions; using Stateflows.Activities.Exceptions; using Stateflows.Activities.Registration.Builders; using Stateflows.Activities.Registration.Interfaces; @@ -85,12 +85,11 @@ public void AddActivity(string activityName, int version, Type activityType) throw new ActivityDefinitionException($"Activity '{activityName}' with version '{version}' is already registered"); } - Services.RegisterActivity(activityType); + Services.AddServiceType(activityType); - var activity = FormatterServices.GetUninitializedObject(activityType) as Activity; + var activity = FormatterServices.GetUninitializedObject(activityType) as IActivity; var builder = new ActivityBuilder(activityName, version, null, Services); - builder.AddActivityEvents(activityType); builder.Result.ActivityType = activityType; activity.Build(builder); builder.Result.Build(); @@ -105,37 +104,43 @@ public void AddActivity(string activityName, int version, Type activityType) [DebuggerHidden] public void AddActivity(string activityName, int version) - where TActivity : Activity + where TActivity : class, IActivity => AddActivity(activityName, version, typeof(TActivity)); #region Observability + [DebuggerHidden] public void AddGlobalInterceptor(ActivityInterceptorFactory interceptorFactory) => GlobalInterceptorFactories.Add(interceptorFactory); + [DebuggerHidden] public void AddGlobalInterceptor() where TInterceptor : class, IActivityInterceptor { - Services.RegisterInterceptor(); + Services.AddServiceType(); AddGlobalInterceptor(serviceProvider => serviceProvider.GetRequiredService()); } + [DebuggerHidden] public void AddGlobalExceptionHandler(ActivityExceptionHandlerFactory exceptionHandlerFactory) => GlobalExceptionHandlerFactories.Add(exceptionHandlerFactory); + [DebuggerHidden] public void AddGlobalExceptionHandler() where TExceptionHandler : class, IActivityExceptionHandler { - Services.RegisterExceptionHandler(); + Services.AddServiceType(); AddGlobalExceptionHandler(serviceProvider => serviceProvider.GetRequiredService()); } + [DebuggerHidden] public void AddGlobalObserver(ActivityObserverFactory observerFactory) => GlobalObserverFactories.Add(observerFactory); + [DebuggerHidden] public void AddGlobalObserver() where TObserver : class, IActivityObserver { - Services.RegisterObserver(); + Services.AddServiceType(); AddGlobalObserver(serviceProvider => serviceProvider.GetRequiredService()); } #endregion diff --git a/Core/Stateflows/Activities/Registration/Builders/ActivitiesBuilder.cs b/Core/Stateflows/Activities/Registration/Builders/ActivitiesBuilder.cs index d167b6d1..9fa2c75a 100644 --- a/Core/Stateflows/Activities/Registration/Builders/ActivitiesBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Builders/ActivitiesBuilder.cs @@ -23,7 +23,7 @@ public IActivitiesBuilder AddFromAssembly(Assembly assembly) { assembly.GetAttributedTypes().ToList().ForEach(@type => { - if (typeof(Activity).IsAssignableFrom(@type)) + if (typeof(IActivity).IsAssignableFrom(@type)) { var attribute = @type.GetCustomAttributes(typeof(ActivityBehaviorAttribute)).FirstOrDefault() as ActivityBehaviorAttribute; Register.AddActivity(attribute?.Name ?? @type.FullName, attribute?.Version ?? 1, @type); @@ -63,16 +63,16 @@ public IActivitiesBuilder AddActivity(string activityName, int version, Reactive [DebuggerHidden] public IActivitiesBuilder AddActivity(string activityName = null, int version = 1) - where TActivity : Activity + where TActivity : class, IActivity { - Register.AddActivity(activityName ?? ActivityInfo.Name, version); + Register.AddActivity(activityName ?? Activity.Name, version); return this; } [DebuggerHidden] public IActivitiesBuilder AddActivity(int version) - where TActivity : Activity + where TActivity : class, IActivity => AddActivity(null, version); #region Observability diff --git a/Core/Stateflows/Activities/Registration/Builders/ActivityBuilder.cs b/Core/Stateflows/Activities/Registration/Builders/ActivityBuilder.cs index d9ce9f17..1dfd2183 100644 --- a/Core/Stateflows/Activities/Registration/Builders/ActivityBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Builders/ActivityBuilder.cs @@ -4,20 +4,19 @@ using Stateflows.Common; using Stateflows.Common.Models; using Stateflows.Activities.Models; -using Stateflows.Activities.Events; using Stateflows.Activities.Extensions; using Stateflows.Activities.Context.Classes; using Stateflows.Activities.Context.Interfaces; using Stateflows.Activities.Registration.Extensions; using Stateflows.Activities.Registration.Interfaces; using Stateflows.Activities.Registration.Interfaces.Base; +using Stateflows.Common.Extensions; namespace Stateflows.Activities.Registration.Builders { internal class ActivityBuilder : BaseActivityBuilder, - IActivityBuilder, - ITypedActivityBuilder + IActivityBuilder { new public Graph Result { @@ -41,6 +40,7 @@ public IActivityBuilder AddInitializer(Type initializerType, string initializerN }; Result.Initializers.Add(initializerName, initializer); + Result.InitializerTypes.Add(initializerType); } initializer.Actions.Add(initializerAction); @@ -48,33 +48,37 @@ public IActivityBuilder AddInitializer(Type initializerType, string initializerN return this; } - public IActivityBuilder AddOnInitialize(Func> actionAsync) - => AddOnInitialize(c => + public IActivityBuilder AddDefaultInitializer(Func> actionAsync) + { + Result.DefaultInitializer = new Logic() + { + Name = Constants.Initialize + }; + + Result.DefaultInitializer.Actions.Add(c => { - var baseContext = c as BaseContext; - var context = new ActivityInitializationContext(baseContext, baseContext.Context.Event as InitializationRequest); + var context = new ActivityInitializationContext(c, c.Context.Event as Initialize); return actionAsync(context); }); - public IActivityBuilder AddOnInitialize(Func, Task> actionAsync) - where TInitializationRequest : InitializationRequest, new() + return this; + } + + public IActivityBuilder AddInitializer(Func, Task> actionAsync) + where TInitializationEvent : Event, new() { actionAsync.ThrowIfNull(nameof(actionAsync)); actionAsync = actionAsync.AddActivityInvocationContext(Result); - var initializerName = EventInfo.Name; + var initializerName = EventInfo.Name; - return AddInitializer(typeof(TInitializationRequest), initializerName, async c => + return AddInitializer(typeof(TInitializationEvent), initializerName, async c => { var result = false; - var context = new ActivityInitializationContext( + var context = new ActivityInitializationContext( c, - ( - c.Context.Event is ExecutionRequest executionRequest - ? executionRequest.InitializationRequest - : c.Context.Event - ) as TInitializationRequest + c.Context.Event as TInitializationEvent ); try @@ -83,7 +87,7 @@ c.Context.Event is ExecutionRequest executionRequest } catch (Exception e) { - await c.Context.Executor.Inspector.OnActivityInitializationExceptionAsync(context, context.InitializationRequest, e); + await c.Context.Executor.Inspector.OnActivityInitializationExceptionAsync(context, context.InitializationEvent, e); result = false; } @@ -98,7 +102,7 @@ IActivityBuilder IReactiveActivity.AddAction(string actionNode IActivityBuilder IReactiveActivity.AddStructuredActivity(string actionNodeName, ReactiveStructuredActivityBuildAction buildAction) => AddStructuredActivity(actionNodeName, buildAction) as IActivityBuilder; - IActivityBuilder IActivityEvents.AddOnFinalize(Func actionAsync) + IActivityBuilder IActivityEvents.AddFinalizer(Func actionAsync) => AddOnFinalize(actionAsync) as IActivityBuilder; IActivityBuilder IInitial.AddInitial(InitialBuildAction buildAction) @@ -122,47 +126,18 @@ IActivityBuilder IReactiveActivity.AddIterativeActivity.AddAcceptEventAction(string actionNodeName, AcceptEventActionDelegateAsync eventActionAsync, AcceptEventActionBuildAction buildAction) => AddAcceptEventAction(actionNodeName, eventActionAsync, buildAction) as IActivityBuilder; + IActivityBuilder IAcceptEvent.AddTimeEventAction(string actionNodeName, TimeEventActionDelegateAsync eventActionAsync, AcceptEventActionBuildAction buildAction) + => AddTimeEventAction(actionNodeName, eventActionAsync, buildAction) as IActivityBuilder; + IActivityBuilder ISendEvent.AddSendEventAction(string actionNodeName, SendEventActionDelegateAsync actionAsync, BehaviorIdSelectorAsync targetSelectorAsync, SendEventActionBuildAction buildAction) => AddSendEventAction(actionNodeName, actionAsync, targetSelectorAsync, buildAction) as IActivityBuilder; #endregion - #region ITypedActivityBuilder - ITypedActivityBuilder IReactiveActivity.AddAction(string actionNodeName, ActionDelegateAsync actionAsync, ActionBuildAction buildAction) - => AddAction(actionNodeName, actionAsync, b => buildAction?.Invoke(b)) as ITypedActivityBuilder; - - ITypedActivityBuilder IReactiveActivity.AddStructuredActivity(string actionNodeName, ReactiveStructuredActivityBuildAction buildAction) - => AddStructuredActivity(actionNodeName, buildAction) as ITypedActivityBuilder; - - ITypedActivityBuilder IInitial.AddInitial(InitialBuildAction buildAction) - => AddInitial(buildAction) as ITypedActivityBuilder; - - ITypedActivityBuilder IFinal.AddFinal() - => AddFinal() as ITypedActivityBuilder; - - ITypedActivityBuilder IInput.AddInput(InputBuildAction buildAction) - => AddInput(buildAction) as ITypedActivityBuilder; - - ITypedActivityBuilder IOutput.AddOutput() - => AddOutput() as ITypedActivityBuilder; - - ITypedActivityBuilder IReactiveActivity.AddParallelActivity(string actionNodeName, ParallelActivityBuildAction buildAction, int chunkSize) - => AddParallelActivity(actionNodeName, buildAction, chunkSize) as ITypedActivityBuilder; - - ITypedActivityBuilder IReactiveActivity.AddIterativeActivity(string actionNodeName, IterativeActivityBuildAction buildAction, int chunkSize) - => AddIterativeActivity(actionNodeName, buildAction, chunkSize) as ITypedActivityBuilder; - - ITypedActivityBuilder IAcceptEvent.AddAcceptEventAction(string actionNodeName, AcceptEventActionDelegateAsync eventActionAsync, AcceptEventActionBuildAction buildAction) - => AddAcceptEventAction(actionNodeName, eventActionAsync, buildAction) as ITypedActivityBuilder; - - ITypedActivityBuilder ISendEvent.AddSendEventAction(string actionNodeName, SendEventActionDelegateAsync actionAsync, BehaviorIdSelectorAsync targetSelectorAsync, SendEventActionBuildAction buildAction) - => AddSendEventAction(actionNodeName, actionAsync, targetSelectorAsync, buildAction) as ITypedActivityBuilder; - #endregion - #region Observability public IActivityBuilder AddExceptionHandler() where TExceptionHandler : class, IActivityExceptionHandler { - Services.RegisterExceptionHandler(); + Services.AddServiceType(); AddExceptionHandler(serviceProvider => serviceProvider.GetRequiredService()); return this; @@ -178,7 +153,7 @@ public IActivityBuilder AddExceptionHandler(ActivityExceptionHandlerFactory exce public IActivityBuilder AddInterceptor() where TInterceptor : class, IActivityInterceptor { - Services.RegisterInterceptor(); + Services.AddServiceType(); AddInterceptor(serviceProvider => serviceProvider.GetRequiredService()); return this; @@ -194,7 +169,7 @@ public IActivityBuilder AddInterceptor(ActivityInterceptorFactory interceptorFac public IActivityBuilder AddObserver() where TObserver : class, IActivityObserver { - Services.RegisterObserver(); + Services.AddServiceType(); AddObserver(serviceProvider => serviceProvider.GetRequiredService()); return this; @@ -206,24 +181,6 @@ public IActivityBuilder AddObserver(ActivityObserverFactory observerFactory) return this; } - - ITypedActivityBuilder IActivityUtils.AddExceptionHandler() - => AddExceptionHandler() as ITypedActivityBuilder; - - ITypedActivityBuilder IActivityUtils.AddExceptionHandler(ActivityExceptionHandlerFactory exceptionHandlerFactory) - => AddExceptionHandler(exceptionHandlerFactory) as ITypedActivityBuilder; - - ITypedActivityBuilder IActivityUtils.AddInterceptor() - => AddInterceptor() as ITypedActivityBuilder; - - ITypedActivityBuilder IActivityUtils.AddInterceptor(ActivityInterceptorFactory interceptorFactory) - => AddInterceptor(interceptorFactory) as ITypedActivityBuilder; - - ITypedActivityBuilder IActivityUtils.AddObserver() - => AddObserver() as ITypedActivityBuilder; - - ITypedActivityBuilder IActivityUtils.AddObserver(ActivityObserverFactory observerFactory) - => AddObserver(observerFactory) as ITypedActivityBuilder; #endregion } } diff --git a/Core/Stateflows/Activities/Registration/Builders/BaseActivityBuilder.cs b/Core/Stateflows/Activities/Registration/Builders/BaseActivityBuilder.cs index 73acbbf1..34393ab3 100644 --- a/Core/Stateflows/Activities/Registration/Builders/BaseActivityBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Builders/BaseActivityBuilder.cs @@ -36,7 +36,8 @@ public BaseActivityBuilder AddNode(NodeType type, string nodeName, ActionDelegat nodeName = $"{Node.Name}.{nodeName}"; } - var namedNodeTypes = new NodeType[] { + var namedNodeTypes = new NodeType[] + { NodeType.Action, NodeType.Join, NodeType.Merge, @@ -47,11 +48,18 @@ public BaseActivityBuilder AddNode(NodeType type, string nodeName, ActionDelegat NodeType.ParallelActivity, NodeType.IterativeActivity, NodeType.AcceptEventAction, + NodeType.TimeEventAction, NodeType.Output, NodeType.Final, NodeType.DataStore }; + var interactiveNodeTypes = new NodeType[] + { + NodeType.AcceptEventAction, + NodeType.TimeEventAction + }; + if (namedNodeTypes.Contains(type)) { if (string.IsNullOrEmpty(nodeName)) @@ -65,6 +73,11 @@ public BaseActivityBuilder AddNode(NodeType type, string nodeName, ActionDelegat } } + if (interactiveNodeTypes.Contains(type)) + { + Result.Interactive = true; + } + var node = new Node() { Type = type, @@ -85,7 +98,7 @@ public BaseActivityBuilder AddNode(NodeType type, string nodeName, ActionDelegat node.ExceptionType = exceptionOrEventType; } - if (type == NodeType.AcceptEventAction) + if (interactiveNodeTypes.Contains(type)) { if (exceptionOrEventType is null) { @@ -110,7 +123,7 @@ public BaseActivityBuilder AddNode(NodeType type, string nodeName, ActionDelegat if (!(c as BaseContext).Context.Executor.StructuralTypes.Contains(node.Type)) { - c.Output(new Control()); + c.Output(new ControlToken()); } } catch (Exception e) @@ -170,6 +183,20 @@ public BaseActivityBuilder AddAcceptEventAction( typeof(TEvent) ); + public BaseActivityBuilder AddTimeEventAction( + string actionNodeName, + TimeEventActionDelegateAsync actionAsync, + AcceptEventActionBuildAction buildAction = null + ) + where TTimeEvent : TimeEvent, new() + => AddNode( + NodeType.TimeEventAction, + actionNodeName, + c => actionAsync(new AcceptEventActionContext(c as ActionContext)), + b => buildAction?.Invoke(b), + typeof(TTimeEvent) + ); + public BaseActivityBuilder AddInitial(InitialBuildAction buildAction) => AddNode( NodeType.Initial, diff --git a/Core/Stateflows/Activities/Registration/Builders/NodeBuilder.cs b/Core/Stateflows/Activities/Registration/Builders/NodeBuilder.cs index eb64f62d..11de93bb 100644 --- a/Core/Stateflows/Activities/Registration/Builders/NodeBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Builders/NodeBuilder.cs @@ -41,10 +41,10 @@ public NodeBuilder(Node node, BaseActivityBuilder activityBuilder, IServiceColle } public IActionBuilder AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction = null) - => AddFlowInternal(targetNodeName, false, b => buildAction?.Invoke(b as IControlFlowBuilder)); + => AddFlowInternal(targetNodeName, false, b => buildAction?.Invoke(b as IControlFlowBuilder)); public IActionBuilder AddElseControlFlow(string targetNodeName, ElseControlFlowBuildAction buildAction = null) - => AddFlowInternal(targetNodeName, true, b => buildAction?.Invoke(b as IElseControlFlowBuilder)); + => AddFlowInternal(targetNodeName, true, b => buildAction?.Invoke(b as IElseControlFlowBuilder)); public IActionBuilder AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction = null) => AddFlowInternal(targetNodeName, false, buildAction); @@ -85,19 +85,19 @@ public IActionBuilderWithOptions SetOptions(NodeOptions nodeOptions) return this; } - IActionBuilderWithOptions IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IActionBuilderWithOptions IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IActionBuilderWithOptions; - IActionBuilderWithOptions IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IActionBuilderWithOptions IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IActionBuilderWithOptions; - IInitialBuilder IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IInitialBuilder IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IInitialBuilder; - ITypedActionBuilder IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + ITypedActionBuilder IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as ITypedActionBuilder; - ITypedActionBuilder IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + ITypedActionBuilder IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as ITypedActionBuilder; public IActionBuilderWithOptions AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) @@ -106,7 +106,7 @@ public IActionBuilderWithOptions AddExceptionHandler(ExceptionHandle var targetNodeName = $"{Node.Name}.{typeof(TException).FullName}.ExceptionHandler"; AddFlow(targetNodeName); - AddFlow(targetNodeName); + AddFlow(targetNodeName); ActivityBuilder.AddNode( NodeType.ExceptionHandler, @@ -114,7 +114,7 @@ public IActionBuilderWithOptions AddExceptionHandler(ExceptionHandle (ActionDelegateAsync)(c => { var contextObj = c as ActionContext; - var nodeOfOrigin = contextObj.InputTokens.OfType>().FirstOrDefault()?.Payload?.Node; + var nodeOfOrigin = contextObj.InputTokens.OfType>().FirstOrDefault()?.Payload?.Node; var context = new ExceptionHandlerContext(contextObj, Node, nodeOfOrigin, contextObj.NodeScope); exceptionHandler?.Invoke(context); @@ -130,46 +130,46 @@ public IActionBuilderWithOptions AddExceptionHandler(ExceptionHandle return this; } - ITypedActionBuilder IExceptionHandler.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) + ITypedActionBuilder IExceptionHandlerBase.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) => AddExceptionHandler(exceptionHandler) as ITypedActionBuilder; - IActionBuilder IExceptionHandler.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) + IActionBuilder IExceptionHandlerBase.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) => AddExceptionHandler(exceptionHandler) as IActionBuilder; - IInputBuilder IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IInputBuilder IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IInputBuilder; - void IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + void IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction); - void IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + void IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction); - IForkBuilder IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IForkBuilder IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IForkBuilder; - IForkBuilder IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IForkBuilder IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IForkBuilder; - IAcceptEventActionBuilder IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IAcceptEventActionBuilder IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IAcceptEventActionBuilder; - IAcceptEventActionBuilder IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IAcceptEventActionBuilder IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IAcceptEventActionBuilder; - IAcceptEventActionBuilder IExceptionHandler.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) + IAcceptEventActionBuilder IExceptionHandlerBase.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) => AddExceptionHandler(exceptionHandler) as IAcceptEventActionBuilder; - ISendEventActionBuilder IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + ISendEventActionBuilder IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as ISendEventActionBuilder; - IDecisionBuilder IDecisionFlow.AddFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IDecisionBuilder IDecisionFlowBase.AddFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IDecisionBuilder; - IDecisionBuilder IElseDecisionFlow.AddElseFlow(string targetNodeName, ElseControlFlowBuildAction buildAction) + IDecisionBuilder IElseDecisionFlowBase.AddElseFlow(string targetNodeName, ElseControlFlowBuildAction buildAction) => AddElseControlFlow(targetNodeName, buildAction) as IDecisionBuilder; - IDataStoreBuilder IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IDataStoreBuilder IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IDataStoreBuilder; } } \ No newline at end of file diff --git a/Core/Stateflows/Activities/Registration/Builders/StructuredActivityBuilder.cs b/Core/Stateflows/Activities/Registration/Builders/StructuredActivityBuilder.cs index e10c42ab..15d1e947 100644 --- a/Core/Stateflows/Activities/Registration/Builders/StructuredActivityBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Builders/StructuredActivityBuilder.cs @@ -70,13 +70,13 @@ public IActionBuilderWithOptions SetOptions(NodeOptions nodeOptions) } #region IActionBuilder - IActionBuilderWithOptions IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IActionBuilderWithOptions IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IActionBuilderWithOptions; - IActionBuilderWithOptions IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IActionBuilderWithOptions IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IActionBuilderWithOptions; - IActionBuilderWithOptions IExceptionHandler.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) + IActionBuilderWithOptions IExceptionHandlerBase.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) => AddExceptionHandler(exceptionHandler) as IActionBuilderWithOptions; #endregion @@ -84,13 +84,13 @@ IActionBuilderWithOptions IExceptionHandler.AddExcept IReactiveStructuredActivityBuilderWithOptions IReactiveActivity.AddAction(string actionNodeName, ActionDelegateAsync actionAsync, ActionBuildAction buildAction) => AddAction(actionNodeName, actionAsync, b => buildAction(b)) as IReactiveStructuredActivityBuilderWithOptions; - IReactiveStructuredActivityBuilderWithOptions IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IReactiveStructuredActivityBuilderWithOptions IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IReactiveStructuredActivityBuilderWithOptions; IReactiveStructuredActivityBuilder IReactiveActivity.AddAction(string actionNodeName, ActionDelegateAsync actionAsync, ActionBuildAction buildAction) => AddAction(actionNodeName, actionAsync, b => buildAction?.Invoke(b)) as IReactiveStructuredActivityBuilder; - IReactiveStructuredActivityBuilder IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IReactiveStructuredActivityBuilder IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IReactiveStructuredActivityBuilder; IReactiveStructuredActivityBuilder IFinal.AddFinal() @@ -102,7 +102,7 @@ IReactiveStructuredActivityBuilder IInitial. IReactiveStructuredActivityBuilder IInput.AddInput(InputBuildAction buildAction) => AddInput(buildAction) as IReactiveStructuredActivityBuilder; - IReactiveStructuredActivityBuilder IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IReactiveStructuredActivityBuilder IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IReactiveStructuredActivityBuilder; IReactiveStructuredActivityBuilder IStructuredActivityEvents.AddOnFinalize(Func actionAsync) @@ -130,10 +130,10 @@ IReactiveStructuredActivityBuilderWithOptions INodeOptions.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IReactiveStructuredActivityBuilderWithOptions IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IReactiveStructuredActivityBuilderWithOptions; - IReactiveStructuredActivityBuilderWithOptions IExceptionHandler.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) + IReactiveStructuredActivityBuilderWithOptions IExceptionHandlerBase.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) => AddExceptionHandler(exceptionHandler) as IReactiveStructuredActivityBuilderWithOptions; IReactiveStructuredActivityBuilderWithOptions IFinal.AddFinal() @@ -163,7 +163,7 @@ IReactiveStructuredActivityBuilderWithOptions IReactiveActivity.AddIterativeActivity(string actionNodeName, IterativeActivityBuildAction buildAction, int chunkSize) => AddIterativeActivity(actionNodeName, buildAction, chunkSize) as IReactiveStructuredActivityBuilderWithOptions; - IReactiveStructuredActivityBuilder IExceptionHandler.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) + IReactiveStructuredActivityBuilder IExceptionHandlerBase.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) => AddExceptionHandler(exceptionHandler) as IReactiveStructuredActivityBuilder; IReactiveStructuredActivityBuilder ISendEvent.AddSendEventAction(string actionNodeName, SendEventActionDelegateAsync actionAsync, BehaviorIdSelectorAsync targetSelectorAsync, SendEventActionBuildAction buildAction) @@ -172,24 +172,30 @@ IReactiveStructuredActivityBuilder ISendEvent.AddAcceptEventAction(string actionNodeName, AcceptEventActionDelegateAsync eventActionAsync, AcceptEventActionBuildAction buildAction) => AddAcceptEventAction(actionNodeName, eventActionAsync, buildAction) as IReactiveStructuredActivityBuilder; + IReactiveStructuredActivityBuilder IAcceptEvent.AddTimeEventAction(string actionNodeName, TimeEventActionDelegateAsync eventActionAsync, AcceptEventActionBuildAction buildAction) + => AddTimeEventAction(actionNodeName, eventActionAsync, buildAction) as IReactiveStructuredActivityBuilder; + IReactiveStructuredActivityBuilderWithOptions ISendEvent.AddSendEventAction(string actionNodeName, SendEventActionDelegateAsync actionAsync, BehaviorIdSelectorAsync targetSelectorAsync, SendEventActionBuildAction buildAction) => AddSendEventAction(actionNodeName, actionAsync, targetSelectorAsync, buildAction) as IReactiveStructuredActivityBuilderWithOptions; IReactiveStructuredActivityBuilderWithOptions IAcceptEvent.AddAcceptEventAction(string actionNodeName, AcceptEventActionDelegateAsync eventActionAsync, AcceptEventActionBuildAction buildAction) => AddAcceptEventAction(actionNodeName, eventActionAsync, buildAction) as IReactiveStructuredActivityBuilderWithOptions; + + IReactiveStructuredActivityBuilderWithOptions IAcceptEvent.AddTimeEventAction(string actionNodeName, TimeEventActionDelegateAsync eventActionAsync, AcceptEventActionBuildAction buildAction) + => AddTimeEventAction(actionNodeName, eventActionAsync, buildAction) as IReactiveStructuredActivityBuilderWithOptions; #endregion #region IStructuredActivityBuilder IStructuredActivityBuilderWithOptions IActivity.AddAction(string actionNodeName, ActionDelegateAsync actionAsync, ActionBuildAction buildAction) => AddAction(actionNodeName, actionAsync, b => buildAction(b)) as IStructuredActivityBuilderWithOptions; - IStructuredActivityBuilderWithOptions IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IStructuredActivityBuilderWithOptions IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IStructuredActivityBuilderWithOptions; IStructuredActivityBuilder IActivity.AddAction(string actionNodeName, ActionDelegateAsync actionAsync, ActionBuildAction buildAction) => AddAction(actionNodeName, actionAsync, b => buildAction?.Invoke(b)) as IStructuredActivityBuilder; - IStructuredActivityBuilder IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + IStructuredActivityBuilder IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as IStructuredActivityBuilder; IStructuredActivityBuilder IFinal.AddFinal() @@ -201,7 +207,7 @@ IStructuredActivityBuilder IInitial.AddInitial(Initi IStructuredActivityBuilder IInput.AddInput(InputBuildAction buildAction) => AddInput(buildAction) as IStructuredActivityBuilder; - IStructuredActivityBuilder IObjectFlow.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IStructuredActivityBuilder IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IStructuredActivityBuilder; IStructuredActivityBuilder IStructuredActivityEvents.AddOnFinalize(Func actionAsync) @@ -216,11 +222,11 @@ IStructuredActivityBuilder IOutput.AddOutput() IStructuredActivityBuilder IActivity.AddStructuredActivity(string actionNodeName, StructuredActivityBuildAction buildAction) => AddStructuredActivity(actionNodeName, b => buildAction?.Invoke(b as IStructuredActivityBuilder)) as IStructuredActivityBuilder; - IStructuredActivityBuilder IActivity.AddParallelActivity(string actionNodeName, ParallelActivityBuildAction buildAction) - => AddParallelActivity(actionNodeName, buildAction) as IStructuredActivityBuilder; + IStructuredActivityBuilder IActivity.AddParallelActivity(string actionNodeName, ParallelActivityBuildAction buildAction, int chunkSize) + => AddParallelActivity(actionNodeName, buildAction, chunkSize) as IStructuredActivityBuilder; - IStructuredActivityBuilder IActivity.AddIterativeActivity(string actionNodeName, IterativeActivityBuildAction buildAction) - => AddIterativeActivity(actionNodeName, buildAction) as IStructuredActivityBuilder; + IStructuredActivityBuilder IActivity.AddIterativeActivity(string actionNodeName, IterativeActivityBuildAction buildAction, int chunkSize) + => AddIterativeActivity(actionNodeName, buildAction, chunkSize) as IStructuredActivityBuilder; IStructuredActivityBuilderWithOptions INodeOptions.SetOptions(NodeOptions nodeOptions) { @@ -229,10 +235,10 @@ IStructuredActivityBuilderWithOptions INodeOptions.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + IStructuredActivityBuilderWithOptions IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as IStructuredActivityBuilderWithOptions; - IStructuredActivityBuilderWithOptions IExceptionHandler.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) + IStructuredActivityBuilderWithOptions IExceptionHandlerBase.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) => AddExceptionHandler(exceptionHandler) as IStructuredActivityBuilderWithOptions; IStructuredActivityBuilderWithOptions IFinal.AddFinal() @@ -256,13 +262,13 @@ IStructuredActivityBuilderWithOptions IOutput.AddStructuredActivity(string actionNodeName, StructuredActivityBuildAction buildAction) => AddStructuredActivity(actionNodeName, b => buildAction?.Invoke(b as IStructuredActivityBuilder)) as IStructuredActivityBuilderWithOptions; - IStructuredActivityBuilderWithOptions IActivity.AddParallelActivity(string actionNodeName, ParallelActivityBuildAction buildAction) - => AddParallelActivity(actionNodeName, buildAction) as IStructuredActivityBuilderWithOptions; + IStructuredActivityBuilderWithOptions IActivity.AddParallelActivity(string actionNodeName, ParallelActivityBuildAction buildAction, int chunkSize) + => AddParallelActivity(actionNodeName, buildAction, chunkSize) as IStructuredActivityBuilderWithOptions; - IStructuredActivityBuilderWithOptions IActivity.AddIterativeActivity(string actionNodeName, IterativeActivityBuildAction buildAction) - => AddIterativeActivity(actionNodeName, buildAction) as IStructuredActivityBuilderWithOptions; + IStructuredActivityBuilderWithOptions IActivity.AddIterativeActivity(string actionNodeName, IterativeActivityBuildAction buildAction, int chunkSize) + => AddIterativeActivity(actionNodeName, buildAction, chunkSize) as IStructuredActivityBuilderWithOptions; - IStructuredActivityBuilder IExceptionHandler.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) + IStructuredActivityBuilder IExceptionHandlerBase.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) => AddExceptionHandler(exceptionHandler) as IStructuredActivityBuilder; IStructuredActivityBuilder ISendEvent.AddSendEventAction(string actionNodeName, SendEventActionDelegateAsync actionAsync, BehaviorIdSelectorAsync targetSelectorAsync, SendEventActionBuildAction buildAction) @@ -273,13 +279,13 @@ IStructuredActivityBuilderWithOptions ISendEvent.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) + ITypedActionBuilder IObjectFlowBase.AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction) => AddFlow(targetNodeName, buildAction) as ITypedActionBuilder; - ITypedActionBuilder IControlFlow.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) + ITypedActionBuilder IControlFlowBase.AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction) => AddControlFlow(targetNodeName, buildAction) as ITypedActionBuilder; - ITypedActionBuilder IExceptionHandler.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) + ITypedActionBuilder IExceptionHandlerBase.AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) => AddExceptionHandler(exceptionHandler) as ITypedActionBuilder; #endregion } diff --git a/Core/Stateflows/Activities/Registration/Constants.cs b/Core/Stateflows/Activities/Registration/Constants.cs index 8eb10035..bbc0ba2d 100644 --- a/Core/Stateflows/Activities/Registration/Constants.cs +++ b/Core/Stateflows/Activities/Registration/Constants.cs @@ -5,6 +5,7 @@ internal static class Constants public static readonly string Node = nameof(Node); public static readonly string ForceConsumed = nameof(ForceConsumed); public static readonly string Initialized = nameof(Initialized); + public static readonly string Finalized = nameof(Finalized); public static readonly string SourceNode = nameof(SourceNode); public static readonly string TargetNode = nameof(TargetNode); public static readonly string Action = nameof(Action); @@ -23,6 +24,7 @@ internal static class Constants public static readonly string ActiveNodes = nameof(ActiveNodes); public static readonly string NodeThreads = nameof(NodeThreads); public static readonly string NodeTimeEvents = nameof(NodeTimeEvents); + public static readonly string NodeStartupEvents = nameof(NodeStartupEvents); public static readonly string OutputTokens = nameof(OutputTokens); public static readonly string Event = nameof(Event); } diff --git a/Core/Stateflows/Activities/Registration/Enums/NodeType.cs b/Core/Stateflows/Activities/Registration/Enums/NodeType.cs index 1d87d285..4e519b30 100644 --- a/Core/Stateflows/Activities/Registration/Enums/NodeType.cs +++ b/Core/Stateflows/Activities/Registration/Enums/NodeType.cs @@ -14,6 +14,7 @@ public enum NodeType Merge, SendEventAction, AcceptEventAction, + TimeEventAction, StructuredActivity, ParallelActivity, IterativeActivity, diff --git a/Core/Stateflows/Activities/Registration/Extensions/LambdaExtensions.cs b/Core/Stateflows/Activities/Registration/Extensions/LambdaExtensions.cs index abf83216..40013799 100644 --- a/Core/Stateflows/Activities/Registration/Extensions/LambdaExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Extensions/LambdaExtensions.cs @@ -17,7 +17,7 @@ public static Func AddActivityInvocationContext { var rootContext = (context as IRootContext).Context; - var stateMachineInstance = rootContext.Executor.GetActivity(graph.ActivityType, rootContext); + var stateMachineInstance = rootContext.Executor.GetActivity(graph.ActivityType); return (TResult)lambdaInfo.Invoke(stateMachineInstance, new object[] { context }); } @@ -33,7 +33,7 @@ public static Action AddActivityInvocationContext(this Actio ? (TContext context) => { var rootContext = (context as IRootContext).Context; - var stateMachineInstance = rootContext.Executor.GetActivity(graph.ActivityType, rootContext); + var stateMachineInstance = rootContext.Executor.GetActivity(graph.ActivityType); lambdaInfo.Invoke(stateMachineInstance, new object[] { context }); } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Base/IAcceptEvent.cs b/Core/Stateflows/Activities/Registration/Interfaces/Base/IAcceptEvent.cs index fde6dd64..f179fbf2 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Base/IAcceptEvent.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Base/IAcceptEvent.cs @@ -6,5 +6,8 @@ public interface IAcceptEvent { TReturn AddAcceptEventAction(string actionNodeName, AcceptEventActionDelegateAsync eventActionAsync, AcceptEventActionBuildAction buildAction = null) where TEvent : Event, new(); + + TReturn AddTimeEventAction(string actionNodeName, TimeEventActionDelegateAsync eventActionAsync, AcceptEventActionBuildAction buildAction = null) + where TTimeEvent : TimeEvent, new(); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Base/IActivity.cs b/Core/Stateflows/Activities/Registration/Interfaces/Base/IActivity.cs index c1b8a825..865452aa 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Base/IActivity.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Base/IActivity.cs @@ -1,6 +1,4 @@ -using Stateflows.Common; - -namespace Stateflows.Activities.Registration.Interfaces.Base +namespace Stateflows.Activities.Registration.Interfaces.Base { public interface IActivity { @@ -8,8 +6,8 @@ public interface IActivity TReturn AddStructuredActivity(string actionNodeName, StructuredActivityBuildAction buildAction); - TReturn AddParallelActivity(string actionNodeName, ParallelActivityBuildAction buildAction); + TReturn AddParallelActivity(string actionNodeName, ParallelActivityBuildAction buildAction, int chunkSize = 1); - TReturn AddIterativeActivity(string actionNodeName, IterativeActivityBuildAction buildAction); + TReturn AddIterativeActivity(string actionNodeName, IterativeActivityBuildAction buildAction, int chunkSize = 1); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Base/IActivityEvents.cs b/Core/Stateflows/Activities/Registration/Interfaces/Base/IActivityEvents.cs index f00058fe..fa1be10d 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Base/IActivityEvents.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Base/IActivityEvents.cs @@ -7,11 +7,11 @@ namespace Stateflows.Activities.Registration.Interfaces.Base { public interface IActivityEvents { - TReturn AddOnInitialize(Func> actionAsync); + TReturn AddDefaultInitializer(Func> actionAsync); - TReturn AddOnInitialize(Func, Task> actionAsync) - where TInitializationRequest : InitializationRequest, new(); + TReturn AddInitializer(Func, Task> actionAsync) + where TInitializationEvent : Event, new(); - TReturn AddOnFinalize(Func actionAsync); + TReturn AddFinalizer(Func actionAsync); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Base/IControlFlow.cs b/Core/Stateflows/Activities/Registration/Interfaces/Base/IControlFlowBase.cs similarity index 68% rename from Core/Stateflows/Activities/Registration/Interfaces/Base/IControlFlow.cs rename to Core/Stateflows/Activities/Registration/Interfaces/Base/IControlFlowBase.cs index 2b17c7ba..4324b9b1 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Base/IControlFlow.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Base/IControlFlowBase.cs @@ -1,26 +1,26 @@ namespace Stateflows.Activities.Registration.Interfaces.Base { - public interface IControlFlow + public interface IControlFlowBase { TReturn AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction = null); } - public interface IElseControlFlow + public interface IElseControlFlowBase { TReturn AddElseControlFlow(string targetNodeName, ElseControlFlowBuildAction buildAction = null); } - public interface IDecisionFlow + public interface IDecisionFlowBase { - TReturn AddFlow(string targetNodeName, ControlFlowBuildAction buildAction = null); + TReturn AddFlow(string targetNodeName, ControlFlowBuildAction buildAction); } - public interface IElseDecisionFlow + public interface IElseDecisionFlowBase { TReturn AddElseFlow(string targetNodeName, ElseControlFlowBuildAction buildAction = null); } - public interface IControlFlow + public interface IControlFlowBase { void AddControlFlow(string targetNodeName, ControlFlowBuildAction buildAction = null); } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Base/IExceptionHandler.cs b/Core/Stateflows/Activities/Registration/Interfaces/Base/IExceptionHandlerBase.cs similarity index 81% rename from Core/Stateflows/Activities/Registration/Interfaces/Base/IExceptionHandler.cs rename to Core/Stateflows/Activities/Registration/Interfaces/Base/IExceptionHandlerBase.cs index 9c3805f5..78f9e516 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Base/IExceptionHandler.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Base/IExceptionHandlerBase.cs @@ -2,7 +2,7 @@ namespace Stateflows.Activities.Registration.Interfaces.Base { - public interface IExceptionHandler + public interface IExceptionHandlerBase { TReturn AddExceptionHandler(ExceptionHandlerDelegateAsync exceptionHandler) where TException : Exception; diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Base/IObjectFlow.cs b/Core/Stateflows/Activities/Registration/Interfaces/Base/IObjectFlow.cs deleted file mode 100644 index 122a46d4..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Base/IObjectFlow.cs +++ /dev/null @@ -1,101 +0,0 @@ -using Stateflows.Activities.Extensions; - -namespace Stateflows.Activities.Registration.Interfaces.Base -{ - public interface IObjectFlow - { - TReturn AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction = null); - } - - public interface IElseObjectFlow - { - TReturn AddElseFlow(string targetNodeName, ElseObjectFlowBuildAction buildAction = null); - } - - public interface IDecisionFlow - { - TReturn AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction = null); - - TReturn AddFlow(ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => AddFlow(ActivityNodeInfo.Name, buildAction); - - TReturn AddFlow(string targetNodeName) - where TFlow : Flow - { - (this as IInternal).Services.RegisterObjectFlow(); - - return AddFlow( - targetNodeName, - b => b.AddObjectFlowEvents() - ); - } - - TReturn AddFlow() - where TFlow : Flow - where TTargetNode : ActivityNode - => AddFlow(ActivityNodeInfo.Name); - - TReturn AddFlow(string targetNodeName) - where TTransformationFlow : TransformationFlow - { - (this as IInternal).Services.RegisterTransformationFlow(); - - return AddFlow( - targetNodeName, - b => b.AddTransformationFlowEvents() - ); - } - - TReturn AddFlow() - where TTransformationFlow : TransformationFlow - where TTargetNode : ActivityNode - => AddFlow(ActivityNodeInfo.Name); - } - - public interface IElseDecisionFlow - { - TReturn AddElseFlow(string targetNodeName, ElseObjectFlowBuildAction buildAction = null); - - TReturn AddElseFlow(ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => AddElseFlow(ActivityNodeInfo.Name, b => buildAction?.Invoke(b as IObjectFlowBuilder)); - - //TReturn AddElseFlow(string targetNodeName) - // where TFlow : Flow - //{ - // (this as IInternal).Services.RegisterObjectFlow(); - - // return AddElseFlow( - // targetNodeName, - // b => (b as IObjectFlowBuilder).AddObjectFlowEvents() - // ); - //} - - //TReturn AddElseFlow() - // where TFlow : Flow - // where TTargetNode : ActivityNode - // => AddElseFlow(ActivityNodeInfo.Name); - - TReturn AddElseFlow(string targetNodeName) - where TElseTransformationFlow : ElseTransformationFlow - { - (this as IInternal).Services.RegisterElseTransformationFlow(); - - return AddElseFlow( - targetNodeName, - b => (b as IObjectFlowBuilder).AddElseTransformationFlowEvents() - ); - } - - TReturn AddElseFlow() - where TElseTransformationFlow : ElseTransformationFlow - where TTargetNode : ActivityNode - => AddElseFlow(ActivityNodeInfo.Name); - } - - public interface IObjectFlow - { - void AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction = null); - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Base/IObjectFlowBase.cs b/Core/Stateflows/Activities/Registration/Interfaces/Base/IObjectFlowBase.cs new file mode 100644 index 00000000..8b00ed26 --- /dev/null +++ b/Core/Stateflows/Activities/Registration/Interfaces/Base/IObjectFlowBase.cs @@ -0,0 +1,86 @@ +using Stateflows.Activities.Extensions; +using Stateflows.Common.Extensions; + +namespace Stateflows.Activities.Registration.Interfaces.Base +{ + public interface IObjectFlowBase + { + TReturn AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction = null); + } + + public interface IElseObjectFlowBase + { + TReturn AddElseFlow(string targetNodeName, ElseObjectFlowBuildAction buildAction = null); + } + + public interface IDecisionFlowBase + { + TReturn AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction = null); + + TReturn AddFlow(ObjectFlowBuildAction buildAction = null) + where TTargetNode : class, IActivityNode + => AddFlow(ActivityNode.Name, buildAction); + + TReturn AddFlow(string targetNodeName) + where TFlow : class, IBaseFlow + { + (this as IInternal).Services.AddServiceType(); + + return AddFlow( + targetNodeName, + b => b.AddObjectFlowEvents() + ); + } + + TReturn AddFlow() + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => AddFlow(ActivityNode.Name); + + TReturn AddFlow(string targetNodeName) + where TTransformationFlow : class, IFlowTransformation + { + (this as IInternal).Services.AddServiceType(); + + return AddFlow( + targetNodeName, + b => b.AddObjectTransformationFlowEvents() + ); + } + + TReturn AddFlow() + where TTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => AddFlow(ActivityNode.Name); + } + + public interface IElseDecisionFlowBase + { + TReturn AddElseFlow(string targetNodeName, ElseObjectFlowBuildAction buildAction = null); + + TReturn AddElseFlow(ObjectFlowBuildAction buildAction = null) + where TTargetNode : class, IActivityNode + => AddElseFlow(ActivityNode.Name, b => buildAction?.Invoke(b as IObjectFlowBuilder)); + + TReturn AddElseFlow(string targetNodeName) + where TElseTransformationFlow : class, IFlowTransformation + { + (this as IInternal).Services.AddServiceType(); + + return AddElseFlow( + targetNodeName, + b => (b as IObjectFlowBuilder).AddElseObjectTransformationFlowEvents() + ); + } + + TReturn AddElseFlow() + where TElseTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => AddElseFlow(ActivityNode.Name); + } + + public interface IObjectFlowBase + { + void AddFlow(string targetNodeName, ObjectFlowBuildAction buildAction = null); + } +} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Delegates.cs b/Core/Stateflows/Activities/Registration/Interfaces/Delegates.cs index 82a916ed..dc829955 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Delegates.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Delegates.cs @@ -29,6 +29,8 @@ public delegate Task PublishEventActionDelegateAsync(IActionCont public delegate Task AcceptEventActionDelegateAsync(IAcceptEventActionContext context) where TEvent : Event, new(); + public delegate Task TimeEventActionDelegateAsync(IActionContext context); + public delegate bool DecisionDelegate(IActionContext context); public delegate void ObjectFlowBuildAction(IObjectFlowBuilder builder); diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/AcceptEventActionBuilder/AcceptEventActionBuilderExceptionHandlersExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/AcceptEventActionBuilder/AcceptEventActionBuilderExceptionHandlersExtensions.cs index 07bc2609..85295084 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/AcceptEventActionBuilder/AcceptEventActionBuilderExceptionHandlersExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/AcceptEventActionBuilder/AcceptEventActionBuilderExceptionHandlersExtensions.cs @@ -1,5 +1,6 @@ using System; -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.Activities.Context.Classes; using Stateflows.Activities.Registration.Interfaces; @@ -7,11 +8,12 @@ namespace Stateflows.Activities.Typed { public static class AcceptEventActionBuilderExceptionHandlersExtensions { + [DebuggerHidden] public static IAcceptEventActionBuilder AddExceptionHandler(this IAcceptEventActionBuilder builder) where TException : Exception - where TExceptionHandler : ExceptionHandlerNode + where TExceptionHandler : class, IExceptionHandlerNode { - (builder as IInternal).Services.RegisterExceptionHandlerAction(); + (builder as IInternal).Services.AddServiceType(); return builder.AddExceptionHandler(async c => { @@ -20,7 +22,7 @@ public static IAcceptEventActionBuilder AddExceptionHandler(this IAcceptEventActionBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IAcceptEventActionBuilder AddControlFlow(this IAcceptEventActionBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow { - (builder as IInternal).Services.RegisterControlFlow(); + (builder as IInternal).Services.AddServiceType(); return builder.AddControlFlow( targetNodeName, @@ -20,9 +24,10 @@ public static IAcceptEventActionBuilder AddControlFlow(this IAccep ); } + [DebuggerHidden] public static IAcceptEventActionBuilder AddControlFlow(this IAcceptEventActionBuilder builder) - where TFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/AcceptEventActionBuilder/Flows/AcceptEventActionBuilderObjectFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/AcceptEventActionBuilder/Flows/AcceptEventActionBuilderObjectFlowsTypedExtensions.cs index d93a345d..eb30745a 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/AcceptEventActionBuilder/Flows/AcceptEventActionBuilderObjectFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/AcceptEventActionBuilder/Flows/AcceptEventActionBuilderObjectFlowsTypedExtensions.cs @@ -1,18 +1,22 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class AcceptEventActionBuilderObjectFlowsTypedExtensions { + [DebuggerHidden] public static IAcceptEventActionBuilder AddFlow(this IAcceptEventActionBuilder builder, ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IAcceptEventActionBuilder AddFlow(this IAcceptEventActionBuilder builder, string targetNodeName) - where TFlow : Flow + where TFlow : class, IBaseFlow { - (builder as IInternal).Services.RegisterObjectFlow(); + (builder as IInternal).Services.AddServiceType(); return builder.AddFlow( targetNodeName, @@ -20,25 +24,28 @@ public static IAcceptEventActionBuilder AddFlow(this IAcceptEvent ); } + [DebuggerHidden] public static IAcceptEventActionBuilder AddFlow(this IAcceptEventActionBuilder builder) - where TFlow : Flow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); + [DebuggerHidden] public static IAcceptEventActionBuilder AddFlow(this IAcceptEventActionBuilder builder, string targetNodeName) - where TTransformationFlow : TransformationFlow + where TTransformationFlow : class, IFlowTransformation { - (builder as IInternal).Services.RegisterTransformationFlow(); + (builder as IInternal).Services.AddServiceType(); return builder.AddFlow( targetNodeName, - b => b.AddTransformationFlowEvents() + b => b.AddObjectTransformationFlowEvents() ); } + [DebuggerHidden] public static IAcceptEventActionBuilder AddFlow(this IAcceptEventActionBuilder builder) - where TTransformationFlow : TransformationFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/ActionBuilderExceptionHandlersExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/ActionBuilderExceptionHandlersExtensions.cs index e53fe882..cdb4472b 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/ActionBuilderExceptionHandlersExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/ActionBuilderExceptionHandlersExtensions.cs @@ -1,5 +1,6 @@ using System; -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.Activities.Context.Classes; using Stateflows.Activities.Registration.Interfaces; @@ -7,11 +8,12 @@ namespace Stateflows.Activities.Typed { public static class ActionBuilderExceptionHandlersExtensions { + [DebuggerHidden] public static IActionBuilder AddExceptionHandler(this IActionBuilder builder) where TException : Exception - where TExceptionHandler : ExceptionHandlerNode + where TExceptionHandler : class, IExceptionHandlerNode { - (builder as IInternal).Services.RegisterExceptionHandlerAction(); + (builder as IInternal).Services.AddServiceType(); return builder.AddExceptionHandler(async c => { @@ -20,7 +22,7 @@ public static IActionBuilder AddExceptionHandler( if (handler != null) { ActivityNodeContextAccessor.Context.Value = c; - await handler?.HandleAsync(); + await handler?.HandleAsync(c.Exception, c.CancellationToken); ActivityNodeContextAccessor.Context.Value = null; } }); diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/Flows/ActionBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/Flows/ActionBuilderControlFlowsTypedExtensions.cs index 2eb88204..21c62cef 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/Flows/ActionBuilderControlFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/Flows/ActionBuilderControlFlowsTypedExtensions.cs @@ -1,18 +1,22 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class ActionBuilderControlFlowsTypedExtensions { + [DebuggerHidden] public static IActionBuilder AddControlFlow(this IActionBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IActionBuilder AddControlFlow(this IActionBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow { - (builder as IInternal).Services.RegisterControlFlow(); + (builder as IInternal).Services.AddServiceType(); return builder.AddControlFlow( targetNodeName, @@ -20,9 +24,10 @@ public static IActionBuilder AddControlFlow(this IActionBuilder bu ); } + [DebuggerHidden] public static IActionBuilder AddControlFlow(this IActionBuilder builder) - where TFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/Flows/ActionBuilderObjectFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/Flows/ActionBuilderObjectFlowsTypedExtensions.cs index 30131a1e..e69577eb 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/Flows/ActionBuilderObjectFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActionBuilder/Flows/ActionBuilderObjectFlowsTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; @@ -6,14 +7,16 @@ namespace Stateflows.Activities.Typed { public static class ActionBuilderObjectFlowsTypedExtensions { + [DebuggerHidden] public static IActionBuilder AddFlow(this IActionBuilder builder, ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IActionBuilder AddFlow(this IActionBuilder builder, string targetNodeName) - where TFlow : Flow + where TFlow : class, IBaseFlow { - (builder as IInternal).Services.RegisterObjectFlow(); + (builder as IInternal).Services.AddServiceType(); return builder.AddFlow( targetNodeName, @@ -21,25 +24,28 @@ public static IActionBuilder AddFlow(this IActionBuilder builder, ); } + [DebuggerHidden] public static IActionBuilder AddFlow(this IActionBuilder builder) - where TFlow : Flow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); - public static IActionBuilder AddFlow(this IActionBuilder builder, string targetNodeName) - where TObjectTransformationFlow : TransformationFlow + [DebuggerHidden] + public static IActionBuilder AddFlow(this IActionBuilder builder, string targetNodeName) + where TTransformationFlow : class, IFlowTransformation { - (builder as IInternal).Services.RegisterTransformationFlow(); + (builder as IInternal).Services.AddServiceType(); return builder.AddFlow( targetNodeName, - b => b.AddTransformationFlowEvents() + b => b.AddObjectTransformationFlowEvents() ); } - public static IActionBuilder AddFlow(this IActionBuilder builder) - where TObjectTransformationFlow : TransformationFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + [DebuggerHidden] + public static IActionBuilder AddFlow(this IActionBuilder builder) + where TTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderAnonymousExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderAnonymousExtensions.cs index 7927f4ae..492cc4b6 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderAnonymousExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderAnonymousExtensions.cs @@ -1,17 +1,20 @@ -using Stateflows.Common; +using System.Diagnostics; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class ActivityBuilderAnonymousExtensions { + [DebuggerHidden] public static IActivityBuilder AddStructuredActivity(this IActivityBuilder builder, ReactiveStructuredActivityBuildAction buildAction) - => builder.AddStructuredActivity(ActivityNodeInfo.Name, buildAction); + => builder.AddStructuredActivity(StructuredActivityNode.Name, buildAction); + [DebuggerHidden] public static IActivityBuilder AddParallelActivity(this IActivityBuilder builder, ParallelActivityBuildAction buildAction, int chunkSize = 1) - => builder.AddParallelActivity(ActivityNodeInfo>.Name, buildAction, chunkSize); + => builder.AddParallelActivity(ParallelActivityNode.Name, buildAction, chunkSize); + [DebuggerHidden] public static IActivityBuilder AddIterativeActivity(this IActivityBuilder builder, IterativeActivityBuildAction buildAction, int chunkSize = 1) - => builder.AddIterativeActivity(ActivityNodeInfo>.Name, buildAction, chunkSize); + => builder.AddIterativeActivity(IterativeActivityNode.Name, buildAction, chunkSize); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderPayloadExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderPayloadExtensions.cs deleted file mode 100644 index 8107b27e..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderPayloadExtensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Stateflows.Common; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities.Data -{ - public static class ActivityBuilderPayloadExtensions - { - public static IActivityBuilder AddAcceptEventAction(this IActivityBuilder builder, string actionNodeName, AcceptEventActionDelegateAsync> eventActionAsync, AcceptEventActionBuildAction buildAction = null) - => builder.AddAcceptEventAction(actionNodeName, eventActionAsync, buildAction); - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderSpecialsExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderSpecialsExtensions.cs index 4a1d8529..f0e62df9 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderSpecialsExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderSpecialsExtensions.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Diagnostics; +using System.Threading.Tasks; using Stateflows.Common; using Stateflows.Activities.Registration; using Stateflows.Activities.Registration.Builders; @@ -8,7 +9,8 @@ namespace Stateflows.Activities { public static class ActivityBuilderSpecialsExtensions { - public static IActivityBuilder AddJoin(this IActivityBuilder builder, string joinNodeName, JoinBuildAction joinBuildAction) + [DebuggerHidden] + public static IActivityBuilder AddJoin(this IActivityBuilder builder, string joinNodeName, JoinBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( NodeType.Join, @@ -18,13 +20,15 @@ public static IActivityBuilder AddJoin(this IActivityBuilder builder, string joi c.PassAllTokensOn(); return Task.CompletedTask; }, - b => joinBuildAction(b) + b => buildAction(b) ) as IActivityBuilder; - public static IActivityBuilder AddJoin(this IActivityBuilder builder, JoinBuildAction joinBuildAction) - => builder.AddJoin(ActivityNodeInfo.Name, joinBuildAction); + [DebuggerHidden] + public static IActivityBuilder AddJoin(this IActivityBuilder builder, JoinBuildAction buildAction) + => builder.AddJoin(JoinNode.Name, buildAction); - public static IActivityBuilder AddFork(this IActivityBuilder builder, string forkNodeName, ForkBuildAction forkBuildAction) + [DebuggerHidden] + public static IActivityBuilder AddFork(this IActivityBuilder builder, string forkNodeName, ForkBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( NodeType.Fork, @@ -34,13 +38,15 @@ public static IActivityBuilder AddFork(this IActivityBuilder builder, string for c.PassAllTokensOn(); return Task.CompletedTask; }, - b => forkBuildAction(b) + b => buildAction(b) ) as IActivityBuilder; - public static IActivityBuilder AddFork(this IActivityBuilder builder, ForkBuildAction forkBuildAction) - => builder.AddFork(ActivityNodeInfo.Name, forkBuildAction); + [DebuggerHidden] + public static IActivityBuilder AddFork(this IActivityBuilder builder, ForkBuildAction buildAction) + => builder.AddFork(ForkNode.Name, buildAction); - public static IActivityBuilder AddMerge(this IActivityBuilder builder, string mergeNodeName, MergeBuildAction mergeBuildAction) + [DebuggerHidden] + public static IActivityBuilder AddMerge(this IActivityBuilder builder, string mergeNodeName, MergeBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( NodeType.Merge, @@ -50,13 +56,15 @@ public static IActivityBuilder AddMerge(this IActivityBuilder builder, string me c.PassAllTokensOn(); return Task.CompletedTask; }, - b => mergeBuildAction(b.SetOptions(NodeOptions.None) as IMergeBuilder) + b => buildAction(b.SetOptions(NodeOptions.None) as IMergeBuilder) ) as IActivityBuilder; - public static IActivityBuilder AddMerge(this IActivityBuilder builder, MergeBuildAction mergeBuildAction) - => builder.AddMerge(ActivityNodeInfo.Name, mergeBuildAction); + [DebuggerHidden] + public static IActivityBuilder AddMerge(this IActivityBuilder builder, MergeBuildAction buildAction) + => builder.AddMerge(MergeNode.Name, buildAction); - public static IActivityBuilder AddControlDecision(this IActivityBuilder builder, string decisionNodeName, DecisionBuildAction decisionBuildAction) + [DebuggerHidden] + public static IActivityBuilder AddControlDecision(this IActivityBuilder builder, string decisionNodeName, DecisionBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( NodeType.Decision, @@ -66,12 +74,14 @@ public static IActivityBuilder AddControlDecision(this IActivityBuilder builder, c.PassAllTokensOn(); return Task.CompletedTask; }, - b => decisionBuildAction(b.SetOptions(NodeOptions.DecisionDefault) as IDecisionBuilder) + b => buildAction(b.SetOptions(NodeOptions.DecisionDefault) as IDecisionBuilder) ) as IActivityBuilder; - public static IActivityBuilder AddControlDecision(this IActivityBuilder builder, DecisionBuildAction decisionBuildAction) - => builder.AddControlDecision(ActivityNodeInfo.Name, decisionBuildAction); + [DebuggerHidden] + public static IActivityBuilder AddControlDecision(this IActivityBuilder builder, DecisionBuildAction buildAction) + => builder.AddControlDecision(ControlDecisionNode.Name, buildAction); + [DebuggerHidden] public static IActivityBuilder AddDecision(this IActivityBuilder builder, string decisionNodeName, DecisionBuildAction decisionBuildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -85,10 +95,12 @@ public static IActivityBuilder AddDecision(this IActivityBuilder builder b => decisionBuildAction(new DecisionBuilder(b.SetOptions(NodeOptions.DecisionDefault) as NodeBuilder)) ) as IActivityBuilder; - public static IActivityBuilder AddDecision(this IActivityBuilder builder, DecisionBuildAction decisionBuildAction) - => builder.AddDecision(ActivityNodeInfo>.Name, decisionBuildAction); + [DebuggerHidden] + public static IActivityBuilder AddDecision(this IActivityBuilder builder, DecisionBuildAction buildAction) + => builder.AddDecision(DecisionNode.Name, buildAction); - public static IActivityBuilder AddDataStore(this IActivityBuilder builder, string dataStoreNodeName, DataStoreBuildAction decisionBuildAction) + [DebuggerHidden] + public static IActivityBuilder AddDataStore(this IActivityBuilder builder, string dataStoreNodeName, DataStoreBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( NodeType.DataStore, @@ -98,39 +110,50 @@ public static IActivityBuilder AddDataStore(this IActivityBuilder builder, strin c.PassAllTokensOn(); return Task.CompletedTask; }, - b => decisionBuildAction(b.SetOptions(NodeOptions.DataStoreDefault) as IDataStoreBuilder) + b => buildAction(b.SetOptions(NodeOptions.DataStoreDefault) as IDataStoreBuilder) ) as IActivityBuilder; + [DebuggerHidden] + public static IActivityBuilder AddDataStore(this IActivityBuilder builder, DataStoreBuildAction buildAction) + => builder.AddDataStore(DataStoreNode.Name, buildAction); + #region AddAcceptEventAction + [DebuggerHidden] public static IActivityBuilder AddAcceptEventAction(this IActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction) where TEvent : Event, new() => builder.AddAcceptEventAction(actionNodeName, c => Task.CompletedTask, buildAction); + [DebuggerHidden] public static IActivityBuilder AddAcceptEventAction(this IActivityBuilder builder, AcceptEventActionBuildAction buildAction) where TEvent : Event, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => Task.CompletedTask, buildAction); + => builder.AddAcceptEventAction(AcceptEventActionNode.Name, c => Task.CompletedTask, buildAction); - public static IActivityBuilder AddAcceptEventAction(this IActivityBuilder builder, ActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) + [DebuggerHidden] + public static IActivityBuilder AddAcceptEventAction(this IActivityBuilder builder, AcceptEventActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) where TEvent : Event, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => actionAsync(c), buildAction); + => builder.AddAcceptEventAction(AcceptEventActionNode.Name, actionAsync, buildAction); #endregion #region AddTimeEventAction + [DebuggerHidden] public static IActivityBuilder AddTimeEventAction(this IActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction) where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(actionNodeName, c => Task.CompletedTask, buildAction); + => builder.AddTimeEventAction(actionNodeName, c => Task.CompletedTask, buildAction); + [DebuggerHidden] public static IActivityBuilder AddTimeEventAction(this IActivityBuilder builder, string actionNodeName, ActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(actionNodeName, c => actionAsync(c), buildAction); + => builder.AddTimeEventAction(actionNodeName, c => actionAsync(c), buildAction); + [DebuggerHidden] public static IActivityBuilder AddTimeEventAction(this IActivityBuilder builder, ActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => actionAsync(c), buildAction); + => builder.AddTimeEventAction(TimeEventActionNode.Name, c => actionAsync(c), buildAction); + [DebuggerHidden] public static IActivityBuilder AddTimeEventAction(this IActivityBuilder builder, AcceptEventActionBuildAction buildAction) where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => Task.CompletedTask, buildAction); + => builder.AddTimeEventAction(TimeEventActionNode.Name, c => Task.CompletedTask, buildAction); #endregion } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderTypedExtensions.cs index 4000c2ed..8ac68388 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderTypedExtensions.cs @@ -1,6 +1,8 @@ using System; +using System.Diagnostics; using System.Threading.Tasks; using Stateflows.Common; +using Stateflows.Common.Extensions; using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration; using Stateflows.Activities.Context.Classes; @@ -13,14 +15,16 @@ namespace Stateflows.Activities.Typed public static class ActivityBuilderTypedExtensions { #region AddAction + [DebuggerHidden] public static IActivityBuilder AddAction(this IActivityBuilder builder, TypedActionBuildAction buildAction = null) - where TAction : ActionNode - => AddAction(builder, ActivityNodeInfo.Name, buildAction); + where TAction : class, IActionNode + => AddAction(builder, ActivityNode.Name, buildAction); + [DebuggerHidden] public static IActivityBuilder AddAction(this IActivityBuilder builder, string actionNodeName, TypedActionBuildAction buildAction = null) - where TAction : ActionNode + where TAction : class, IActionNode { - (builder as IInternal).Services.RegisterAction(); + (builder as IInternal).Services.AddServiceType(); return builder.AddAction( actionNodeName, @@ -28,11 +32,11 @@ public static IActivityBuilder AddAction(this IActivityBuilder builder, { var action = (c as BaseContext).NodeScope.GetAction(c); - InputTokensHolder.Tokens.Value = ((ActionContext)c).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)c).OutputTokens; + InputTokens.TokensHolder.Value = ((ActionContext)c).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)c).OutputTokens; ActivityNodeContextAccessor.Context.Value = c; - var result = action.ExecuteAsync(); + var result = action.ExecuteAsync(c.CancellationToken); ActivityNodeContextAccessor.Context.Value = null; return result; @@ -47,54 +51,74 @@ public static IActivityBuilder AddAction(this IActivityBuilder builder, #endregion #region AddAcceptEventAction + [DebuggerHidden] public static IActivityBuilder AddAcceptEventAction(this IActivityBuilder builder, AcceptEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TAcceptEventAction : AcceptEventActionNode - => builder.AddAcceptEventAction(ActivityNodeInfo.Name, buildAction); + where TAcceptEventAction : class, IAcceptEventActionNode + => builder.AddAcceptEventAction(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IActivityBuilder AddAcceptEventAction(this IActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TAcceptEventAction : AcceptEventActionNode + where TAcceptEventAction : class, IAcceptEventActionNode => builder.AddAcceptEventAction( actionNodeName, - (AcceptEventActionDelegateAsync)(c => + c => { var action = (c as BaseContext).NodeScope.GetAcceptEventAction(c); - InputTokensHolder.Tokens.Value = ((ActionContext)c).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)c).OutputTokens; + InputTokens.TokensHolder.Value = ((ActionContext)c).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)c).OutputTokens; ActivityNodeContextAccessor.Context.Value = c; - var result = action.ExecuteAsync(); + var result = action.ExecuteAsync(c.Event, c.CancellationToken); ActivityNodeContextAccessor.Context.Value = null; return result; - }), + }, buildAction ); #endregion #region AddTimeEventAction + [DebuggerHidden] public static IActivityBuilder AddTimeEventAction(this IActivityBuilder builder, AcceptEventActionBuildAction buildAction = null) where TTimeEvent : TimeEvent, new() - where TTimeEventAction : AcceptEventActionNode - => builder.AddAcceptEventAction(buildAction); + where TTimeEventAction : class, ITimeEventActionNode + => builder.AddTimeEventAction(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IActivityBuilder AddTimeEventAction(this IActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction = null) where TTimeEvent : TimeEvent, new() - where TTimeEventAction : AcceptEventActionNode - => builder.AddAcceptEventAction(actionNodeName, buildAction); + where TTimeEventAction : class, ITimeEventActionNode + => builder.AddTimeEventAction( + actionNodeName, + c => + { + var action = (c as BaseContext).NodeScope.GetTimeEventAction(c); + + InputTokens.TokensHolder.Value = ((ActionContext)c).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)c).OutputTokens; + + ActivityNodeContextAccessor.Context.Value = c; + var result = action.ExecuteAsync(c.CancellationToken); + ActivityNodeContextAccessor.Context.Value = null; + + return result; + }, + buildAction + ); #endregion #region AddSendEventAction private static async Task GetSendEventAction(this IActionContext context, Func> callback) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode + where TSendEventAction : class, ISendEventActionNode { var action = (context as BaseContext).NodeScope.GetSendEventAction(context); - InputTokensHolder.Tokens.Value = ((ActionContext)context).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)context).OutputTokens; + InputTokens.TokensHolder.Value = ((ActionContext)context).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)context).OutputTokens; ActivityNodeContextAccessor.Context.Value = context; var result = await callback(action); @@ -103,14 +127,16 @@ private static async Task GetSendEventAction(this IActivityBuilder builder, SendEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode - => builder.AddSendEventAction(ActivityNodeInfo.Name, buildAction); + where TSendEventAction : class, ISendEventActionNode + => builder.AddSendEventAction(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IActivityBuilder AddSendEventAction(this IActivityBuilder builder, string actionNodeName, SendEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode + where TSendEventAction : class, ISendEventActionNode { return builder.AddSendEventAction( actionNodeName, @@ -122,14 +148,16 @@ public static IActivityBuilder AddSendEventAction(this #endregion #region AddStructuredActivity - public static IActivityBuilder AddStructuredActivity(this IActivityBuilder builder, ReactiveStructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode - => AddStructuredActivity(builder, ActivityNodeInfo.Name, buildAction); + [DebuggerHidden] + public static IActivityBuilder AddStructuredActivity(this IActivityBuilder builder, ReactiveStructuredActivityBuildAction buildAction) + where TStructuredActivity : class, IBaseStructuredActivityNode + => AddStructuredActivity(builder, ActivityNode.Name, buildAction); + [DebuggerHidden] public static IActivityBuilder AddStructuredActivity(this IActivityBuilder builder, string structuredActivityName, ReactiveStructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode + where TStructuredActivity : class, IBaseStructuredActivityNode { - (builder as IInternal).Services.RegisterStructuredActivity(); + (builder as IInternal).Services.AddServiceType(); return builder.AddStructuredActivity( structuredActivityName, @@ -145,37 +173,42 @@ public static IActivityBuilder AddStructuredActivity(this I #endregion #region AddParallelActivity - public static IActivityBuilder AddParallelActivity(this IActivityBuilder builder, ParallelActivityBuildAction buildAction = null) - where TStructuredActivity : ParallelActivityNode - => AddParallelActivity(builder, ActivityNodeInfo.Name, buildAction); - - public static IActivityBuilder AddParallelActivity(this IActivityBuilder builder, string structuredActivityName, ParallelActivityBuildAction buildAction = null) - where TStructuredActivity : ParallelActivityNode + [DebuggerHidden] + public static IActivityBuilder AddParallelActivity(this IActivityBuilder builder, ParallelActivityBuildAction buildAction = null, int chunkSize = 1) + where TStructuredActivity : class, IBaseStructuredActivityNode + => AddParallelActivity(builder, ActivityNode.Name, buildAction, chunkSize); + + [DebuggerHidden] + public static IActivityBuilder AddParallelActivity(this IActivityBuilder builder, string structuredActivityName, ParallelActivityBuildAction buildAction = null, int chunkSize = 1) + where TParallelActivity : class, IBaseStructuredActivityNode { - (builder as IInternal).Services.RegisterStructuredActivity(); + (builder as IInternal).Services.AddServiceType(); return builder.AddParallelActivity( structuredActivityName, b => { var builder = b as StructuredActivityBuilder; - builder.AddStructuredActivityEvents(); - builder.Node.ScanForDeclaredTypes(typeof(TStructuredActivity)); + builder.AddStructuredActivityEvents(); + builder.Node.ScanForDeclaredTypes(typeof(TParallelActivity)); buildAction?.Invoke(b); - } + }, + chunkSize ); } #endregion #region AddIterativeActivity + [DebuggerHidden] public static IActivityBuilder AddIterativeActivity(this IActivityBuilder builder, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) - where TStructuredActivity : IterativeActivityNode - => AddIterativeActivity(builder, ActivityNodeInfo.Name, buildAction, chunkSize); + where TStructuredActivity : class, IBaseStructuredActivityNode + => AddIterativeActivity(builder, ActivityNode.Name, buildAction, chunkSize); + [DebuggerHidden] public static IActivityBuilder AddIterativeActivity(this IActivityBuilder builder, string structuredActivityName, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) - where TStructuredActivity : IterativeActivityNode + where TStructuredActivity : class, IBaseStructuredActivityNode { - (builder as IInternal).Services.RegisterStructuredActivity(); + (builder as IInternal).Services.AddServiceType(); return builder.AddIterativeActivity( structuredActivityName, b => diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderTypedPayloadExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderTypedPayloadExtensions.cs deleted file mode 100644 index 04c109c4..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ActivityBuilder/ActivityBuilderTypedPayloadExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Stateflows.Common; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities.Typed.Data -{ - public static class ActivityBuilderTypedPayloadExtensions - { - #region AddAcceptEventAction - public static IActivityBuilder AddAcceptEventAction(this IActivityBuilder builder, AcceptEventActionBuildAction buildAction = null) - where TAcceptEventAction : AcceptEventActionNode> - => builder.AddAcceptEventAction(ActivityNodeInfo.Name, buildAction); - - public static IActivityBuilder AddAcceptEventAction(this IActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction = null) - where TAcceptEventAction : AcceptEventActionNode> - => builder.AddAcceptEventAction, TAcceptEventAction>(actionNodeName, buildAction); - #endregion - - #region AddSendEventAction - public static IActivityBuilder AddSendEventAction(this IActivityBuilder builder, SendEventActionBuildAction buildAction = null) - where TSendEventAction : SendEventActionNode> - => builder.AddSendEventAction(ActivityNodeInfo.Name, buildAction); - - public static IActivityBuilder AddSendEventAction(this IActivityBuilder builder, string actionNodeName, SendEventActionBuildAction buildAction = null) - where TSendEventAction : SendEventActionNode> - => builder.AddSendEventAction, TSendEventAction>(actionNodeName, buildAction); - #endregion - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DataStoreBuilder/Flows/DataStoreBuilderFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DataStoreBuilder/Flows/DataStoreBuilderFlowsTypedExtensions.cs index cc070777..6c09eb90 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DataStoreBuilder/Flows/DataStoreBuilderFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DataStoreBuilder/Flows/DataStoreBuilderFlowsTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; @@ -6,38 +7,43 @@ namespace Stateflows.Activities.Typed { public static class DataStoreBuilderFlowsTypedExtensions { - public static void AddFlow(this IDataStoreBuilder builder, ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + [DebuggerHidden] + public static IDataStoreBuilder AddFlow(this IDataStoreBuilder builder, ObjectFlowBuildAction buildAction = null) + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); - public static void AddFlow(this IDataStoreBuilder builder, string targetNodeName) - where TFlow : Flow + [DebuggerHidden] + public static IDataStoreBuilder AddFlow(this IDataStoreBuilder builder, string targetNodeName) + where TFlow : class, IBaseFlow { - (builder as IInternal).Services.RegisterObjectFlow(); - builder.AddFlow( + (builder as IInternal).Services.AddServiceType(); + return builder.AddFlow( targetNodeName, b => b.AddObjectFlowEvents() ); } - public static void AddFlow(this IDataStoreBuilder builder) - where TFlow : Flow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + [DebuggerHidden] + public static IDataStoreBuilder AddFlow(this IDataStoreBuilder builder) + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); - public static void AddFlow(this IDataStoreBuilder builder, string targetNodeName) - where TObjectTransformationFlow : TransformationFlow + [DebuggerHidden] + public static IDataStoreBuilder AddFlow(this IDataStoreBuilder builder, string targetNodeName) + where TTransformationFlow : class, IFlowTransformation { - (builder as IInternal).Services.RegisterTransformationFlow(); - builder.AddFlow( + (builder as IInternal).Services.AddServiceType(); + return builder.AddFlow( targetNodeName, - b => b.AddTransformationFlowEvents() + b => b.AddObjectTransformationFlowEvents() ); } - public static void AddFlow(this IDataStoreBuilder builder) - where TObjectTransformationFlow : TransformationFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + [DebuggerHidden] + public static IDataStoreBuilder AddFlow(this IDataStoreBuilder builder) + where TTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/ElseFlows/DecisionBuilderElseControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/ElseFlows/DecisionBuilderElseControlFlowsTypedExtensions.cs index cb18e2b5..a17f4a6e 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/ElseFlows/DecisionBuilderElseControlFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/ElseFlows/DecisionBuilderElseControlFlowsTypedExtensions.cs @@ -1,28 +1,13 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class DecisionBuilderElseControlFlowsTypedExtensions { - public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddElseFlow(ActivityNodeInfo.Name, b => buildAction?.Invoke(b as IControlFlowBuilder)); - - public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow - { - (builder as IInternal).Services.RegisterControlFlow(); - - return builder.AddElseFlow( - targetNodeName, - b => (b as IControlFlowBuilder).AddControlFlowEvents() - ); - } - - public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder) - where TFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddElseFlow(ActivityNodeInfo.Name); + [DebuggerHidden] + public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder, ElseControlFlowBuildAction buildAction = null) + where TTargetNode : class, IActivityNode + => builder.AddElseFlow(ActivityNode.Name, b => buildAction?.Invoke(b)); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/ElseFlows/DecisionBuilderElseObjectFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/ElseFlows/DecisionBuilderElseObjectFlowsTypedExtensions.cs index fdbeef28..cf753283 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/ElseFlows/DecisionBuilderElseObjectFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/ElseFlows/DecisionBuilderElseObjectFlowsTypedExtensions.cs @@ -1,44 +1,33 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class DecisionBuilderElseObjectFlowsTypedExtensions { - // public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder, ObjectFlowBuildAction buildAction = null) - // where TTargetNode : ActivityNode - // => builder.AddElseFlow(ActivityNodeInfo.Name, b => buildAction?.Invoke(b as IObjectFlowBuilder)); + [DebuggerHidden] + public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder, ObjectFlowBuildAction buildAction = null) + where TTargetNode : class, IActivityNode + => builder.AddElseFlow(ActivityNode.Name, b => buildAction?.Invoke(b as IObjectFlowBuilder)); - // public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder, string targetNodeName) - // where TFlow : Flow - // { - // (builder as IInternal).Services.RegisterObjectFlow(); + [DebuggerHidden] + public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder, string targetNodeName) + where TTransformationFlow : class, IFlowTransformation + { + (builder as IInternal).Services.AddServiceType(); - // return builder.AddElseFlow( - // targetNodeName, - // b => (b as IObjectFlowBuilder).AddObjectFlowEvents() - // ); - // } + return builder.AddElseFlow( + targetNodeName, + b => (b as IObjectFlowBuilder).AddObjectTransformationFlowEvents() + ); + } - // public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder) - // where TFlow : Flow - // where TTargetNode : ActivityNode - // => builder.AddElseFlow(ActivityNodeInfo.Name); - - // public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder, string targetNodeName) - // where TObjectTransformationFlow : TransformationFlow - // { - // (builder as IInternal).Services.RegisterObjectTransformationFlow(); - - // return builder.AddElseFlow( - // targetNodeName, - // b => (b as IObjectFlowBuilder).AddObjectTransformationFlowEvents() - // ); - // } - - // public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder) - // where TObjectTransformationFlow : TransformationFlow - // where TTargetNode : ActivityNode - // => builder.AddElseFlow(ActivityNodeInfo.Name); + [DebuggerHidden] + public static IDecisionBuilder AddElseFlow(this IDecisionBuilder builder) + where TTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddElseFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/Flows/DecisionBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/Flows/DecisionBuilderControlFlowsTypedExtensions.cs index 3ed66d69..09e298ff 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/Flows/DecisionBuilderControlFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/Flows/DecisionBuilderControlFlowsTypedExtensions.cs @@ -1,18 +1,22 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class DecisionBuilderControlFlowsTypedExtensions { - public static IDecisionBuilder AddFlow(this IDecisionBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + [DebuggerHidden] + public static IDecisionBuilder AddFlow(this IDecisionBuilder builder, ControlFlowBuildAction buildAction) + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IDecisionBuilder AddFlow(this IDecisionBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow { - (builder as IInternal).Services.RegisterControlFlow(); + (builder as IInternal).Services.AddServiceType(); return builder.AddFlow( targetNodeName, @@ -20,9 +24,10 @@ public static IDecisionBuilder AddFlow(this IDecisionBuilder build ); } + [DebuggerHidden] public static IDecisionBuilder AddFlow(this IDecisionBuilder builder) - where TFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/Flows/DecisionBuilderObjectFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/Flows/DecisionBuilderObjectFlowsTypedExtensions.cs index c1910902..6bacd276 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/Flows/DecisionBuilderObjectFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/DecisionBuilder/Flows/DecisionBuilderObjectFlowsTypedExtensions.cs @@ -1,44 +1,51 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class DecisionBuilderObjectFlowsTypedExtensions { - //public static IDecisionBuilder AddFlow(this IDecisionBuilder builder, ObjectFlowBuildAction buildAction = null) - // where TTargetNode : ActivityNode - // => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + [DebuggerHidden] + public static IDecisionBuilder AddFlow(this IDecisionBuilder builder, ObjectFlowBuildAction buildAction = null) + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); - //public static IDecisionBuilder AddFlow(this IDecisionBuilder builder, string targetNodeName) - // where TFlow : Flow - //{ - // (builder as IInternal).Services.RegisterObjectFlow(); + [DebuggerHidden] + public static IDecisionBuilder AddFlow(this IDecisionBuilder builder, string targetNodeName) + where TFlow : class, IBaseFlow + { + (builder as IInternal).Services.AddServiceType(); - // return builder.AddFlow( - // targetNodeName, - // b => b.AddObjectFlowEvents() - // ); - //} + return builder.AddFlow( + targetNodeName, + b => b.AddObjectFlowEvents() + ); + } - //public static IDecisionBuilder AddFlow(this IDecisionBuilder builder) - // where TFlow : Flow - // where TTargetNode : ActivityNode - // => builder.AddFlow(ActivityNodeInfo.Name); + [DebuggerHidden] + public static IDecisionBuilder AddFlow(this IDecisionBuilder builder) + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); - //public static IDecisionBuilder AddFlow(this IDecisionBuilder builder, string targetNodeName) - // where TObjectTransformationFlow : TransformationFlow - //{ - // (builder as IInternal).Services.RegisterObjectTransformationFlow(); + [DebuggerHidden] + public static IDecisionBuilder AddFlow(this IDecisionBuilder builder, string targetNodeName) + where TTransformationFlow : class, IFlowTransformation + { + (builder as IInternal).Services.AddServiceType(); - // return builder.AddFlow( - // targetNodeName, - // b => b.AddObjectTransformationFlowEvents() - // ); - //} + return builder.AddFlow( + targetNodeName, + b => b.AddObjectTransformationFlowEvents() + ); + } - //public static IDecisionBuilder AddFlow(this IDecisionBuilder builder) - // where TObjectTransformationFlow : TransformationFlow - // where TTargetNode : ActivityNode - // => builder.AddFlow(ActivityNodeInfo.Name); + [DebuggerHidden] + public static IDecisionBuilder AddFlow(this IDecisionBuilder builder) + where TTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ForkBuilder/Flows/ForkBuilderFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ForkBuilder/Flows/ForkBuilderFlowsTypedExtensions.cs new file mode 100644 index 00000000..06c09428 --- /dev/null +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ForkBuilder/Flows/ForkBuilderFlowsTypedExtensions.cs @@ -0,0 +1,49 @@ +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; +using Stateflows.Activities.Registration.Interfaces; + +namespace Stateflows.Activities.Typed +{ + public static class ForkBuilderFlowsTypedExtensions + { + [DebuggerHidden] + public static IForkBuilder AddFlow(this IForkBuilder builder, ObjectFlowBuildAction buildAction = null) + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + + [DebuggerHidden] + public static IForkBuilder AddFlow(this IForkBuilder builder, string targetNodeName) + where TFlow : class, IBaseFlow + { + (builder as IInternal).Services.AddServiceType(); + return builder.AddFlow( + targetNodeName, + b => b.AddObjectFlowEvents() + ); + } + + [DebuggerHidden] + public static IForkBuilder AddFlow(this IForkBuilder builder) + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); + + [DebuggerHidden] + public static IForkBuilder AddFlow(this IForkBuilder builder, string targetNodeName) + where TTransformationFlow : class, IFlowTransformation + { + (builder as IInternal).Services.AddServiceType(); + return builder.AddFlow( + targetNodeName, + b => b.AddObjectTransformationFlowEvents() + ); + } + + [DebuggerHidden] + public static IForkBuilder AddFlow(this IForkBuilder builder) + where TTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); + } +} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InitialBuilder/Flows/InitialBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InitialBuilder/Flows/InitialBuilderControlFlowsTypedExtensions.cs index 0875dd65..3fc73f41 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InitialBuilder/Flows/InitialBuilderControlFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InitialBuilder/Flows/InitialBuilderControlFlowsTypedExtensions.cs @@ -1,18 +1,22 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class InitialBuilderControlFlowsTypedExtensions { + [DebuggerHidden] public static IInitialBuilder AddControlFlow(this IInitialBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IInitialBuilder AddControlFlow(this IInitialBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow { - (builder as IInternal).Services.RegisterControlFlow(); + (builder as IInternal).Services.AddServiceType(); return builder.AddControlFlow( targetNodeName, @@ -20,9 +24,10 @@ public static IInitialBuilder AddControlFlow(this IInitialBuilder ); } + [DebuggerHidden] public static IInitialBuilder AddControlFlow(this IInitialBuilder builder) - where TFlow : ControlFlow - where TTargetNode : ActivityNode - => AddControlFlow(builder, ActivityNodeInfo.Name); + where TFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => AddControlFlow(builder, ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InputBuilder/Flows/InputBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InputBuilder/Flows/InputBuilderControlFlowsTypedExtensions.cs deleted file mode 100644 index 8fa0374b..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InputBuilder/Flows/InputBuilderControlFlowsTypedExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities.Typed -{ - public static class InputBuilderControlFlowsTypedExtensions - { - public static IInputBuilder AddControlFlow(this IInputBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow - => (builder as IActionBuilder).AddControlFlow(targetNodeName) as IInputBuilder; - - public static IInputBuilder AddControlFlow(this IInputBuilder builder) - where TControlFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name); - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InputBuilder/Flows/InputBuilderFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InputBuilder/Flows/InputBuilderFlowsTypedExtensions.cs index 7cfb46e4..c3cca673 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InputBuilder/Flows/InputBuilderFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/InputBuilder/Flows/InputBuilderFlowsTypedExtensions.cs @@ -1,29 +1,35 @@ -using Stateflows.Activities.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class InputBuilderFlowsTypedExtensions { + [DebuggerHidden] public static IInputBuilder AddFlow(this IInputBuilder builder, ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IInputBuilder AddFlow(this IInputBuilder builder, string targetNodeName) - where TFlow : Flow + where TFlow : class, IBaseFlow => (builder as IActionBuilder).AddFlow(targetNodeName) as IInputBuilder; + [DebuggerHidden] public static IInputBuilder AddFlow(this IInputBuilder builder) - where TFlow : Flow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); + [DebuggerHidden] public static IInputBuilder AddFlow(this IInputBuilder builder, string targetNodeName) - where TFlow : TransformationFlow + where TFlow : class, IFlowTransformation => (builder as IActionBuilder).AddFlow(targetNodeName) as IInputBuilder; + [DebuggerHidden] public static IInputBuilder AddFlow(this IInputBuilder builder) - where TFlow : TransformationFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/JoinBuilder/Flows/JoinBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/JoinBuilder/Flows/JoinBuilderControlFlowsTypedExtensions.cs index 981f94c0..0127233a 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/JoinBuilder/Flows/JoinBuilderControlFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/JoinBuilder/Flows/JoinBuilderControlFlowsTypedExtensions.cs @@ -1,18 +1,22 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class JoinBuilderControlFlowsTypedExtensions { + [DebuggerHidden] public static void AddControlFlow(this IJoinBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static void AddControlFlow(this IJoinBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow { - (builder as IInternal).Services.RegisterControlFlow(); + (builder as IInternal).Services.AddServiceType(); builder.AddControlFlow( targetNodeName, @@ -20,9 +24,10 @@ public static void AddControlFlow(this IJoinBuilder builder, strin ); } + [DebuggerHidden] public static void AddControlFlow(this IJoinBuilder builder) - where TFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/JoinBuilder/Flows/JoinBuilderFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/JoinBuilder/Flows/JoinBuilderFlowsTypedExtensions.cs index 97c80334..d3ea6720 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/JoinBuilder/Flows/JoinBuilderFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/JoinBuilder/Flows/JoinBuilderFlowsTypedExtensions.cs @@ -1,42 +1,49 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class JoinBuilderFlowsTypedExtensions { + [DebuggerHidden] public static void AddFlow(this IJoinBuilder builder, ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static void AddFlow(this IJoinBuilder builder, string targetNodeName) - where TFlow : Flow + where TFlow : class, IBaseFlow { - (builder as IInternal).Services.RegisterObjectFlow(); + (builder as IInternal).Services.AddServiceType(); builder.AddFlow( targetNodeName, b => b.AddObjectFlowEvents() ); } + [DebuggerHidden] public static void AddFlow(this IJoinBuilder builder) - where TFlow : Flow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); - public static void AddFlow(this IJoinBuilder builder, string targetNodeName) - where TObjectTransformationFlow : TransformationFlow + [DebuggerHidden] + public static void AddFlow(this IJoinBuilder builder, string targetNodeName) + where TTransformationFlow : class, IFlowTransformation { - (builder as IInternal).Services.RegisterTransformationFlow(); + (builder as IInternal).Services.AddServiceType(); builder.AddFlow( targetNodeName, - b => b.AddTransformationFlowEvents() + b => b.AddObjectTransformationFlowEvents() ); } - public static void AddFlow(this IJoinBuilder builder) - where TObjectTransformationFlow : TransformationFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + [DebuggerHidden] + public static void AddFlow(this IJoinBuilder builder) + where TTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/MergeBuilder/Flows/MergeBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/MergeBuilder/Flows/MergeBuilderControlFlowsTypedExtensions.cs index 08fb9015..53b0b25d 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/MergeBuilder/Flows/MergeBuilderControlFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/MergeBuilder/Flows/MergeBuilderControlFlowsTypedExtensions.cs @@ -1,18 +1,22 @@ -using Stateflows.Activities.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class MergeBuilderControlFlowsTypedExtensions { + [DebuggerHidden] public static void AddControlFlow(this IMergeBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static void AddControlFlow(this IMergeBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow { - (builder as IInternal).Services.RegisterControlFlow(); + (builder as IInternal).Services.AddServiceType(); builder.AddControlFlow( targetNodeName, @@ -20,9 +24,10 @@ public static void AddControlFlow(this IMergeBuilder builder, stri ); } + [DebuggerHidden] public static void AddControlFlow(this IMergeBuilder builder) - where TFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/MergeBuilder/Flows/MergeBuilderObjectFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/MergeBuilder/Flows/MergeBuilderObjectFlowsTypedExtensions.cs index 6b0988b7..facecaee 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/MergeBuilder/Flows/MergeBuilderObjectFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/MergeBuilder/Flows/MergeBuilderObjectFlowsTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration.Interfaces; @@ -6,38 +7,43 @@ namespace Stateflows.Activities.Typed { public static class MergeBuilderObjectFlowsTypedExtensions { + [DebuggerHidden] public static void AddFlow(this IMergeBuilder builder, ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static void AddFlow(this IMergeBuilder builder, string targetNodeName) - where TFlow : Flow + where TFlow : class, IBaseFlow { - (builder as IInternal).Services.RegisterObjectFlow(); + (builder as IInternal).Services.AddServiceType(); builder.AddFlow( targetNodeName, b => b.AddObjectFlowEvents() ); } + [DebuggerHidden] public static void AddFlow(this IMergeBuilder builder) - where TFlow : Flow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); - public static void AddFlow(this IMergeBuilder builder, string targetNodeName) - where TObjectTransformationFlow : TransformationFlow + [DebuggerHidden] + public static void AddFlow(this IMergeBuilder builder, string targetNodeName) + where TTransformationFlow : class, IFlowTransformation { - (builder as IInternal).Services.RegisterTransformationFlow(); + (builder as IInternal).Services.AddServiceType(); builder.AddFlow( targetNodeName, - b => b.AddTransformationFlowEvents() + b => b.AddObjectTransformationFlowEvents() ); } - public static void AddFlow(this IMergeBuilder builder) - where TObjectTransformationFlow : TransformationFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + [DebuggerHidden] + public static void AddFlow(this IMergeBuilder builder) + where TTransformationFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/Flows/ReactiveStructuredActivityBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/Flows/ReactiveStructuredActivityBuilderControlFlowsTypedExtensions.cs index 8fa4a42f..091dec5f 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/Flows/ReactiveStructuredActivityBuilderControlFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/Flows/ReactiveStructuredActivityBuilderControlFlowsTypedExtensions.cs @@ -1,20 +1,24 @@ -using Stateflows.Activities.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class ReactiveStructuredActivityBuilderControlFlowsTypedExtensions { + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddControlFlow(this IReactiveStructuredActivityBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddControlFlow(this IReactiveStructuredActivityBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow => (builder as IActionBuilder).AddControlFlow(targetNodeName) as IReactiveStructuredActivityBuilder; + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddControlFlow(this IReactiveStructuredActivityBuilder builder) - where TControlFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name); + where TControlFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/Flows/ReactiveStructuredActivityBuilderFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/Flows/ReactiveStructuredActivityBuilderFlowsTypedExtensions.cs index c63e7244..3c0694e9 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/Flows/ReactiveStructuredActivityBuilderFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/Flows/ReactiveStructuredActivityBuilderFlowsTypedExtensions.cs @@ -1,29 +1,35 @@ -using Stateflows.Activities.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class ReactiveStructuredActivityBuilderFlowsTypedExtensions { + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddFlow(this IReactiveStructuredActivityBuilder builder, ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddFlow(this IReactiveStructuredActivityBuilder builder, string targetNodeName) - where TFlow : Flow + where TFlow : class, IBaseFlow => (builder as IActionBuilder).AddFlow(targetNodeName) as IReactiveStructuredActivityBuilder; + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddFlow(this IReactiveStructuredActivityBuilder builder) - where TFlow : Flow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddFlow(this IReactiveStructuredActivityBuilder builder, string targetNodeName) - where TFlow : TransformationFlow + where TFlow : class, IFlowTransformation => (builder as IActionBuilder).AddFlow(targetNodeName) as IReactiveStructuredActivityBuilder; + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddFlow(this IReactiveStructuredActivityBuilder builder) - where TFlow : TransformationFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderAnonymousExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderAnonymousExtensions.cs index c13480f7..81231b03 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderAnonymousExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderAnonymousExtensions.cs @@ -1,16 +1,20 @@ -using Stateflows.Activities.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class ReactiveStructuredActivityBuilderAnonymousExtensions { + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddStructuredActivity(this IReactiveStructuredActivityBuilder builder, ReactiveStructuredActivityBuildAction buildAction) - => builder.AddStructuredActivity(ActivityNodeInfo.Name, buildAction); + => builder.AddStructuredActivity(StructuredActivityNode.Name, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddParallelActivity(this IReactiveStructuredActivityBuilder builder, ParallelActivityBuildAction buildAction, int chunkSize = 1) - => builder.AddParallelActivity(ActivityNodeInfo>.Name, buildAction, chunkSize); + => builder.AddParallelActivity(ParallelActivityNode.Name, buildAction, chunkSize); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddIterativeActivity(this IReactiveStructuredActivityBuilder builder, IterativeActivityBuildAction buildAction, int chunkSize = 1) - => builder.AddIterativeActivity(ActivityNodeInfo>.Name, buildAction, chunkSize); + => builder.AddIterativeActivity(IterativeActivityNode.Name, buildAction, chunkSize); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderExceptionHandlersExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderExceptionHandlersExtensions.cs index 26dd0e74..06eefcd3 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderExceptionHandlersExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderExceptionHandlersExtensions.cs @@ -1,13 +1,15 @@ using System; +using System.Diagnostics; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class ReactiveStructuredActivityBuilderExceptionHandlersExtensions { + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddExceptionHandler(this IReactiveStructuredActivityBuilder builder) where TException : Exception - where TExceptionHandler : ExceptionHandlerNode + where TExceptionHandler : class, IExceptionHandlerNode => (builder as IActionBuilder).AddExceptionHandler() as IReactiveStructuredActivityBuilder; } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderPayloadExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderPayloadExtensions.cs deleted file mode 100644 index 40522bb9..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderPayloadExtensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Stateflows.Common; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities.Data -{ - public static class ReactiveStructuredActivityBuilderPayloadExtensions - { - public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, AcceptEventActionDelegateAsync> eventActionAsync, AcceptEventActionBuildAction buildAction = null) - => builder.AddAcceptEventAction(actionNodeName, eventActionAsync, buildAction); - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderSpecialsExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderSpecialsExtensions.cs index 98995eda..61ce6c01 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderSpecialsExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderSpecialsExtensions.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Diagnostics; +using System.Threading.Tasks; using Stateflows.Common; using Stateflows.Activities.Registration; using Stateflows.Activities.Registration.Builders; @@ -8,6 +9,7 @@ namespace Stateflows.Activities { public static class ReactiveStructuredActivityBuilderSpecialsExtensions { + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddJoin(this IReactiveStructuredActivityBuilder builder, string joinNodeName, JoinBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -21,9 +23,11 @@ public static IReactiveStructuredActivityBuilder AddJoin(this IReactiveStructure b => buildAction(b) ) as IReactiveStructuredActivityBuilder; + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddJoin(this IReactiveStructuredActivityBuilder builder, JoinBuildAction joinBuildAction) - => builder.AddJoin(ActivityNodeInfo.Name, joinBuildAction); + => builder.AddJoin(JoinNode.Name, joinBuildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddFork(this IReactiveStructuredActivityBuilder builder, string forkNodeName, ForkBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -37,9 +41,11 @@ public static IReactiveStructuredActivityBuilder AddFork(this IReactiveStructure b => buildAction(b) ) as IReactiveStructuredActivityBuilder; + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddFork(this IReactiveStructuredActivityBuilder builder, ForkBuildAction forkBuildAction) - => builder.AddFork(ActivityNodeInfo.Name, forkBuildAction); + => builder.AddFork(ForkNode.Name, forkBuildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddMerge(this IReactiveStructuredActivityBuilder builder, string mergeNodeName, MergeBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -53,9 +59,11 @@ public static IReactiveStructuredActivityBuilder AddMerge(this IReactiveStructur b => buildAction(b.SetOptions(NodeOptions.None) as IMergeBuilder) ) as IReactiveStructuredActivityBuilder; + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddMerge(this IReactiveStructuredActivityBuilder builder, MergeBuildAction mergeBuildAction) - => builder.AddMerge(ActivityNodeInfo.Name, mergeBuildAction); + => builder.AddMerge(MergeNode.Name, mergeBuildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddControlDecision(this IReactiveStructuredActivityBuilder builder, string decisionNodeName, DecisionBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -69,9 +77,11 @@ public static IReactiveStructuredActivityBuilder AddControlDecision(this IReacti b => buildAction(b.SetOptions(NodeOptions.DecisionDefault) as IDecisionBuilder) ) as IReactiveStructuredActivityBuilder; + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddControlDecision(this IReactiveStructuredActivityBuilder builder, DecisionBuildAction decisionBuildAction) - => builder.AddControlDecision(ActivityNodeInfo>.Name, decisionBuildAction); + => builder.AddControlDecision(DecisionNode.Name, decisionBuildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddDecision(this IReactiveStructuredActivityBuilder builder, string decisionNodeName, DecisionBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -85,9 +95,11 @@ public static IReactiveStructuredActivityBuilder AddDecision(this IReact b => buildAction(new DecisionBuilder(b.SetOptions(NodeOptions.DecisionDefault) as NodeBuilder)) ) as IReactiveStructuredActivityBuilder; + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddDecision(this IReactiveStructuredActivityBuilder builder, DecisionBuildAction decisionBuildAction) - => builder.AddDecision(ActivityNodeInfo>.Name, decisionBuildAction); + => builder.AddDecision(DecisionNode.Name, decisionBuildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddDataStore(this IReactiveStructuredActivityBuilder builder, string dataStoreNodeName, DataStoreBuildAction buildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -101,36 +113,47 @@ public static IReactiveStructuredActivityBuilder AddDataStore(this IReactiveStru b => buildAction(b.SetOptions(NodeOptions.DataStoreDefault) as IDataStoreBuilder) ) as IReactiveStructuredActivityBuilder; + [DebuggerHidden] + public static IReactiveStructuredActivityBuilder AddDataStore(this IReactiveStructuredActivityBuilder builder, DataStoreBuildAction buildAction) + => builder.AddDataStore(DataStoreNode.Name, buildAction); + #region AddAcceptEventAction + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction) where TEvent : Event, new() => builder.AddAcceptEventAction(actionNodeName, c => Task.CompletedTask, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, AcceptEventActionBuildAction buildAction) where TEvent : Event, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => Task.CompletedTask, buildAction); + => builder.AddAcceptEventAction(AcceptEventActionNode.Name, c => Task.CompletedTask, buildAction); - public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, ActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) + [DebuggerHidden] + public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, AcceptEventActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) where TEvent : Event, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => actionAsync(c), buildAction); + => builder.AddAcceptEventAction(AcceptEventActionNode.Name, c => actionAsync(c), buildAction); #endregion #region AddTimeEventAction + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddTimeEventAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction) where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(actionNodeName, c => Task.CompletedTask, buildAction); + => builder.AddTimeEventAction(actionNodeName, c => Task.CompletedTask, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddTimeEventAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, ActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(actionNodeName, c => actionAsync(c), buildAction); + => builder.AddTimeEventAction(actionNodeName, c => actionAsync(c), buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddTimeEventAction(this IReactiveStructuredActivityBuilder builder, ActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => actionAsync(c), buildAction); + => builder.AddTimeEventAction(TimeEventActionNode.Name, c => actionAsync(c), buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddTimeEventAction(this IReactiveStructuredActivityBuilder builder, AcceptEventActionBuildAction buildAction) where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => Task.CompletedTask, buildAction); + => builder.AddTimeEventAction(TimeEventActionNode.Name, c => Task.CompletedTask, buildAction); #endregion } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderTypedExtensions.cs index 578e934a..af8fb482 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderTypedExtensions.cs @@ -1,6 +1,8 @@ using System; +using System.Diagnostics; using System.Threading.Tasks; using Stateflows.Common; +using Stateflows.Common.Extensions; using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration; using Stateflows.Activities.Context.Classes; @@ -13,14 +15,16 @@ namespace Stateflows.Activities.Typed public static class ReactiveStructuredActivityBuilderTypedExtensions { #region AddAction + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddAction(this IReactiveStructuredActivityBuilder builder, TypedActionBuildAction buildAction = null) - where TAction : ActionNode - => AddAction(builder, ActivityNodeInfo.Name, buildAction); + where TAction : class, IActionNode + => AddAction(builder, ActivityNode.Name, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, TypedActionBuildAction buildAction = null) - where TAction : ActionNode + where TAction : class, IActionNode { - (builder as IInternal).Services.RegisterAction(); + (builder as IInternal).Services.AddServiceType(); return builder.AddAction( actionNodeName, @@ -28,11 +32,11 @@ public static IReactiveStructuredActivityBuilder AddAction(this IReacti { var action = (c as BaseContext).NodeScope.GetAction(c); - InputTokensHolder.Tokens.Value = ((ActionContext)c).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)c).OutputTokens; + InputTokens.TokensHolder.Value = ((ActionContext)c).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)c).OutputTokens; ActivityNodeContextAccessor.Context.Value = c; - var result = action.ExecuteAsync(); + var result = action.ExecuteAsync(c.CancellationToken); ActivityNodeContextAccessor.Context.Value = null; return result; @@ -47,25 +51,27 @@ public static IReactiveStructuredActivityBuilder AddAction(this IReacti #endregion #region AddAcceptEventAction + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, AcceptEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TAcceptEventAction : AcceptEventActionNode - => builder.AddAcceptEventAction(ActivityNodeInfo.Name, buildAction); + where TAcceptEventAction : class, IAcceptEventActionNode + => builder.AddAcceptEventAction(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TAcceptEventAction : AcceptEventActionNode + where TAcceptEventAction : class, IAcceptEventActionNode => builder.AddAcceptEventAction( actionNodeName, (AcceptEventActionDelegateAsync)(c => { var action = (c as BaseContext).NodeScope.GetAcceptEventAction(c); - InputTokensHolder.Tokens.Value = ((ActionContext)c).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)c).OutputTokens; + InputTokens.TokensHolder.Value = ((ActionContext)c).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)c).OutputTokens; ActivityNodeContextAccessor.Context.Value = c; - var result = action.ExecuteAsync(); + var result = action.ExecuteAsync(c.Event, c.CancellationToken); ActivityNodeContextAccessor.Context.Value = null; return result; @@ -75,26 +81,45 @@ public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, AcceptEventActionBuildAction buildAction = null) where TTimeEvent : TimeEvent, new() - where TTimeEventAction : AcceptEventActionNode - => builder.AddAcceptEventAction(buildAction); + where TTimeEventAction : class, ITimeEventActionNode + => builder.AddTimeEventAction(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddTimeEventAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction = null) where TTimeEvent : TimeEvent, new() - where TTimeEventAction : AcceptEventActionNode - => builder.AddAcceptEventAction(actionNodeName, buildAction); + where TTimeEventAction : class, ITimeEventActionNode + => builder.AddTimeEventAction( + actionNodeName, + c => + { + var action = (c as BaseContext).NodeScope.GetTimeEventAction(c); + + InputTokens.TokensHolder.Value = ((ActionContext)c).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)c).OutputTokens; + + ActivityNodeContextAccessor.Context.Value = c; + var result = action.ExecuteAsync(c.CancellationToken); + ActivityNodeContextAccessor.Context.Value = null; + + return result; + }, + buildAction + ); #endregion #region AddSendEventAction + [DebuggerHidden] private static async Task GetSendEventAction(this IActionContext context, Func> callback) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode + where TSendEventAction : class, ISendEventActionNode { var action = (context as BaseContext).NodeScope.GetSendEventAction(context); - InputTokensHolder.Tokens.Value = ((ActionContext)context).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)context).OutputTokens; + InputTokens.TokensHolder.Value = ((ActionContext)context).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)context).OutputTokens; ActivityNodeContextAccessor.Context.Value = context; @@ -104,14 +129,16 @@ private static async Task GetSendEventAction(this IReactiveStructuredActivityBuilder builder, SendEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode - => builder.AddSendEventAction(ActivityNodeInfo.Name, buildAction); + where TSendEventAction : class, ISendEventActionNode + => builder.AddSendEventAction(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddSendEventAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, SendEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode + where TSendEventAction : class, ISendEventActionNode { return builder.AddSendEventAction( actionNodeName, @@ -123,14 +150,16 @@ public static IReactiveStructuredActivityBuilder AddSendEventAction(this IReactiveStructuredActivityBuilder builder, ReactiveStructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode - => AddStructuredActivity(builder, ActivityNodeInfo.Name, buildAction); + [DebuggerHidden] + public static IReactiveStructuredActivityBuilder AddStructuredActivity(this IReactiveStructuredActivityBuilder builder, ReactiveStructuredActivityBuildAction buildAction) + where TStructuredActivity : class, IBaseStructuredActivityNode + => AddStructuredActivity(builder, ActivityNode.Name, buildAction); + [DebuggerHidden] public static IReactiveStructuredActivityBuilder AddStructuredActivity(this IReactiveStructuredActivityBuilder builder, string structuredActivityName, ReactiveStructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode + where TStructuredActivity : class, IBaseStructuredActivityNode { - (builder as IInternal).Services.RegisterStructuredActivity(); + (builder as IInternal).Services.AddServiceType(); return builder.AddStructuredActivity( structuredActivityName, @@ -146,14 +175,16 @@ public static IReactiveStructuredActivityBuilder AddStructuredActivity(this IReactiveStructuredActivityBuilder builder, ParallelActivityBuildAction buildAction = null) - where TStructuredActivity : ParallelActivityNode - => AddParallelActivity(builder, ActivityNodeInfo.Name, buildAction); - - public static IReactiveStructuredActivityBuilder AddParallelActivity(this IReactiveStructuredActivityBuilder builder, string structuredActivityName, ParallelActivityBuildAction buildAction = null) - where TStructuredActivity : ParallelActivityNode + [DebuggerHidden] + public static IReactiveStructuredActivityBuilder AddParallelActivity(this IReactiveStructuredActivityBuilder builder, ParallelActivityBuildAction buildAction = null, int chunkSize = 1) + where TStructuredActivity : class, IBaseStructuredActivityNode + => AddParallelActivity(builder, ActivityNode.Name, buildAction, chunkSize); + + [DebuggerHidden] + public static IReactiveStructuredActivityBuilder AddParallelActivity(this IReactiveStructuredActivityBuilder builder, string structuredActivityName, ParallelActivityBuildAction buildAction = null, int chunkSize = 1) + where TStructuredActivity : class, IBaseStructuredActivityNode { - (builder as IInternal).Services.RegisterStructuredActivity(); + (builder as IInternal).Services.AddServiceType(); return builder.AddParallelActivity( structuredActivityName, @@ -163,27 +194,30 @@ public static IReactiveStructuredActivityBuilder AddParallelActivity(); builder.Node.ScanForDeclaredTypes(typeof(TStructuredActivity)); buildAction?.Invoke(b); - } + }, + chunkSize ); } #endregion #region AddIterativeActivity - public static IReactiveStructuredActivityBuilder AddIterativeActivity(this IReactiveStructuredActivityBuilder builder, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) - where TStructuredActivity : IterativeActivityNode - => AddIterativeActivity(builder, ActivityNodeInfo.Name, buildAction, chunkSize); - - public static IReactiveStructuredActivityBuilder AddIterativeActivity(this IReactiveStructuredActivityBuilder builder, string structuredActivityName, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) - where TStructuredActivity : IterativeActivityNode + [DebuggerHidden] + public static IReactiveStructuredActivityBuilder AddIterativeActivity(this IReactiveStructuredActivityBuilder builder, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) + where TIterativeActivity : class, IBaseStructuredActivityNode + => AddIterativeActivity(builder, ActivityNode.Name, buildAction, chunkSize); + + [DebuggerHidden] + public static IReactiveStructuredActivityBuilder AddIterativeActivity(this IReactiveStructuredActivityBuilder builder, string structuredActivityName, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) + where TIterativeActivity : class, IBaseStructuredActivityNode { - (builder as IInternal).Services.RegisterStructuredActivity(); + (builder as IInternal).Services.AddServiceType(); return builder.AddIterativeActivity( structuredActivityName, b => { var builder = b as StructuredActivityBuilder; - builder.AddStructuredActivityEvents(); - builder.Node.ScanForDeclaredTypes(typeof(TStructuredActivity)); + builder.AddStructuredActivityEvents(); + builder.Node.ScanForDeclaredTypes(typeof(TIterativeActivity)); buildAction?.Invoke(b); }, chunkSize diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderTypedPayloadExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderTypedPayloadExtensions.cs deleted file mode 100644 index 46a68b75..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/ReactiveStructuredActivityBuilder/ReactiveStructuredActivityBuilderTypedPayloadExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Stateflows.Common; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities.Typed.Data -{ - public static class ReactiveStructuredActivityBuilderTypedPayloadExtensions - { - #region AddAcceptEventAction - public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, AcceptEventActionBuildAction buildAction = null) - where TAcceptEventAction : AcceptEventActionNode> - => builder.AddAcceptEventAction(ActivityNodeInfo.Name, buildAction); - - public static IReactiveStructuredActivityBuilder AddAcceptEventAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction = null) - where TAcceptEventAction : AcceptEventActionNode> - => builder.AddAcceptEventAction, TAcceptEventAction>(actionNodeName, buildAction); - #endregion - - #region AddSendEventAction - public static IReactiveStructuredActivityBuilder AddSendEventAction(this IReactiveStructuredActivityBuilder builder, SendEventActionBuildAction buildAction = null) - where TSendEventAction : SendEventActionNode> - => builder.AddSendEventAction(ActivityNodeInfo.Name, buildAction); - - public static IReactiveStructuredActivityBuilder AddSendEventAction(this IReactiveStructuredActivityBuilder builder, string actionNodeName, SendEventActionBuildAction buildAction = null) - where TSendEventAction : SendEventActionNode> - => builder.AddSendEventAction, TSendEventAction>(actionNodeName, buildAction); - #endregion - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/SendEventActionBuilder/Flows/SendEventActionBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/SendEventActionBuilder/Flows/SendEventActionBuilderControlFlowsTypedExtensions.cs new file mode 100644 index 00000000..9fdd9af3 --- /dev/null +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/SendEventActionBuilder/Flows/SendEventActionBuilderControlFlowsTypedExtensions.cs @@ -0,0 +1,33 @@ +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.Activities.Extensions; +using Stateflows.Activities.Registration.Interfaces; + +namespace Stateflows.Activities.Typed +{ + public static class SendEventActionBuilderControlFlowsTypedExtensions + { + [DebuggerHidden] + public static ISendEventActionBuilder AddControlFlow(this ISendEventActionBuilder builder, ControlFlowBuildAction buildAction = null) + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name, buildAction); + + [DebuggerHidden] + public static ISendEventActionBuilder AddControlFlow(this ISendEventActionBuilder builder, string targetNodeName) + where TControlFlow : class, IBaseControlFlow + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddControlFlow( + targetNodeName, + b => b.AddControlFlowEvents() + ); + } + + [DebuggerHidden] + public static ISendEventActionBuilder AddControlFlow(this ISendEventActionBuilder builder) + where TFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name); + } +} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/Flows/StructuredActivityBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/Flows/StructuredActivityBuilderControlFlowsTypedExtensions.cs index eddb6903..11edb834 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/Flows/StructuredActivityBuilderControlFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/Flows/StructuredActivityBuilderControlFlowsTypedExtensions.cs @@ -1,20 +1,24 @@ -using Stateflows.Activities.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class StructuredActivityBuilderControlFlowsTypedExtensions { + [DebuggerHidden] public static IStructuredActivityBuilder AddControlFlow(this IStructuredActivityBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddControlFlow(this IStructuredActivityBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow => (builder as IActionBuilder).AddControlFlow(targetNodeName) as IStructuredActivityBuilder; + [DebuggerHidden] public static IStructuredActivityBuilder AddControlFlow(this IStructuredActivityBuilder builder) - where TControlFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name); + where TControlFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/Flows/StructuredActivityBuilderFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/Flows/StructuredActivityBuilderFlowsTypedExtensions.cs index 065fe0f0..0ec8459a 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/Flows/StructuredActivityBuilderFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/Flows/StructuredActivityBuilderFlowsTypedExtensions.cs @@ -1,29 +1,35 @@ -using Stateflows.Activities.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class StructuredActivityBuilderFlowsTypedExtensions { + [DebuggerHidden] public static IStructuredActivityBuilder AddFlow(this IStructuredActivityBuilder builder, ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddFlow(this IStructuredActivityBuilder builder, string targetNodeName) - where TFlow : Flow + where TFlow : class, IBaseFlow => (builder as IActionBuilder).AddFlow(targetNodeName) as IStructuredActivityBuilder; + [DebuggerHidden] public static IStructuredActivityBuilder AddFlow(this IStructuredActivityBuilder builder) - where TFlow : Flow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); + [DebuggerHidden] public static IStructuredActivityBuilder AddFlow(this IStructuredActivityBuilder builder, string targetNodeName) - where TFlow : TransformationFlow + where TFlow : class, IFlowTransformation => (builder as IActionBuilder).AddFlow(targetNodeName) as IStructuredActivityBuilder; + [DebuggerHidden] public static IStructuredActivityBuilder AddFlow(this IStructuredActivityBuilder builder) - where TFlow : TransformationFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderAnonymousExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderAnonymousExtensions.cs index 90ae78e8..7b33c73d 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderAnonymousExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderAnonymousExtensions.cs @@ -1,17 +1,20 @@ -using Stateflows.Common; +using System.Diagnostics; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class StructuredActivityBuilderAnonymousExtensions { + [DebuggerHidden] public static IStructuredActivityBuilder AddStructuredActivity(this IStructuredActivityBuilder builder, StructuredActivityBuildAction buildAction) - => builder.AddStructuredActivity(ActivityNodeInfo.Name, buildAction); + => builder.AddStructuredActivity(StructuredActivityNode.Name, buildAction); - public static IStructuredActivityBuilder AddParallelActivity(this IStructuredActivityBuilder builder, ParallelActivityBuildAction buildAction) - => builder.AddParallelActivity(ActivityNodeInfo>.Name, buildAction); + [DebuggerHidden] + public static IStructuredActivityBuilder AddParallelActivity(this IStructuredActivityBuilder builder, ParallelActivityBuildAction buildAction, int chunkSize = 1) + => builder.AddParallelActivity(ParallelActivityNode.Name, buildAction, chunkSize); - public static IStructuredActivityBuilder AddIterativeActivity(this IStructuredActivityBuilder builder, IterativeActivityBuildAction buildAction) - => builder.AddIterativeActivity(ActivityNodeInfo>.Name, buildAction); + [DebuggerHidden] + public static IStructuredActivityBuilder AddIterativeActivity(this IStructuredActivityBuilder builder, IterativeActivityBuildAction buildAction, int chunkSize = 1) + => builder.AddIterativeActivity(IterativeActivityNode.Name, buildAction, chunkSize); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderExceptionHandlersExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderExceptionHandlersExtensions.cs index 777c198c..7af65258 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderExceptionHandlersExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderExceptionHandlersExtensions.cs @@ -1,13 +1,15 @@ using System; +using System.Diagnostics; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class StructuredActivityBuilderExceptionHandlersExtensions { + [DebuggerHidden] public static IStructuredActivityBuilder AddExceptionHandler(this IStructuredActivityBuilder builder) where TException : Exception - where TExceptionHandler : ExceptionHandlerNode + where TExceptionHandler : class, IExceptionHandlerNode => (builder as IActionBuilder).AddExceptionHandler() as IStructuredActivityBuilder; } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderSpecialsExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderSpecialsExtensions.cs index 8855c974..89536d3c 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderSpecialsExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderSpecialsExtensions.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Diagnostics; +using System.Threading.Tasks; using Stateflows.Activities.Registration; using Stateflows.Activities.Registration.Builders; using Stateflows.Activities.Registration.Interfaces; @@ -7,6 +8,7 @@ namespace Stateflows.Activities { public static class StructuredActivityBuilderSpecialsExtensions { + [DebuggerHidden] public static IStructuredActivityBuilder AddJoin(this IStructuredActivityBuilder builder, string joinNodeName, JoinBuildAction joinBuildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -20,9 +22,11 @@ public static IStructuredActivityBuilder AddJoin(this IStructuredActivityBuilder b => joinBuildAction(b) ) as IStructuredActivityBuilder; + [DebuggerHidden] public static IStructuredActivityBuilder AddJoin(this IStructuredActivityBuilder builder, JoinBuildAction joinBuildAction) - => builder.AddJoin(ActivityNodeInfo.Name, joinBuildAction); + => builder.AddJoin(ActivityNode.Name, joinBuildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddFork(this IStructuredActivityBuilder builder, string forkNodeName, ForkBuildAction forkBuildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -36,9 +40,11 @@ public static IStructuredActivityBuilder AddFork(this IStructuredActivityBuilder b => forkBuildAction(b) ) as IStructuredActivityBuilder; + [DebuggerHidden] public static IStructuredActivityBuilder AddFork(this IStructuredActivityBuilder builder, ForkBuildAction forkBuildAction) - => builder.AddFork(ActivityNodeInfo.Name, forkBuildAction); + => builder.AddFork(ActivityNode.Name, forkBuildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddMerge(this IStructuredActivityBuilder builder, string mergeNodeName, MergeBuildAction mergeBuildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -52,9 +58,11 @@ public static IStructuredActivityBuilder AddMerge(this IStructuredActivityBuilde b => mergeBuildAction(b.SetOptions(NodeOptions.None) as IMergeBuilder) ) as IStructuredActivityBuilder; + [DebuggerHidden] public static IStructuredActivityBuilder AddMerge(this IStructuredActivityBuilder builder, MergeBuildAction mergeBuildAction) - => builder.AddMerge(ActivityNodeInfo.Name, mergeBuildAction); + => builder.AddMerge(ActivityNode.Name, mergeBuildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddControlDecision(this IStructuredActivityBuilder builder, string decisionNodeName, DecisionBuildAction decisionBuildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -68,9 +76,11 @@ public static IStructuredActivityBuilder AddControlDecision(this IStructuredActi b => decisionBuildAction(b.SetOptions(NodeOptions.DecisionDefault) as IDecisionBuilder) ) as IStructuredActivityBuilder; + [DebuggerHidden] public static IStructuredActivityBuilder AddControlDecision(this IStructuredActivityBuilder builder, DecisionBuildAction decisionBuildAction) - => builder.AddControlDecision(ActivityNodeInfo>.Name, decisionBuildAction); + => builder.AddControlDecision(ActivityNode>.Name, decisionBuildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddDecision(this IStructuredActivityBuilder builder, string decisionNodeName, DecisionBuildAction decisionBuildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -84,9 +94,11 @@ public static IStructuredActivityBuilder AddDecision(this IStructuredAct b => decisionBuildAction(new DecisionBuilder(b.SetOptions(NodeOptions.DecisionDefault) as NodeBuilder)) ) as IStructuredActivityBuilder; + [DebuggerHidden] public static IStructuredActivityBuilder AddDecision(this IStructuredActivityBuilder builder, DecisionBuildAction decisionBuildAction) - => builder.AddDecision(ActivityNodeInfo>.Name, decisionBuildAction); + => builder.AddDecision(ActivityNode>.Name, decisionBuildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddDataStore(this IStructuredActivityBuilder builder, string dataStoreNodeName, DataStoreBuildAction decisionBuildAction) => (builder as BaseActivityBuilder) .AddNode( @@ -99,5 +111,9 @@ public static IStructuredActivityBuilder AddDataStore(this IStructuredActivityBu }, b => decisionBuildAction(b.SetOptions(NodeOptions.DataStoreDefault) as IDataStoreBuilder) ) as IStructuredActivityBuilder; + + [DebuggerHidden] + public static IStructuredActivityBuilder AddDataStore(this IStructuredActivityBuilder builder, DataStoreBuildAction buildAction) + => builder.AddDataStore(DataStoreNode.Name, buildAction); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderTypedExtensions.cs index 5eb55606..73246b65 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderTypedExtensions.cs @@ -1,38 +1,42 @@ using System; +using System.Diagnostics; using System.Threading.Tasks; using Stateflows.Common; +using Stateflows.Common.Extensions; using Stateflows.Activities.Extensions; using Stateflows.Activities.Registration; using Stateflows.Activities.Context.Classes; using Stateflows.Activities.Context.Interfaces; -using Stateflows.Activities.Registration.Interfaces; using Stateflows.Activities.Registration.Builders; +using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class StructuredActivityBuilderTypedExtensions { #region AddAction + [DebuggerHidden] public static IStructuredActivityBuilder AddAction(this IStructuredActivityBuilder builder, TypedActionBuildAction buildAction = null) - where TAction : ActionNode - => AddAction(builder, ActivityNodeInfo.Name, buildAction); + where TAction : class, IActionNode + => AddAction(builder, ActivityNode.Name, buildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddAction(this IStructuredActivityBuilder builder, string actionNodeName, TypedActionBuildAction buildAction = null) - where TAction : ActionNode + where TAction : class, IActionNode { - (builder as IInternal).Services.RegisterAction(); + (builder as IInternal).Services.AddServiceType(); return builder.AddAction( actionNodeName, - (ActionDelegateAsync)(c => + (c => { var action = (c as BaseContext).NodeScope.GetAction(c); - InputTokensHolder.Tokens.Value = ((ActionContext)c).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)c).OutputTokens; + InputTokens.TokensHolder.Value = ((ActionContext)c).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)c).OutputTokens; ActivityNodeContextAccessor.Context.Value = c; - var result = action.ExecuteAsync(); + var result = action.ExecuteAsync(c.CancellationToken); ActivityNodeContextAccessor.Context.Value = null; return result; @@ -47,14 +51,15 @@ public static IStructuredActivityBuilder AddAction(this IStructuredActi #endregion #region AddSendEventAction + [DebuggerHidden] private static async Task GetSendEventAction(this IActionContext context, Func> callback) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode + where TSendEventAction : class, ISendEventActionNode { var action = (context as BaseContext).NodeScope.GetSendEventAction(context); - InputTokensHolder.Tokens.Value = ((ActionContext)context).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)context).OutputTokens; + InputTokens.TokensHolder.Value = ((ActionContext)context).InputTokens; + OutputTokens.TokensHolder.Value = ((ActionContext)context).OutputTokens; ActivityNodeContextAccessor.Context.Value = context; var result = await callback(action); @@ -63,14 +68,16 @@ private static async Task GetSendEventAction(this IStructuredActivityBuilder builder, SendEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode - => builder.AddSendEventAction(ActivityNodeInfo.Name, buildAction); + where TSendEventAction : class, ISendEventActionNode + => builder.AddSendEventAction(ActivityNode.Name, buildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddSendEventAction(this IStructuredActivityBuilder builder, string actionNodeName, SendEventActionBuildAction buildAction = null) where TEvent : Event, new() - where TSendEventAction : SendEventActionNode + where TSendEventAction : class, ISendEventActionNode { return builder.AddSendEventAction( actionNodeName, @@ -81,38 +88,17 @@ public static IStructuredActivityBuilder AddSendEventAction(this IReactiveStructuredActivityBuilder builder, ReactiveStructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode - => AddStructuredActivity(builder, ActivityNodeInfo.Name, buildAction); - - public static IReactiveStructuredActivityBuilder AddStructuredActivity(this IReactiveStructuredActivityBuilder builder, string structuredActivityName, ReactiveStructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode - { - (builder as IInternal).Services.RegisterStructuredActivity(); - - return builder.AddStructuredActivity( - structuredActivityName, - b => - { - var builder = b as StructuredActivityBuilder; - builder.AddStructuredActivityEvents(); - builder.Node.ScanForDeclaredTypes(typeof(TStructuredActivity)); - buildAction?.Invoke(b); - } - ); - } - #endregion - #region AddStructuredActivity + [DebuggerHidden] public static IStructuredActivityBuilder AddStructuredActivity(this IStructuredActivityBuilder builder, StructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode - => AddStructuredActivity(builder, ActivityNodeInfo.Name, buildAction); + where TStructuredActivity : class, IBaseStructuredActivityNode + => AddStructuredActivity(builder, ActivityNode.Name, buildAction); + [DebuggerHidden] public static IStructuredActivityBuilder AddStructuredActivity(this IStructuredActivityBuilder builder, string structuredActivityName, StructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode + where TStructuredActivity : class, IBaseStructuredActivityNode { - (builder as IInternal).Services.RegisterStructuredActivity(); + (builder as IInternal).Services.AddServiceType(); return builder.AddStructuredActivity( structuredActivityName, @@ -128,16 +114,16 @@ public static IStructuredActivityBuilder AddStructuredActivity(this IStructuredActivityBuilder builder, ParallelActivityBuildAction buildAction = null) - where TParallelizationToken : TokenHolder, new() - where TStructuredActivity : ParallelActivityNode - => AddParallelActivity(builder, ActivityNodeInfo.Name, buildAction); - - public static IStructuredActivityBuilder AddParallelActivity(this IStructuredActivityBuilder builder, string structuredActivityName, ParallelActivityBuildAction buildAction = null) - where TParallelizationToken : TokenHolder, new() - where TStructuredActivity : ParallelActivityNode + [DebuggerHidden] + public static IStructuredActivityBuilder AddParallelActivity(this IStructuredActivityBuilder builder, ParallelActivityBuildAction buildAction = null, int chunkSize = 1) + where TStructuredActivity : class, IBaseStructuredActivityNode + => AddParallelActivity(builder, ActivityNode.Name, buildAction, chunkSize); + + [DebuggerHidden] + public static IStructuredActivityBuilder AddParallelActivity(this IStructuredActivityBuilder builder, string structuredActivityName, ParallelActivityBuildAction buildAction = null, int chunkSize = 1) + where TStructuredActivity : class, IBaseStructuredActivityNode { - (builder as IInternal).Services.RegisterStructuredActivity(); + (builder as IInternal).Services.AddServiceType(); return builder.AddParallelActivity( structuredActivityName, @@ -147,22 +133,23 @@ public static IStructuredActivityBuilder AddParallelActivity(); builder.Node.ScanForDeclaredTypes(typeof(TStructuredActivity)); buildAction?.Invoke(b); - } + }, + chunkSize ); } #endregion #region AddIterativeActivity - public static IStructuredActivityBuilder AddIterativeActivity(this IStructuredActivityBuilder builder, IterativeActivityBuildAction buildAction = null) - where TIterationToken : TokenHolder, new() - where TStructuredActivity : IterativeActivityNode - => AddIterativeActivity(builder, ActivityNodeInfo.Name, buildAction); - - public static IStructuredActivityBuilder AddIterativeActivity(this IStructuredActivityBuilder builder, string structuredActivityName, IterativeActivityBuildAction buildAction = null) - where TIterationToken : TokenHolder, new() - where TStructuredActivity : IterativeActivityNode + [DebuggerHidden] + public static IStructuredActivityBuilder AddIterativeActivity(this IStructuredActivityBuilder builder, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) + where TStructuredActivity : class, IBaseStructuredActivityNode + => AddIterativeActivity(builder, ActivityNode.Name, buildAction, chunkSize); + + [DebuggerHidden] + public static IStructuredActivityBuilder AddIterativeActivity(this IStructuredActivityBuilder builder, string structuredActivityName, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) + where TStructuredActivity : class, IBaseStructuredActivityNode { - (builder as IInternal).Services.RegisterStructuredActivity(); + (builder as IInternal).Services.AddServiceType(); return builder.AddIterativeActivity( structuredActivityName, b => @@ -171,7 +158,8 @@ public static IStructuredActivityBuilder AddIterativeActivity(); builder.Node.ScanForDeclaredTypes(typeof(TStructuredActivity)); buildAction?.Invoke(b); - } + }, + chunkSize ); } #endregion diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderTypedPayloadExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderTypedPayloadExtensions.cs deleted file mode 100644 index 046c4d1d..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/StructuredActivityBuilder/StructuredActivityBuilderTypedPayloadExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Stateflows.Common; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities.Typed.Data -{ - public static class StructuredActivityBuilderTypedPayloadExtensions - { - #region AddSendEventAction - public static IStructuredActivityBuilder AddSendEventAction(this IStructuredActivityBuilder builder, SendEventActionBuildAction buildAction = null) - where TSendEventAction : SendEventActionNode> - => builder.AddSendEventAction(ActivityNodeInfo.Name, buildAction); - - public static IStructuredActivityBuilder AddSendEventAction(this IStructuredActivityBuilder builder, string actionNodeName, SendEventActionBuildAction buildAction = null) - where TSendEventAction : SendEventActionNode> - => builder.AddSendEventAction, TSendEventAction>(actionNodeName, buildAction); - #endregion - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/Flows/TypedActionBuilderControlFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/Flows/TypedActionBuilderControlFlowsTypedExtensions.cs index 88c07b1c..785c203a 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/Flows/TypedActionBuilderControlFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/Flows/TypedActionBuilderControlFlowsTypedExtensions.cs @@ -1,20 +1,24 @@ -using Stateflows.Activities.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class TypedActionBuilderControlFlowsTypedExtensions { + [DebuggerHidden] public static ITypedActionBuilder AddControlFlow(this ITypedActionBuilder builder, ControlFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static ITypedActionBuilder AddControlFlow(this ITypedActionBuilder builder, string targetNodeName) - where TControlFlow : ControlFlow + where TControlFlow : class, IBaseControlFlow => (builder as IActionBuilder).AddControlFlow(targetNodeName) as ITypedActionBuilder; + [DebuggerHidden] public static ITypedActionBuilder AddControlFlow(this ITypedActionBuilder builder) - where TControlFlow : ControlFlow - where TTargetNode : ActivityNode - => builder.AddControlFlow(ActivityNodeInfo.Name); + where TControlFlow : class, IBaseControlFlow + where TTargetNode : class, IActivityNode + => builder.AddControlFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/Flows/TypedActionBuilderFlowsTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/Flows/TypedActionBuilderFlowsTypedExtensions.cs index ea109759..c4316281 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/Flows/TypedActionBuilderFlowsTypedExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/Flows/TypedActionBuilderFlowsTypedExtensions.cs @@ -1,29 +1,35 @@ -using Stateflows.Activities.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class TypedActionBuilderFlowsTypedExtensions { + [DebuggerHidden] public static ITypedActionBuilder AddFlow(this ITypedActionBuilder builder, ObjectFlowBuildAction buildAction = null) - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name, buildAction); + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name, buildAction); + [DebuggerHidden] public static ITypedActionBuilder AddFlow(this ITypedActionBuilder builder, string targetNodeName) - where TFlow : Flow + where TFlow : class, IBaseFlow => (builder as IActionBuilder).AddFlow(targetNodeName) as ITypedActionBuilder; + [DebuggerHidden] public static ITypedActionBuilder AddFlow(this ITypedActionBuilder builder) - where TFlow : Flow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IBaseFlow + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); + [DebuggerHidden] public static ITypedActionBuilder AddFlow(this ITypedActionBuilder builder, string targetNodeName) - where TFlow : TransformationFlow + where TFlow : class, IFlowTransformation => (builder as IActionBuilder).AddFlow(targetNodeName) as ITypedActionBuilder; + [DebuggerHidden] public static ITypedActionBuilder AddFlow(this ITypedActionBuilder builder) - where TFlow : TransformationFlow - where TTargetNode : ActivityNode - => builder.AddFlow(ActivityNodeInfo.Name); + where TFlow : class, IFlowTransformation + where TTargetNode : class, IActivityNode + => builder.AddFlow(ActivityNode.Name); } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/TypedActionBuilderExceptionHandlersExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/TypedActionBuilderExceptionHandlersExtensions.cs index b7ee8371..943977c6 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/TypedActionBuilderExceptionHandlersExtensions.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActionBuilder/TypedActionBuilderExceptionHandlersExtensions.cs @@ -1,13 +1,15 @@ using System; +using System.Diagnostics; using Stateflows.Activities.Registration.Interfaces; namespace Stateflows.Activities.Typed { public static class TypedActionBuilderExceptionHandlersExtensions { + [DebuggerHidden] public static ITypedActionBuilder AddExceptionHandler(this ITypedActionBuilder builder) where TException : Exception - where TExceptionHandler : ExceptionHandlerNode + where TExceptionHandler : class, IExceptionHandlerNode => (builder as IActionBuilder).AddExceptionHandler() as ITypedActionBuilder; } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderPayloadExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderPayloadExtensions.cs deleted file mode 100644 index 8b78aba2..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderPayloadExtensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Stateflows.Common; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities.Data -{ - public static class TypedActivityBuilderPayloadExtensions - { - public static ITypedActivityBuilder AddAcceptEventAction(this ITypedActivityBuilder builder, string actionNodeName, AcceptEventActionDelegateAsync> eventActionAsync, AcceptEventActionBuildAction buildAction = null) - => builder.AddAcceptEventAction(actionNodeName, eventActionAsync, buildAction); - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderSpecialsExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderSpecialsExtensions.cs deleted file mode 100644 index 67465047..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderSpecialsExtensions.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System.Threading.Tasks; -using Stateflows.Common; -using Stateflows.Activities.Registration; -using Stateflows.Activities.Registration.Builders; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities -{ - public static class TypedActivityBuilderSpecialsExtensions - { - public static ITypedActivityBuilder AddJoin(this ITypedActivityBuilder builder, string joinNodeName, JoinBuildAction joinBuildAction) - => (builder as BaseActivityBuilder) - .AddNode( - NodeType.Join, - joinNodeName, - c => - { - c.PassAllTokensOn(); - return Task.CompletedTask; - }, - b => joinBuildAction(b) - ) as ITypedActivityBuilder; - - public static ITypedActivityBuilder AddFork(this ITypedActivityBuilder builder, string forkNodeName, ForkBuildAction forkBuildAction) - => (builder as BaseActivityBuilder) - .AddNode( - NodeType.Fork, - forkNodeName, - c => - { - c.PassAllTokensOn(); - return Task.CompletedTask; - }, - b => forkBuildAction(b) - ) as ITypedActivityBuilder; - - public static ITypedActivityBuilder AddMerge(this ITypedActivityBuilder builder, string mergeNodeName, MergeBuildAction mergeBuildAction) - => (builder as BaseActivityBuilder) - .AddNode( - NodeType.Merge, - mergeNodeName, - c => - { - c.PassAllTokensOn(); - return Task.CompletedTask; - }, - b => mergeBuildAction(b.SetOptions(NodeOptions.None) as IMergeBuilder) - ) as ITypedActivityBuilder; - - public static ITypedActivityBuilder AddControlDecision(this ITypedActivityBuilder builder, string decisionNodeName, DecisionBuildAction decisionBuildAction) - => (builder as BaseActivityBuilder) - .AddNode( - NodeType.Decision, - decisionNodeName, - c => - { - c.PassAllTokensOn(); - return Task.CompletedTask; - }, - b => decisionBuildAction(b.SetOptions(NodeOptions.DecisionDefault) as IDecisionBuilder) - ) as ITypedActivityBuilder; - - public static ITypedActivityBuilder AddDecision(this ITypedActivityBuilder builder, string decisionNodeName, DecisionBuildAction decisionBuildAction) - => (builder as BaseActivityBuilder) - .AddNode( - NodeType.Decision, - decisionNodeName, - c => - { - c.PassAllTokensOn(); - return Task.CompletedTask; - }, - b => decisionBuildAction(new DecisionBuilder(b.SetOptions(NodeOptions.DecisionDefault) as NodeBuilder)) - ) as ITypedActivityBuilder; - - public static ITypedActivityBuilder AddDataStore(this ITypedActivityBuilder builder, string dataStoreNodeName, DataStoreBuildAction decisionBuildAction) - => (builder as BaseActivityBuilder) - .AddNode( - NodeType.DataStore, - dataStoreNodeName, - c => - { - c.PassAllTokensOn(); - return Task.CompletedTask; - }, - b => decisionBuildAction(b.SetOptions(NodeOptions.DataStoreDefault) as IDataStoreBuilder) - ) as ITypedActivityBuilder; - - #region AddAcceptEventAction - public static ITypedActivityBuilder AddAcceptEventAction(this ITypedActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction) - where TEvent : Event, new() - => builder.AddAcceptEventAction(actionNodeName, c => Task.CompletedTask, buildAction); - - public static ITypedActivityBuilder AddAcceptEventAction(this ITypedActivityBuilder builder, AcceptEventActionBuildAction buildAction) - where TEvent : Event, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => Task.CompletedTask, buildAction); - - public static ITypedActivityBuilder AddAcceptEventAction(this ITypedActivityBuilder builder, ActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) - where TEvent : Event, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => actionAsync(c), buildAction); - #endregion - - #region AddTimeEventAction - public static ITypedActivityBuilder AddTimeEventAction(this ITypedActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction) - where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(actionNodeName, c => Task.CompletedTask, buildAction); - - public static ITypedActivityBuilder AddTimeEventAction(this ITypedActivityBuilder builder, string actionNodeName, ActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) - where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(actionNodeName, c => actionAsync(c), buildAction); - - public static ITypedActivityBuilder AddTimeEventAction(this ITypedActivityBuilder builder, ActionDelegateAsync actionAsync, AcceptEventActionBuildAction buildAction = null) - where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => actionAsync(c), buildAction); - - public static ITypedActivityBuilder AddTimeEventAction(this ITypedActivityBuilder builder, AcceptEventActionBuildAction buildAction) - where TTimeEvent : TimeEvent, new() - => builder.AddAcceptEventAction(ActivityNodeInfo>.Name, c => Task.CompletedTask, buildAction); - #endregion - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderTypedExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderTypedExtensions.cs deleted file mode 100644 index 2b055d0a..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderTypedExtensions.cs +++ /dev/null @@ -1,181 +0,0 @@ -using System; -using System.Threading.Tasks; -using Stateflows.Common; -using Stateflows.Activities.Extensions; -using Stateflows.Activities.Registration; -using Stateflows.Activities.Context.Classes; -using Stateflows.Activities.Context.Interfaces; -using Stateflows.Activities.Registration.Builders; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities.Typed -{ - public static class TypedActivityBuilderTypedExtensions - { - #region AddAction - public static ITypedActivityBuilder AddAction(this ITypedActivityBuilder builder, TypedActionBuildAction buildAction = null) - where TAction : ActionNode - => AddAction(builder, ActivityNodeInfo.Name, buildAction); - - public static ITypedActivityBuilder AddAction(this ITypedActivityBuilder builder, string actionNodeName, TypedActionBuildAction buildAction = null) - where TAction : ActionNode - { - (builder as IInternal).Services.RegisterAction(); - - return builder.AddAction( - actionNodeName, - (ActionDelegateAsync)(c => - { - var action = (c as BaseContext).NodeScope.GetAction(c); - - InputTokensHolder.Tokens.Value = ((ActionContext)c).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)c).OutputTokens; - - ActivityNodeContextAccessor.Context.Value = c; - var result = action.ExecuteAsync(); - ActivityNodeContextAccessor.Context.Value = null; - - return result; - }), - b => - { - (b as NodeBuilder).Node.ScanForDeclaredTypes(typeof(TAction)); - buildAction?.Invoke(b as ITypedActionBuilder); - } - ); - } - #endregion - - #region AddAcceptEventAction - public static ITypedActivityBuilder AddAcceptEventAction(this ITypedActivityBuilder builder, AcceptEventActionBuildAction buildAction = null) - where TEvent : Event, new() - where TAcceptEventAction : AcceptEventActionNode - => builder.AddAcceptEventAction(ActivityNodeInfo.Name, buildAction); - - public static ITypedActivityBuilder AddAcceptEventAction(this ITypedActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction = null) - where TEvent : Event, new() - where TAcceptEventAction : AcceptEventActionNode - => builder.AddAcceptEventAction( - actionNodeName, - (AcceptEventActionDelegateAsync)(c => - { - var action = (c as BaseContext).NodeScope.GetAcceptEventAction(c); - - InputTokensHolder.Tokens.Value = ((ActionContext)c).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)c).OutputTokens; - - ActivityNodeContextAccessor.Context.Value = c; - var result = action.ExecuteAsync(); - ActivityNodeContextAccessor.Context.Value = null; - - return result; - }), - buildAction - ); - #endregion - - #region AddSendEventAction - private static async Task GetSendEventAction(this IActionContext context, Func> callback) - where TEvent : Event, new() - where TSendEventAction : SendEventActionNode - { - var action = (context as BaseContext).NodeScope.GetSendEventAction(context); - - InputTokensHolder.Tokens.Value = ((ActionContext)context).InputTokens; - OutputTokensHolder.Tokens.Value = ((ActionContext)context).OutputTokens; - - ActivityNodeContextAccessor.Context.Value = context; - var result = await callback(action); - ActivityNodeContextAccessor.Context.Value = null; - - return result; - } - - public static ITypedActivityBuilder AddSendEventAction(this ITypedActivityBuilder builder, SendEventActionBuildAction buildAction = null) - where TEvent : Event, new() - where TSendEventAction : SendEventActionNode - => builder.AddSendEventAction(ActivityNodeInfo.Name, buildAction); - - public static ITypedActivityBuilder AddSendEventAction(this ITypedActivityBuilder builder, string actionNodeName, SendEventActionBuildAction buildAction = null) - where TEvent : Event, new() - where TSendEventAction : SendEventActionNode - { - return builder.AddSendEventAction( - actionNodeName, - c => c.GetSendEventAction(a => a.GenerateEventAsync()), - c => c.GetSendEventAction(a => a.SelectTargetAsync()), - buildAction - ); - } - #endregion - - #region AddStructuredActivity - public static ITypedActivityBuilder AddStructuredActivity(this ITypedActivityBuilder builder, ReactiveStructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode - => AddStructuredActivity(builder, ActivityNodeInfo.Name, buildAction); - - public static ITypedActivityBuilder AddStructuredActivity(this ITypedActivityBuilder builder, string structuredActivityName, ReactiveStructuredActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode - { - (builder as IInternal).Services.RegisterStructuredActivity(); - - return builder.AddStructuredActivity( - structuredActivityName, - b => - { - var builder = b as StructuredActivityBuilder; - builder.AddStructuredActivityEvents(); - builder.Node.ScanForDeclaredTypes(typeof(TStructuredActivity)); - buildAction?.Invoke(b); - } - ); - } - #endregion - - #region AddParallelActivity - public static ITypedActivityBuilder AddParallelActivity(this ITypedActivityBuilder builder, ParallelActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode - => AddParallelActivity(builder, ActivityNodeInfo.Name, buildAction); - - public static ITypedActivityBuilder AddParallelActivity(this ITypedActivityBuilder builder, string structuredActivityName, ParallelActivityBuildAction buildAction = null) - where TStructuredActivity : StructuredActivityNode - { - (builder as IInternal).Services.RegisterStructuredActivity(); - - return builder.AddParallelActivity( - structuredActivityName, - b => - { - var builder = b as StructuredActivityBuilder; - builder.AddStructuredActivityEvents(); - builder.Node.ScanForDeclaredTypes(typeof(TStructuredActivity)); - buildAction?.Invoke(b); - } - ); - } - #endregion - - #region AddIterativeActivity - public static ITypedActivityBuilder AddIterativeActivity(this ITypedActivityBuilder builder, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) - where TStructuredActivity : StructuredActivityNode - => AddIterativeActivity(builder, ActivityNodeInfo.Name, buildAction, chunkSize); - - public static ITypedActivityBuilder AddIterativeActivity(this ITypedActivityBuilder builder, string structuredActivityName, IterativeActivityBuildAction buildAction = null, int chunkSize = 1) - where TStructuredActivity : StructuredActivityNode - { - (builder as IInternal).Services.RegisterStructuredActivity(); - return builder.AddIterativeActivity( - structuredActivityName, - b => - { - var builder = b as StructuredActivityBuilder; - builder.AddStructuredActivityEvents(); - builder.Node.ScanForDeclaredTypes(typeof(TStructuredActivity)); - buildAction?.Invoke(b); - }, - chunkSize - ); - } - #endregion - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderTypedPayloadExtensions.cs b/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderTypedPayloadExtensions.cs deleted file mode 100644 index ba3de41e..00000000 --- a/Core/Stateflows/Activities/Registration/Interfaces/Extensions/TypedActivityBuilder/TypedActivityBuilderTypedPayloadExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Stateflows.Common; -using Stateflows.Activities.Registration.Interfaces; - -namespace Stateflows.Activities.Typed.Data -{ - public static class TypedActivityBuilderTypedPayloadExtensions - { - #region AddAcceptEventAction - public static ITypedActivityBuilder AddAcceptEventAction(this ITypedActivityBuilder builder, AcceptEventActionBuildAction buildAction = null) - where TAcceptEventAction : AcceptEventActionNode> - => builder.AddAcceptEventAction(ActivityNodeInfo.Name, buildAction); - - public static ITypedActivityBuilder AddAcceptEventAction(this ITypedActivityBuilder builder, string actionNodeName, AcceptEventActionBuildAction buildAction = null) - where TAcceptEventAction : AcceptEventActionNode> - => builder.AddAcceptEventAction, TAcceptEventAction>(actionNodeName, buildAction); - #endregion - - #region AddSendEventAction - public static ITypedActivityBuilder AddSendEventAction(this ITypedActivityBuilder builder, SendEventActionBuildAction buildAction = null) - where TSendEventAction : SendEventActionNode> - => builder.AddSendEventAction(ActivityNodeInfo.Name, buildAction); - - public static ITypedActivityBuilder AddSendEventAction(this ITypedActivityBuilder builder, string actionNodeName, SendEventActionBuildAction buildAction = null) - where TSendEventAction : SendEventActionNode> - => builder.AddSendEventAction, TSendEventAction>(actionNodeName, buildAction); - #endregion - } -} diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IAcceptEventActionBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IAcceptEventActionBuilder.cs index af4e7ba6..45c2b2ed 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IAcceptEventActionBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IAcceptEventActionBuilder.cs @@ -3,8 +3,8 @@ namespace Stateflows.Activities.Registration.Interfaces { public interface IAcceptEventActionBuilder : - IObjectFlow, - IControlFlow, - IExceptionHandler + IObjectFlowBase, + IControlFlowBase, + IExceptionHandlerBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IActionBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IActionBuilder.cs index 95b862ff..11c460c9 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IActionBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IActionBuilder.cs @@ -3,21 +3,21 @@ namespace Stateflows.Activities.Registration.Interfaces { public interface IActionBuilder : - IObjectFlow, - IControlFlow, - IExceptionHandler, + IObjectFlowBase, + IControlFlowBase, + IExceptionHandlerBase, INodeOptions { } public interface IActionBuilderWithOptions : - IObjectFlow, - IControlFlow, - IExceptionHandler + IObjectFlowBase, + IControlFlowBase, + IExceptionHandlerBase { } public interface ITypedActionBuilder : - IObjectFlow, - IControlFlow, - IExceptionHandler + IObjectFlowBase, + IControlFlowBase, + IExceptionHandlerBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IActivityBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IActivityBuilder.cs index 8d56f85d..1293d5cf 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IActivityBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IActivityBuilder.cs @@ -13,15 +13,4 @@ public interface IActivityBuilder : IAcceptEvent, ISendEvent { } - - public interface ITypedActivityBuilder : - IActivityUtils, - IReactiveActivity, - IInitial, - IFinal, - IInput, - IOutput, - IAcceptEvent, - ISendEvent - { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IDataStoreBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IDataStoreBuilder.cs index 068df2e4..f7c974d2 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IDataStoreBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IDataStoreBuilder.cs @@ -2,6 +2,6 @@ namespace Stateflows.Activities.Registration.Interfaces { - public interface IDataStoreBuilder : IObjectFlow + public interface IDataStoreBuilder : IObjectFlowBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IDecisionBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IDecisionBuilder.cs index 01fa10ce..cf08cfc0 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IDecisionBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IDecisionBuilder.cs @@ -2,9 +2,9 @@ namespace Stateflows.Activities { - public interface IDecisionBuilder : IDecisionFlow>, IElseDecisionFlow> + public interface IDecisionBuilder : IDecisionFlowBase>, IElseDecisionFlowBase> { } - public interface IDecisionBuilder : IDecisionFlow, IElseDecisionFlow + public interface IDecisionBuilder : IDecisionFlowBase, IElseDecisionFlowBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IForkBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IForkBuilder.cs index 1718a188..f5f3e80f 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IForkBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IForkBuilder.cs @@ -2,6 +2,6 @@ namespace Stateflows.Activities.Registration.Interfaces { - public interface IForkBuilder : IObjectFlow, IControlFlow + public interface IForkBuilder : IObjectFlowBase, IControlFlowBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IInitialBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IInitialBuilder.cs index a0c97d9a..f28251e9 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IInitialBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IInitialBuilder.cs @@ -2,6 +2,6 @@ namespace Stateflows.Activities.Registration.Interfaces { - public interface IInitialBuilder : IControlFlow + public interface IInitialBuilder : IControlFlowBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IInputBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IInputBuilder.cs index 2a7e814c..4500543f 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IInputBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IInputBuilder.cs @@ -2,6 +2,6 @@ namespace Stateflows.Activities.Registration.Interfaces { - public interface IInputBuilder : IObjectFlow + public interface IInputBuilder : IObjectFlowBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IJoinBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IJoinBuilder.cs index d0d2c4b9..c69e7efa 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IJoinBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IJoinBuilder.cs @@ -2,6 +2,6 @@ namespace Stateflows.Activities.Registration.Interfaces { - public interface IJoinBuilder : IObjectFlow, IControlFlow + public interface IJoinBuilder : IObjectFlowBase, IControlFlowBase { } } \ No newline at end of file diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IMergeBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IMergeBuilder.cs index da8c89ed..45473d95 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IMergeBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IMergeBuilder.cs @@ -2,6 +2,6 @@ namespace Stateflows.Activities.Registration.Interfaces { - public interface IMergeBuilder : IObjectFlow, IControlFlow + public interface IMergeBuilder : IObjectFlowBase, IControlFlowBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IPublishEventActionBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IPublishEventActionBuilder.cs index 4d3158d0..74623f61 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IPublishEventActionBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IPublishEventActionBuilder.cs @@ -2,7 +2,7 @@ namespace Stateflows.Activities.Registration.Interfaces { - public interface IPublishEventActionBuilder : IControlFlow + public interface IPublishEventActionBuilder : IControlFlowBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IReactiveStructuredActivityBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IReactiveStructuredActivityBuilder.cs index 64f5e865..6bf884fd 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IReactiveStructuredActivityBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IReactiveStructuredActivityBuilder.cs @@ -3,14 +3,14 @@ namespace Stateflows.Activities.Registration.Interfaces { public interface IReactiveStructuredActivityBuilder : - IObjectFlow, - IControlFlow, + IObjectFlowBase, + IControlFlowBase, IReactiveActivity, IInitial, IFinal, IInput, IOutput, - IExceptionHandler, + IExceptionHandlerBase, INodeOptions, IStructuredActivityEvents, ISendEvent, @@ -18,14 +18,14 @@ public interface IReactiveStructuredActivityBuilder : { } public interface IReactiveStructuredActivityBuilderWithOptions : - IObjectFlow, - IControlFlow, + IObjectFlowBase, + IControlFlowBase, IReactiveActivity, IInitial, IFinal, IInput, IOutput, - IExceptionHandler, + IExceptionHandlerBase, IStructuredActivityEvents, ISendEvent, IAcceptEvent diff --git a/Core/Stateflows/Activities/Registration/Interfaces/ISendEventActionBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/ISendEventActionBuilder.cs index f0f226b8..3c40255d 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/ISendEventActionBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/ISendEventActionBuilder.cs @@ -2,7 +2,7 @@ namespace Stateflows.Activities.Registration.Interfaces { - public interface ISendEventActionBuilder : IControlFlow + public interface ISendEventActionBuilder : IControlFlowBase { } } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/IStructuredActivityBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/IStructuredActivityBuilder.cs index 2f712508..4803701b 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/IStructuredActivityBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/IStructuredActivityBuilder.cs @@ -3,28 +3,28 @@ namespace Stateflows.Activities.Registration.Interfaces { public interface IStructuredActivityBuilder : - IObjectFlow, - IControlFlow, + IObjectFlowBase, + IControlFlowBase, IActivity, IInitial, IFinal, IInput, IOutput, - IExceptionHandler, + IExceptionHandlerBase, INodeOptions, IStructuredActivityEvents, ISendEvent { } public interface IStructuredActivityBuilderWithOptions : - IObjectFlow, - IControlFlow, + IObjectFlowBase, + IControlFlowBase, IActivity, IInitial, IFinal, IInput, IOutput, - IExceptionHandler, + IExceptionHandlerBase, IStructuredActivityEvents, ISendEvent { } diff --git a/Core/Stateflows/Activities/Registration/Interfaces/ITimeEventBuilder.cs b/Core/Stateflows/Activities/Registration/Interfaces/ITimeEventBuilder.cs index b1dc8cda..f14d199b 100644 --- a/Core/Stateflows/Activities/Registration/Interfaces/ITimeEventBuilder.cs +++ b/Core/Stateflows/Activities/Registration/Interfaces/ITimeEventBuilder.cs @@ -2,6 +2,6 @@ namespace Stateflows.Activities.Registration.Interfaces { - public interface ITimeEventBuilder : IControlFlow + public interface ITimeEventBuilder : IControlFlowBase { } } diff --git a/Core/Stateflows/Activities/Registration/Policies/FinalizationResetPolicy.cs b/Core/Stateflows/Activities/Registration/Policies/FinalizationResetPolicy.cs new file mode 100644 index 00000000..5e561887 --- /dev/null +++ b/Core/Stateflows/Activities/Registration/Policies/FinalizationResetPolicy.cs @@ -0,0 +1,38 @@ +using System.Threading.Tasks; +using Stateflows.Common; +using Stateflows.Activities.Context.Interfaces; +using Stateflows.Activities.Registration.Interfaces; + +namespace Stateflows.Activities +{ + internal class ResetObserver : IActivityObserver + { + private readonly ResetMode resetMode; + + public ResetObserver(ResetMode resetMode) + { + this.resetMode = resetMode; + } + + public Task AfterActivityFinalizeAsync(IActivityFinalizationContext context) + { + var stateflowsContext = (context as IRootContext).Context.Context; + if (stateflowsContext.Stored) + { + context.Activity.Send(new ResetRequest() { Mode = resetMode }); + } + else + { + stateflowsContext.Deleted = true; + } + + return Task.CompletedTask; + } + } + + public static class FinalizationResetPolicy + { + public static IActivityBuilder AddFinalizationResetPolicy(this IActivityBuilder builder, ResetMode resetMode = ResetMode.Full) + => builder.AddObserver(_ => new ResetObserver(resetMode)); + } +} diff --git a/Core/Stateflows/Activities/StateMachines/Extensions/CompositeStateBuilderExtensions.cs b/Core/Stateflows/Activities/StateMachines/Extensions/CompositeStateBuilderExtensions.cs index 3d681a3a..51761704 100644 --- a/Core/Stateflows/Activities/StateMachines/Extensions/CompositeStateBuilderExtensions.cs +++ b/Core/Stateflows/Activities/StateMachines/Extensions/CompositeStateBuilderExtensions.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using System.Collections.Generic; using Stateflows.Common; using Stateflows.StateMachines.Sync; using Stateflows.Activities.Events; @@ -19,14 +18,14 @@ public static ICompositeStateBuilder AddOnEntryActivity(this ICompositeStateBuil { if (c.TryLocateActivity(activityName, Constants.Entry, out var a)) { - InitializationRequest initializationRequest = initializationBuilder?.Invoke(c); + Event initializationEvent = initializationBuilder?.Invoke(c) ?? new Initialize(); Task.Run(() => { var integratedActivityBuilder = new IntegratedActivityBuilder(buildAction); return a.SendCompoundAsync( integratedActivityBuilder.GetSubscriptionRequest(), - new ResetRequest() { KeepVersion = true }, - new ExecutionRequest(initializationRequest, new List()), + new ResetRequest() { Mode = ResetMode.KeepVersionAndSubscriptions }, + new ExecutionRequest() { InitializationEvent = initializationEvent }, integratedActivityBuilder.GetUnsubscriptionRequest() ); }); @@ -35,8 +34,8 @@ public static ICompositeStateBuilder AddOnEntryActivity(this ICompositeStateBuil ); public static ICompositeStateBuilder AddOnEntryActivity(this ICompositeStateBuilder builder, StateActionActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) - where TActivity : Activity - => AddOnEntryActivity(builder, ActivityInfo.Name, initializationBuilder, buildAction); + where TActivity : class, IActivity + => AddOnEntryActivity(builder, Activity.Name, initializationBuilder, buildAction); public static ICompositeStateBuilder AddOnExitActivity(this ICompositeStateBuilder builder, string activityName, StateActionActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) => builder @@ -45,14 +44,14 @@ public static ICompositeStateBuilder AddOnExitActivity(this ICompositeStateBuild { if (c.TryLocateActivity(activityName, Constants.Exit, out var a)) { - InitializationRequest initializationRequest = initializationBuilder?.Invoke(c); + Event initializationEvent = initializationBuilder?.Invoke(c) ?? new Initialize(); Task.Run(() => { var integratedActivityBuilder = new IntegratedActivityBuilder(buildAction); return a.SendCompoundAsync( integratedActivityBuilder.GetSubscriptionRequest(), - new ResetRequest() { KeepVersion = true }, - new ExecutionRequest(initializationRequest, new List()), + new ResetRequest() { Mode = ResetMode.KeepVersionAndSubscriptions }, + new ExecutionRequest() { InitializationEvent = initializationEvent }, integratedActivityBuilder.GetUnsubscriptionRequest() ); }); @@ -61,7 +60,7 @@ public static ICompositeStateBuilder AddOnExitActivity(this ICompositeStateBuild ); public static ICompositeStateBuilder AddOnExitActivity(this ICompositeStateBuilder builder, StateActionActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) - where TActivity : Activity - => AddOnExitActivity(builder, ActivityInfo.Name, initializationBuilder, buildAction); + where TActivity : class, IActivity + => AddOnExitActivity(builder, Activity.Name, initializationBuilder, buildAction); } } diff --git a/Core/Stateflows/Activities/StateMachines/Extensions/Delegates.cs b/Core/Stateflows/Activities/StateMachines/Extensions/Delegates.cs index f0b29d40..a3412d8d 100644 --- a/Core/Stateflows/Activities/StateMachines/Extensions/Delegates.cs +++ b/Core/Stateflows/Activities/StateMachines/Extensions/Delegates.cs @@ -4,12 +4,12 @@ namespace Stateflows.Activities.Extensions { - public delegate InitializationRequest StateActionActivityInitializationBuilder(IStateActionContext context); + public delegate Event StateActionActivityInitializationBuilder(IStateActionContext context); - public delegate InitializationRequest GuardActivityInitializationBuilder(IGuardContext context) + public delegate Event GuardActivityInitializationBuilder(IGuardContext context) where TEvent : Event, new(); - public delegate InitializationRequest EffectActivityInitializationBuilder(IEventContext context) + public delegate Event EffectActivityInitializationBuilder(IEventActionContext context) where TEvent : Event, new(); public delegate void IntegratedActivityBuildAction(IIntegratedActivityBuilder builder); diff --git a/Core/Stateflows/Activities/StateMachines/Extensions/IStateActionContextExtensions.cs b/Core/Stateflows/Activities/StateMachines/Extensions/IStateActionContextExtensions.cs index 7b4a2bfe..45bd4325 100644 --- a/Core/Stateflows/Activities/StateMachines/Extensions/IStateActionContextExtensions.cs +++ b/Core/Stateflows/Activities/StateMachines/Extensions/IStateActionContextExtensions.cs @@ -7,7 +7,7 @@ internal static class IStateActionContextExtensions public static string GetActivityInstance(this IStateActionContext context, string action) => $"{context.StateMachine.Id}.{context.CurrentState.Name}.{action}"; - public static bool TryLocateActivity(this IStateActionContext context, string activityName, string action, out IActivity activity) + public static bool TryLocateActivity(this IStateActionContext context, string activityName, string action, out IActivityBehavior activity) => context.TryLocateActivity(new ActivityId(activityName, context.GetActivityInstance(action)), out activity); } } diff --git a/Core/Stateflows/Activities/StateMachines/Extensions/ITransitionContextExtensions.cs b/Core/Stateflows/Activities/StateMachines/Extensions/ITransitionContextExtensions.cs index 61f25cfc..14aa442b 100644 --- a/Core/Stateflows/Activities/StateMachines/Extensions/ITransitionContextExtensions.cs +++ b/Core/Stateflows/Activities/StateMachines/Extensions/ITransitionContextExtensions.cs @@ -11,7 +11,7 @@ public static string GetDoActivityInstance(this ITransitionContext $"{context.StateMachine.Id}.{context.SourceState.Name}.{Constants.Do}"; - public static bool TryLocateDoActivity(this ITransitionContext context, string activityName, out IActivity activity) + public static bool TryLocateDoActivity(this ITransitionContext context, string activityName, out IActivityBehavior activity) where TEvent : Event, new() => context.TryLocateActivity(new ActivityId(activityName, context.GetDoActivityInstance()), out activity); @@ -19,7 +19,7 @@ public static string GetActivityInstance(this ITransitionContext where TEvent : Event, new() => $"{context.StateMachine.Id}.{context.SourceState.Name}.{action}.{new Random().Next()}"; - public static bool TryLocateActivity(this ITransitionContext context, string activityName, string action, out IActivity activity) + public static bool TryLocateActivity(this ITransitionContext context, string activityName, string action, out IActivityBehavior activity) where TEvent : Event, new() => context.TryLocateActivity(new ActivityId(activityName, context.GetActivityInstance(action)), out activity); } diff --git a/Core/Stateflows/Activities/StateMachines/Extensions/StateBuilderExtensions.cs b/Core/Stateflows/Activities/StateMachines/Extensions/StateBuilderExtensions.cs index bba13366..2f2f8608 100644 --- a/Core/Stateflows/Activities/StateMachines/Extensions/StateBuilderExtensions.cs +++ b/Core/Stateflows/Activities/StateMachines/Extensions/StateBuilderExtensions.cs @@ -21,15 +21,15 @@ public static IStateBuilder AddOnEntryActivity(this IStateBuilder builder, strin { if (c.TryLocateActivity(activityName, Constants.Entry, out var a)) { - InitializationRequest initializationRequest = initializationBuilder?.Invoke(c); + Event initializationEvent = initializationBuilder?.Invoke(c) ?? new Initialize(); Task.Run(() => { var integratedActivityBuilder = new IntegratedActivityBuilder(buildAction); return a.SendCompoundAsync( integratedActivityBuilder.GetSubscriptionRequest(), - new ResetRequest() { KeepVersion = true }, - new ExecutionRequest(initializationRequest, new List()), + new ResetRequest() { Mode = ResetMode.KeepVersionAndSubscriptions }, + new ExecutionRequest() { InitializationEvent = initializationEvent }, integratedActivityBuilder.GetUnsubscriptionRequest() ); }); @@ -38,8 +38,8 @@ public static IStateBuilder AddOnEntryActivity(this IStateBuilder builder, strin ); public static IStateBuilder AddOnEntryActivity(this IStateBuilder builder, StateActionActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) - where TActivity : Activity - => AddOnEntryActivity(builder, ActivityInfo.Name, initializationBuilder, buildAction); + where TActivity : class, IActivity + => AddOnEntryActivity(builder, Activity.Name, initializationBuilder, buildAction); public static IStateBuilder AddOnExitActivity(this IStateBuilder builder, string activityName, StateActionActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) => builder @@ -48,36 +48,24 @@ public static IStateBuilder AddOnExitActivity(this IStateBuilder builder, string { if (c.TryLocateActivity(activityName, Constants.Exit, out var a)) { - InitializationRequest initializationRequest = initializationBuilder?.Invoke(c); + Event initializationEvent = initializationBuilder?.Invoke(c) ?? new Initialize(); Task.Run(() => { var integratedActivityBuilder = new IntegratedActivityBuilder(buildAction); return a.SendCompoundAsync( integratedActivityBuilder.GetSubscriptionRequest(), - new ResetRequest() { KeepVersion = true }, - new ExecutionRequest(initializationRequest, new List()), + new ResetRequest() { Mode = ResetMode.KeepVersionAndSubscriptions }, + new ExecutionRequest() { InitializationEvent = initializationEvent }, integratedActivityBuilder.GetUnsubscriptionRequest() ); - //var request = new CompoundRequest() - //{ - // Events = new List() - // { - // integratedActivityBuilder.GetSubscriptionRequest(), - // new ResetRequest() { KeepVersion = true }, - // new ExecutionRequest(initializationRequest, new List()), - // integratedActivityBuilder.GetUnsubscriptionRequest(), - // } - //}; - - //return a.RequestAsync(request); }); } } ); public static IStateBuilder AddOnExitActivity(this IStateBuilder builder, StateActionActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) - where TActivity : Activity - => AddOnExitActivity(builder, ActivityInfo.Name, initializationBuilder, buildAction); + where TActivity : class, IActivity + => AddOnExitActivity(builder, Activity.Name, initializationBuilder, buildAction); } } diff --git a/Core/Stateflows/Activities/StateMachines/Extensions/TransitionBuilderExtensions.cs b/Core/Stateflows/Activities/StateMachines/Extensions/TransitionBuilderExtensions.cs index 2bb867f7..7b5c72f5 100644 --- a/Core/Stateflows/Activities/StateMachines/Extensions/TransitionBuilderExtensions.cs +++ b/Core/Stateflows/Activities/StateMachines/Extensions/TransitionBuilderExtensions.cs @@ -1,9 +1,12 @@ using System.Linq; using System.Diagnostics; +using System.Threading.Tasks; using Stateflows.Common; using Stateflows.Activities.Extensions; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.Activities.StateMachines.Interfaces; +using Stateflows.Activities.Events; namespace Stateflows.Activities { @@ -11,39 +14,73 @@ public static class TransitionBuilderExtensions { #region AddGuardActivity [DebuggerHidden] - public static ITransitionBuilder AddGuardActivity(this ITransitionBuilder builder, string activityName, GuardActivityInitializationBuilder parametersBuilder = null) + public static ITransitionBuilder AddGuardActivity(this ITransitionBuilder builder, string activityName, GuardActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) where TEvent : Event, new() => builder.AddGuard( - async c => c.TryLocateActivity(activityName, Constants.Guard, out var a) - && ((await a.ExecuteAsync(parametersBuilder?.Invoke(c), new object[] { c.Event })).Response?.OutputTokens.OfType().FirstOrDefault() ?? false) + async c => + { + var result = false; + if (c.TryLocateActivity(activityName, Constants.Entry, out var a)) + { + Event initializationEvent = initializationBuilder?.Invoke(c) ?? new Initialize(); + await Task.Run(async () => + { + var integratedActivityBuilder = new IntegratedActivityBuilder(buildAction); + var sendResult = await a.SendCompoundAsync( + integratedActivityBuilder.GetSubscriptionRequest(), + new ResetRequest() { Mode = ResetMode.KeepVersionAndSubscriptions }, + new ExecutionRequest() { InitializationEvent = initializationEvent }, + integratedActivityBuilder.GetUnsubscriptionRequest() + ); + + result = (sendResult.Response.Results.Skip(2).Take(1).First().Response as ExecutionResponse).OutputTokens.OfType>().FirstOrDefault()?.Payload ?? false; + }); + } + + return result; + } ); [DebuggerHidden] - public static ITransitionBuilder AddGuardActivity(this ITransitionBuilder builder, GuardActivityInitializationBuilder parametersBuilder = null) + public static ITransitionBuilder AddGuardActivity(this ITransitionBuilder builder, GuardActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) where TEvent : Event, new() - where TActivity : Activity - => builder.AddGuardActivity(ActivityInfo.Name, parametersBuilder); + where TActivity : class, IActivity + => builder.AddGuardActivity(Activity.Name, initializationBuilder); #endregion #region AddEffectActivity [DebuggerHidden] - public static ITransitionBuilder AddEffectActivity(this ITransitionBuilder builder, string activityName, EffectActivityInitializationBuilder parametersBuilder = null) + public static ITransitionBuilder AddEffectActivity(this ITransitionBuilder builder, string activityName, EffectActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) where TEvent : Event, new() => builder.AddEffect( - async c => + c => { - if (c.TryLocateActivity(activityName, Constants.Guard, out var a)) + if (c.TryLocateActivity(activityName, Constants.Entry, out var a)) { - await a.ExecuteAsync(parametersBuilder?.Invoke(c), new object[] { c.Event }); + Event initializationEvent = initializationBuilder?.Invoke(c) ?? new Initialize(); + return Task.Run(() => + { + var integratedActivityBuilder = new IntegratedActivityBuilder(buildAction); + return a.SendCompoundAsync( + integratedActivityBuilder.GetSubscriptionRequest(), + new ResetRequest() { Mode = ResetMode.KeepVersionAndSubscriptions }, + new ExecutionRequest() { InitializationEvent = initializationEvent }, + integratedActivityBuilder.GetUnsubscriptionRequest() + ); + }); } + else + { + return Task.CompletedTask; + } } ); [DebuggerHidden] - public static ITransitionBuilder AddEffectActivity(this ITransitionBuilder builder, EffectActivityInitializationBuilder parametersBuilder = null) + public static ITransitionBuilder AddEffectActivity(this ITransitionBuilder builder, EffectActivityInitializationBuilder initializationBuilder = null, IntegratedActivityBuildAction buildAction = null) where TEvent : Event, new() - where TActivity : Activity - => builder.AddEffectActivity(ActivityInfo.Name, parametersBuilder); + where TActivity : class, IActivity + => builder.AddEffectActivity(Activity.Name, initializationBuilder); #endregion } } \ No newline at end of file diff --git a/Core/Stateflows/Activities/StateMachines/Extensions/TypedCompositeStateBuilderExtensions.cs b/Core/Stateflows/Activities/StateMachines/Extensions/TypedCompositeStateBuilderExtensions.cs index e22ba358..fb32036c 100644 --- a/Core/Stateflows/Activities/StateMachines/Extensions/TypedCompositeStateBuilderExtensions.cs +++ b/Core/Stateflows/Activities/StateMachines/Extensions/TypedCompositeStateBuilderExtensions.cs @@ -9,14 +9,14 @@ public static ITypedCompositeStateBuilder AddOnEntryActivity(this ITypedComposit => (builder as ICompositeStateBuilder).AddOnEntryActivity(activityName, parametersBuilder, buildAction) as ITypedCompositeStateBuilder; public static ITypedCompositeStateBuilder AddOnEntryActivity(this ITypedCompositeStateBuilder builder, StateActionActivityInitializationBuilder parametersBuilder = null, IntegratedActivityBuildAction buildAction = null) - where TActivity : Activity + where TActivity : class, IActivity => (builder as ICompositeStateBuilder).AddOnEntryActivity(parametersBuilder, buildAction) as ITypedCompositeStateBuilder; public static ITypedCompositeStateBuilder AddOnExitActivity(this ITypedCompositeStateBuilder builder, string activityName, StateActionActivityInitializationBuilder parametersBuilder = null, IntegratedActivityBuildAction buildAction = null) => (builder as ICompositeStateBuilder).AddOnExitActivity(activityName, parametersBuilder, buildAction) as ITypedCompositeStateBuilder; public static ITypedCompositeStateBuilder AddOnExitActivity(this ITypedCompositeStateBuilder builder, StateActionActivityInitializationBuilder parametersBuilder = null, IntegratedActivityBuildAction buildAction = null) - where TActivity : Activity + where TActivity : class, IActivity => (builder as ICompositeStateBuilder).AddOnExitActivity(parametersBuilder, buildAction) as ITypedCompositeStateBuilder; } } diff --git a/Core/Stateflows/Activities/StateMachines/Extensions/TypedStateBuilderExtensions.cs b/Core/Stateflows/Activities/StateMachines/Extensions/TypedStateBuilderExtensions.cs index b4b38018..b57e71fa 100644 --- a/Core/Stateflows/Activities/StateMachines/Extensions/TypedStateBuilderExtensions.cs +++ b/Core/Stateflows/Activities/StateMachines/Extensions/TypedStateBuilderExtensions.cs @@ -9,14 +9,14 @@ public static ITypedStateBuilder AddOnEntryActivity(this ITypedStateBuilder buil => (builder as IStateBuilder).AddOnEntryActivity(activityName, parametersBuilder, buildAction) as ITypedStateBuilder; public static ITypedStateBuilder AddOnEntryActivity(this ITypedStateBuilder builder, StateActionActivityInitializationBuilder parametersBuilder = null, IntegratedActivityBuildAction buildAction = null) - where TActivity : Activity + where TActivity : class, IActivity => (builder as IStateBuilder).AddOnEntryActivity(parametersBuilder, buildAction) as ITypedStateBuilder; public static ITypedStateBuilder AddOnExitActivity(this ITypedStateBuilder builder, string activityName, StateActionActivityInitializationBuilder parametersBuilder = null, IntegratedActivityBuildAction buildAction = null) => (builder as IStateBuilder).AddOnExitActivity(activityName, parametersBuilder, buildAction) as ITypedStateBuilder; public static ITypedStateBuilder AddOnExitActivity(this ITypedStateBuilder builder, StateActionActivityInitializationBuilder parametersBuilder = null, IntegratedActivityBuildAction buildAction = null) - where TActivity : Activity + where TActivity : class, IActivity => (builder as IStateBuilder).AddOnExitActivity(parametersBuilder, buildAction) as ITypedStateBuilder; } } diff --git a/Core/Stateflows/Activities/Streams/Stream.cs b/Core/Stateflows/Activities/Streams/Stream.cs index 7d55f591..4c062fb8 100644 --- a/Core/Stateflows/Activities/Streams/Stream.cs +++ b/Core/Stateflows/Activities/Streams/Stream.cs @@ -24,7 +24,7 @@ public void Consume(IEnumerable tokens, bool isPersistent) public void Consume(TokenHolder token) { - if (token is TokenHolder) + if (token is TokenHolder) { IsActivated = true; } diff --git a/Core/Stateflows/Activities/Tokens/Control.cs b/Core/Stateflows/Activities/Tokens/Control.cs deleted file mode 100644 index dd220ae2..00000000 --- a/Core/Stateflows/Activities/Tokens/Control.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Stateflows.Activities -{ - public sealed class Control - { } -} diff --git a/Core/Stateflows/Activities/Interfaces/INodeInterface.cs b/Core/Stateflows/Activities/Tokens/ControlToken.cs similarity index 55% rename from Core/Stateflows/Activities/Interfaces/INodeInterface.cs rename to Core/Stateflows/Activities/Tokens/ControlToken.cs index 6654e054..60d39450 100644 --- a/Core/Stateflows/Activities/Interfaces/INodeInterface.cs +++ b/Core/Stateflows/Activities/Tokens/ControlToken.cs @@ -1,5 +1,5 @@ namespace Stateflows.Activities { - public interface INodeInterface + public sealed class ControlToken { } } diff --git a/Core/Stateflows/Activities/Tokens/NodeReference.cs b/Core/Stateflows/Activities/Tokens/NodeReferenceToken.cs similarity index 73% rename from Core/Stateflows/Activities/Tokens/NodeReference.cs rename to Core/Stateflows/Activities/Tokens/NodeReferenceToken.cs index f6023a9a..8656523d 100644 --- a/Core/Stateflows/Activities/Tokens/NodeReference.cs +++ b/Core/Stateflows/Activities/Tokens/NodeReferenceToken.cs @@ -2,7 +2,7 @@ namespace Stateflows.Activities { - internal sealed class NodeReference + internal sealed class NodeReferenceToken { public Node Node { get; set; } } diff --git a/Core/Stateflows/Common/Classes/BaseValueAccessor.cs b/Core/Stateflows/Common/Classes/BaseValueAccessor.cs index a4790e7f..f979695d 100644 --- a/Core/Stateflows/Common/Classes/BaseValueAccessor.cs +++ b/Core/Stateflows/Common/Classes/BaseValueAccessor.cs @@ -1,18 +1,9 @@ using System; -using System.Threading; using Stateflows.Common.Interfaces; using Stateflows.Common.Exceptions; namespace Stateflows.Common.Classes { - public static class ContextValuesHolder - { - public static readonly AsyncLocal GlobalValues = new AsyncLocal(); - public static readonly AsyncLocal StateValues = new AsyncLocal(); - public static readonly AsyncLocal SourceStateValues = new AsyncLocal(); - public static readonly AsyncLocal TargetStateValues = new AsyncLocal(); - } - public class BaseValueAccessor { private readonly string valueName; diff --git a/Core/Stateflows/Common/Classes/Behavior.cs b/Core/Stateflows/Common/Classes/Behavior.cs index 91467b14..bfce2188 100644 --- a/Core/Stateflows/Common/Classes/Behavior.cs +++ b/Core/Stateflows/Common/Classes/Behavior.cs @@ -4,6 +4,8 @@ using Microsoft.Extensions.DependencyInjection; using Stateflows.Common.Utilities; using Stateflows.Common.Subscription; +using System.Linq; +using System.Diagnostics; namespace Stateflows.Common.Classes { @@ -44,6 +46,7 @@ private void SubscriptionHub_OnPublish(Notification notification) } } + [DebuggerHidden] public async Task SendAsync(TEvent @event) where TEvent : Event, new() { @@ -53,6 +56,7 @@ public async Task SendAsync(TEvent @event) return new SendResult(@event, holder.Status, holder.Validation); } + [DebuggerHidden] public async Task> RequestAsync(Request request) where TResponse : Response, new() { diff --git a/Core/Stateflows/Common/Classes/ContextValues.cs b/Core/Stateflows/Common/Classes/ContextValues.cs index 13217be4..32f8510f 100644 --- a/Core/Stateflows/Common/Classes/ContextValues.cs +++ b/Core/Stateflows/Common/Classes/ContextValues.cs @@ -1,118 +1,25 @@ -using Newtonsoft.Json.Linq; -using Stateflows.Common.Interfaces; -using Stateflows.Common.Utilities; +using System.Threading; using System.Collections.Generic; +using Stateflows.Common.Interfaces; namespace Stateflows.Common.Classes { - public class ContextValues : IContextValues + public static class ContextValues { - public Dictionary Values { get; } - - public ContextValues(Dictionary values) - { - Values = values; - } - - public void Set(string key, T value) - { - lock (Values) - { - Values[key] = StateflowsJsonConverter.SerializePolymorphicObject(value); - } - } - - public bool IsSet(string key) - { - bool result; - - lock (Values) - { - result = Values.ContainsKey(key); - } - - return result; - } - - public bool TryGet(string key, out T value) - { - value = default; - - lock (Values) - { - if (Values.TryGetValue(key, out var data)) - { - var type = typeof(T); - var deserializedData = type.IsPrimitive - ? ParseStringToTypedValue(data) - : type.IsEnum - ? ParseStringToEnum(data) - : StateflowsJsonConverter.DeserializeObject(data); - - if (deserializedData is T t) - { - value = t; - - return true; - } - } - } - - return false; - } - - public T GetOrDefault(string key, T defaultValue) - { - lock (Values) - { - if (Values.TryGetValue(key, out var data)) - { - var type = typeof(T); - var deserializedData = type.IsPrimitive - ? ParseStringToTypedValue(data) - : type.IsEnum - ? ParseStringToEnum(data) - : StateflowsJsonConverter.DeserializeObject(data); - - if (deserializedData is T t) - { - return t; - } - } - } - - return defaultValue; - } - - public void Remove(string key) - { - lock (Values) - { - Values.Remove(key); - } - } - - public void Clear() - { - lock (Values) - { - Values.Clear(); - } - } + internal static readonly AsyncLocal GlobalValuesHolder = new AsyncLocal(); + public static IContextValues GlobalValues + => GlobalValuesHolder.Value ??= new ContextValuesCollection(new Dictionary()); - private static T ParseStringToEnum(string value) - { - return (T)(object)JToken.Parse(value).Value(); - } + internal static readonly AsyncLocal StateValuesHolder = new AsyncLocal(); + public static IContextValues StateValues + => StateValuesHolder.Value ??= new ContextValuesCollection(new Dictionary()); - private static T ParseStringToTypedValue(string value) - { - if (typeof(T) == typeof(string)) - { - return JToken.Parse($"\"{value}\"").Value(); - } + internal static readonly AsyncLocal SourceStateValuesHolder = new AsyncLocal(); + public static IContextValues SourceStateValues + => SourceStateValuesHolder.Value ??= new ContextValuesCollection(new Dictionary()); - return JToken.Parse(value).Value(); - } + internal static readonly AsyncLocal TargetStateValuesHolder = new AsyncLocal(); + public static IContextValues TargetStateValues + => TargetStateValuesHolder.Value ??= new ContextValuesCollection(new Dictionary()); } } diff --git a/Core/Stateflows/Common/Classes/ContextValuesCollection.cs b/Core/Stateflows/Common/Classes/ContextValuesCollection.cs new file mode 100644 index 00000000..445328ce --- /dev/null +++ b/Core/Stateflows/Common/Classes/ContextValuesCollection.cs @@ -0,0 +1,118 @@ +using Newtonsoft.Json.Linq; +using Stateflows.Common.Interfaces; +using Stateflows.Common.Utilities; +using System.Collections.Generic; + +namespace Stateflows.Common.Classes +{ + internal class ContextValuesCollection : IContextValues + { + public Dictionary Values { get; } + + public ContextValuesCollection(Dictionary values) + { + Values = values; + } + + public void Set(string key, T value) + { + lock (Values) + { + Values[key] = StateflowsJsonConverter.SerializePolymorphicObject(value); + } + } + + public bool IsSet(string key) + { + bool result; + + lock (Values) + { + result = Values.ContainsKey(key); + } + + return result; + } + + public bool TryGet(string key, out T value) + { + value = default; + + lock (Values) + { + if (Values.TryGetValue(key, out var data)) + { + var type = typeof(T); + var deserializedData = type.IsPrimitive + ? ParseStringToTypedValue(data) + : type.IsEnum + ? ParseStringToEnum(data) + : StateflowsJsonConverter.DeserializeObject(data); + + if (deserializedData is T t) + { + value = t; + + return true; + } + } + } + + return false; + } + + public T GetOrDefault(string key, T defaultValue) + { + lock (Values) + { + if (Values.TryGetValue(key, out var data)) + { + var type = typeof(T); + var deserializedData = type.IsPrimitive + ? ParseStringToTypedValue(data) + : type.IsEnum + ? ParseStringToEnum(data) + : StateflowsJsonConverter.DeserializeObject(data); + + if (deserializedData is T t) + { + return t; + } + } + } + + return defaultValue; + } + + public void Remove(string key) + { + lock (Values) + { + Values.Remove(key); + } + } + + public void Clear() + { + lock (Values) + { + Values.Clear(); + } + } + + private static T ParseStringToEnum(string value) + { + return (T)(object)JToken.Parse(value).Value(); + } + + private static T ParseStringToTypedValue(string value) + { + if (typeof(T) == typeof(string)) + { + return JToken.Parse($"\"{value}\"").Value(); + } + + return JToken.Parse(value).Value(); + } + } +} diff --git a/Core/Stateflows/Common/Classes/EventHolder.cs b/Core/Stateflows/Common/Classes/EventHolder.cs index d70e7faa..d89b24f2 100644 --- a/Core/Stateflows/Common/Classes/EventHolder.cs +++ b/Core/Stateflows/Common/Classes/EventHolder.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading; namespace Stateflows.Common.Classes @@ -15,6 +16,8 @@ internal class EventHolder public EventStatus Status { get; set; } + public List Exceptions { get; set; } = new List(); + public EventValidation Validation { get; internal set; } public EventHolder(BehaviorId targetId, Event @event, IServiceProvider serviceProvider) diff --git a/Core/Stateflows/Common/Classes/GlobalValueAccessors.cs b/Core/Stateflows/Common/Classes/GlobalValueAccessors.cs index eb724ae7..c63adb57 100644 --- a/Core/Stateflows/Common/Classes/GlobalValueAccessors.cs +++ b/Core/Stateflows/Common/Classes/GlobalValueAccessors.cs @@ -4,7 +4,7 @@ namespace Stateflows.Common { public class GlobalValue : BaseValueAccessor { - public GlobalValue(string valueName) : base(valueName, () => ContextValuesHolder.GlobalValues.Value, nameof(ContextValuesHolder.GlobalValues)) + public GlobalValue(string valueName) : base(valueName, () => ContextValues.GlobalValuesHolder.Value, nameof(ContextValues.GlobalValuesHolder)) { } } } diff --git a/Core/Stateflows/Common/Classes/ValueAccessors.cs b/Core/Stateflows/Common/Classes/ValueAccessors.cs index aefd2c6d..bd37e976 100644 --- a/Core/Stateflows/Common/Classes/ValueAccessors.cs +++ b/Core/Stateflows/Common/Classes/ValueAccessors.cs @@ -4,19 +4,19 @@ namespace Stateflows.StateMachines { public class StateValue : BaseValueAccessor { - public StateValue(string valueName) : base(valueName, () => ContextValuesHolder.StateValues.Value, nameof(ContextValuesHolder.StateValues)) + public StateValue(string valueName) : base(valueName, () => ContextValues.StateValuesHolder.Value, nameof(ContextValues.StateValuesHolder)) { } } public class SourceStateValue : BaseValueAccessor { - public SourceStateValue(string valueName) : base(valueName, () => ContextValuesHolder.SourceStateValues.Value, nameof(ContextValuesHolder.SourceStateValues)) + public SourceStateValue(string valueName) : base(valueName, () => ContextValues.SourceStateValuesHolder.Value, nameof(ContextValues.SourceStateValuesHolder)) { } } public class TargetStateValue : BaseValueAccessor { - public TargetStateValue(string valueName) : base(valueName, () => ContextValuesHolder.TargetStateValues.Value, nameof(ContextValuesHolder.TargetStateValues)) + public TargetStateValue(string valueName) : base(valueName, () => ContextValues.TargetStateValuesHolder.Value, nameof(ContextValues.TargetStateValuesHolder)) { } } } diff --git a/Core/Stateflows/Common/Context/Classes/BehaviorContext.cs b/Core/Stateflows/Common/Context/Classes/BehaviorContext.cs index 3a40aece..3a830784 100644 --- a/Core/Stateflows/Common/Context/Classes/BehaviorContext.cs +++ b/Core/Stateflows/Common/Context/Classes/BehaviorContext.cs @@ -19,7 +19,7 @@ private BehaviorSubscriber Subscriber public BehaviorContext(StateflowsContext context, IServiceProvider serviceProvider) : base(context, serviceProvider) { - Values = new ContextValues(Context.GlobalValues); + Values = new ContextValuesCollection(Context.GlobalValues); } public IContextValues Values { get; } diff --git a/Core/Stateflows/Common/Engine/StateflowsEngine.cs b/Core/Stateflows/Common/Engine/StateflowsEngine.cs index 25275c9d..99047bb2 100644 --- a/Core/Stateflows/Common/Engine/StateflowsEngine.cs +++ b/Core/Stateflows/Common/Engine/StateflowsEngine.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Threading; +using System.Diagnostics; using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.Extensions.Hosting; @@ -13,7 +14,7 @@ namespace Stateflows.Common { - internal class StateflowsEngine : BackgroundService, IHostedService + internal class StateflowsEngine : /*BackgroundService, */IHostedService { private readonly IServiceScope Scope; private IServiceProvider ServiceProvider => Scope.ServiceProvider; @@ -28,6 +29,8 @@ private Dictionary Processors private EventQueue EventQueue { get; } = new EventQueue(true); + private Task executionTask; + public StateflowsEngine(IServiceProvider serviceProvider) { Scope = serviceProvider.CreateScope(); @@ -49,80 +52,106 @@ public EventHolder EnqueueEvent(BehaviorId id, Event @event, IServiceProvider se return token; } - public override Task StartAsync(CancellationToken cancellationToken) + [DebuggerHidden] + public Task StartAsync(CancellationToken cancellationToken) { - return base.StartAsync(cancellationToken); + executionTask = Task.Run(() => + { + while (!cancellationToken.IsCancellationRequested) + { + EventQueue.WaitAsync().GetAwaiter().GetResult(); + + var token = EventQueue.Dequeue(); + + if (token != null) + { + _ = Task.Run(() => + { + token.Validation = token.Event.Validate(); + + var status = EventStatus.Invalid; + + try + { + if (token.Validation.IsValid) + { + status = ProcessEventAsync(token.TargetId, token.Event, token.ServiceProvider, token.Exceptions) + .GetAwaiter() + .GetResult(); + } + + token.Status = token.Validation.IsValid + ? status + : EventStatus.Invalid; + + token.Handled.Set(); + } + catch (Exception) + { + try + { + throw; + } + finally + { + token.Status = EventStatus.Failed; + + token.Handled.Set(); + } + } + }); + } + } + }); + + return Task.CompletedTask; } - public async Task ProcessEventAsync(BehaviorId id, TEvent @event, IServiceProvider serviceProvider) + //[DebuggerHidden] + public async Task ProcessEventAsync(BehaviorId id, TEvent @event, IServiceProvider serviceProvider, List exceptions) where TEvent : Event, new() { - var result = EventStatus.Undelivered; if (Processors.TryGetValue(id.Type, out var processor)) { - try + if (Interceptor.BeforeExecute(@event)) { - if (Interceptor.BeforeExecute(@event)) - { - TenantAccessor.CurrentTenantId = await TenantProvider.GetCurrentTenantIdAsync(); + TenantAccessor.CurrentTenantId = await TenantProvider.GetCurrentTenantIdAsync(); - await using var lockHandle = await Lock.AquireLockAsync(id); + await using var lockHandle = await Lock.AquireLockAsync(id); + try + { try { - try - { - result = await processor.ProcessEventAsync(id, @event, serviceProvider); - } - finally - { - var response = @event.GetResponse(); - if (response != null) - { - response.SenderId = id; - response.SentAt = DateTime.Now; - } - } + result = await processor.ProcessEventAsync(id, @event, serviceProvider, exceptions); } finally { - Interceptor.AfterExecute(@event); + var response = @event.GetResponse(); + if (response != null) + { + response.SenderId = id; + response.SentAt = DateTime.Now; + } } } - } - catch (Exception e) - { - Logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(StateflowsEngine).FullName, nameof(ProcessEventAsync), e.GetType().Name, e.Message); + finally + { + Interceptor.AfterExecute(@event); + } } } return result; } - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + public Task StopAsync(CancellationToken cancellationToken) { - while (!stoppingToken.IsCancellationRequested) - { - await EventQueue.WaitAsync(); - - var token = EventQueue.Dequeue(); + executionTask.Wait(); - if (token != null) - { - _ = Task.Run(async () => - { - token.Validation = token.Event.Validate(); - - token.Status = token.Validation.IsValid - ? await ProcessEventAsync(token.TargetId, token.Event, token.ServiceProvider) - : EventStatus.Invalid; - - token.Handled.Set(); - }); - } - } + return Task.CompletedTask; } } } diff --git a/Core/Stateflows/Common/Extensions/MethodInfoExtensions.cs b/Core/Stateflows/Common/Extensions/MethodInfoExtensions.cs index 14728c9b..27210556 100644 --- a/Core/Stateflows/Common/Extensions/MethodInfoExtensions.cs +++ b/Core/Stateflows/Common/Extensions/MethodInfoExtensions.cs @@ -32,6 +32,54 @@ public static bool IsOverridenIn(this MethodInfo baseMethod) where TType : class => baseMethod.IsOverridenIn(typeof(TType)); + public static bool IsImplementedIn(this MethodInfo baseMethod, Type type) + { + if (baseMethod == null) + throw new ArgumentNullException("baseMethod"); + if (type == null) + throw new ArgumentNullException("type"); + if (!baseMethod.ReflectedType.IsAssignableFrom(type)) + throw new ArgumentException(string.Format("Type must implement interface {0}", baseMethod.DeclaringType)); + while (type != baseMethod.ReflectedType) + { + if (!type.GetInterfaceMap(baseMethod.DeclaringType).TargetMethods.Any(m => m.GetBaseDefinition() == baseMethod)) + return true; + type = type.BaseType; + + if (!baseMethod.ReflectedType.IsAssignableFrom(type)) + break; + } + return false; + } + + public static bool IsImplementedIn(this MethodInfo baseMethod) + where TType : class + => baseMethod.IsImplementedIn(typeof(TType)); + + public static bool IsImplementedIn(this PropertyInfo baseProperty, Type type) + { + if (baseProperty == null) + throw new ArgumentNullException("baseProperty"); + if (type == null) + throw new ArgumentNullException("type"); + if (!baseProperty.ReflectedType.IsAssignableFrom(type)) + throw new ArgumentException(string.Format("Type must implement interface {0}", baseProperty.DeclaringType)); + while (type != baseProperty.ReflectedType) + { + if (!type.GetInterfaceMap(baseProperty.DeclaringType).TargetMethods.Any(m => m.GetBaseDefinition() == baseProperty)) + return true; + type = type.BaseType; + + if (!baseProperty.ReflectedType.IsAssignableFrom(type)) + break; + } + return false; + } + + public static bool IsImplementedIn(this PropertyInfo baseProperty) + where TType : class + => baseProperty.IsImplementedIn(typeof(TType)); + public static bool IsOverridenIn(this PropertyInfo baseProperty, Type type) { if (baseProperty == null) diff --git a/Core/Stateflows/Common/Initializer/AutoInitializationToken.cs b/Core/Stateflows/Common/Initializer/AutoInitializationToken.cs deleted file mode 100644 index 0640d422..00000000 --- a/Core/Stateflows/Common/Initializer/AutoInitializationToken.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Stateflows.Common.Initializer -{ - internal class AutoInitializationToken - { - public BehaviorClass BehaviorClass { get; private set; } - - public AutoInitializationRequestFactoryAsync InitializationRequestFactory { get; } - - public AutoInitializationToken(BehaviorClass behaviorClass, AutoInitializationRequestFactoryAsync initializationRequestFactoryAsync) - { - BehaviorClass = behaviorClass; - InitializationRequestFactory = initializationRequestFactoryAsync; - } - - public void RefreshEnvironment() - { - BehaviorClass = new BehaviorClass(BehaviorClass.Type, BehaviorClass.Name); - } - } -} \ No newline at end of file diff --git a/Core/Stateflows/Common/Initializer/BehaviorClassesInitializations.cs b/Core/Stateflows/Common/Initializer/BehaviorClassesInitializations.cs index 68d6954f..3fb702a1 100644 --- a/Core/Stateflows/Common/Initializer/BehaviorClassesInitializations.cs +++ b/Core/Stateflows/Common/Initializer/BehaviorClassesInitializations.cs @@ -1,6 +1,5 @@ -using System; +using System.Threading.Tasks; using System.Collections.Generic; -using System.Threading.Tasks; namespace Stateflows.Common.Initializer { @@ -10,29 +9,9 @@ internal class BehaviorClassesInitializations public readonly List DefaultInstanceInitializationTokens = new List(); - private static readonly DefaultInstanceInitializationRequestFactoryAsync DefaultDefaultInstanceFactory = (serviceProvider, behaviorClass) => Task.FromResult(new InitializationRequest()); + private static readonly DefaultInstanceInitializationRequestFactoryAsync DefaultDefaultInstanceFactory = (serviceProvider, behaviorClass) => Task.FromResult(new Initialize() as Event); public void AddDefaultInstanceInitialization(BehaviorClass behaviorClass, DefaultInstanceInitializationRequestFactoryAsync initializationRequestFactory = null) => DefaultInstanceInitializationTokens.Add(new DefaultInstanceInitializationToken(behaviorClass, initializationRequestFactory ?? DefaultDefaultInstanceFactory)); - - public readonly List AutoInitializationTokens = new List(); - - private static readonly AutoInitializationRequestFactoryAsync DefaultAutoFactory = (serviceProvider, behaviorClass) => Task.FromResult(new InitializationRequest()); - - public void AddAutoInitialization(BehaviorClass behaviorClass, AutoInitializationRequestFactoryAsync initializationRequestFactory = null) - => AutoInitializationTokens.Add(new AutoInitializationToken(behaviorClass, initializationRequestFactory ?? DefaultAutoFactory)); - - public void RefreshEnvironment() - { - foreach (var token in DefaultInstanceInitializationTokens) - { - token.RefreshEnvironment(); - } - - foreach (var token in AutoInitializationTokens) - { - token.RefreshEnvironment(); - } - } } } diff --git a/Core/Stateflows/Common/Initializer/InitializationRequestFactory.cs b/Core/Stateflows/Common/Initializer/InitializationRequestFactory.cs index 292d26cc..2c6ded8d 100644 --- a/Core/Stateflows/Common/Initializer/InitializationRequestFactory.cs +++ b/Core/Stateflows/Common/Initializer/InitializationRequestFactory.cs @@ -4,8 +4,5 @@ namespace Stateflows.Common.Initializer { - public delegate Task DefaultInstanceInitializationRequestFactoryAsync(IServiceProvider serviceProvider, BehaviorClass behaviorClass); -#nullable enable - public delegate Task AutoInitializationRequestFactoryAsync(IServiceProvider serviceProvider, BehaviorId behaviorId); -#nullable disable + public delegate Task DefaultInstanceInitializationRequestFactoryAsync(IServiceProvider serviceProvider, BehaviorClass behaviorClass); } \ No newline at end of file diff --git a/Core/Stateflows/Common/Initializer/ThreadInitializer.cs b/Core/Stateflows/Common/Initializer/ThreadInitializer.cs index 9a196073..a99b6997 100644 --- a/Core/Stateflows/Common/Initializer/ThreadInitializer.cs +++ b/Core/Stateflows/Common/Initializer/ThreadInitializer.cs @@ -3,9 +3,8 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Stateflows.Common.Tenant; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; namespace Stateflows.Common.Initializer { @@ -52,7 +51,7 @@ await Task.WhenAll( if (Locator.TryLocateBehavior(new BehaviorId(token.BehaviorClass, string.Empty), out var behavior)) { - await behavior.InitializeAsync(await token.InitializationRequestFactory(ServiceProvider, token.BehaviorClass)); + await behavior.SendAsync(await token.InitializationRequestFactory(ServiceProvider, token.BehaviorClass)); } }) ); diff --git a/Core/Stateflows/Common/Interfaces/IEventProcessor.cs b/Core/Stateflows/Common/Interfaces/IEventProcessor.cs index 1e050154..637e0c0f 100644 --- a/Core/Stateflows/Common/Interfaces/IEventProcessor.cs +++ b/Core/Stateflows/Common/Interfaces/IEventProcessor.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; namespace Stateflows.Common.Interfaces @@ -7,7 +8,7 @@ internal interface IEventProcessor { string BehaviorType { get; } - Task ProcessEventAsync(BehaviorId id, TEvent @event, IServiceProvider serviceProvider) + Task ProcessEventAsync(BehaviorId id, TEvent @event, IServiceProvider serviceProvider, List exceptions) where TEvent : Event, new(); } } diff --git a/Core/Stateflows/Common/Interfaces/IInitializedBy.cs b/Core/Stateflows/Common/Interfaces/IInitializedBy.cs deleted file mode 100644 index 4150c4e8..00000000 --- a/Core/Stateflows/Common/Interfaces/IInitializedBy.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; - -namespace Stateflows.Common -{ - public interface IInitializedBy - where TInitializationRequest : InitializationRequest, new() - { - Task OnInitializeAsync(TInitializationRequest initializationRequest); - } -} diff --git a/Core/Stateflows/Common/Interfaces/IStateflowsStorage.cs b/Core/Stateflows/Common/Interfaces/IStateflowsStorage.cs index 21481f17..13661da3 100644 --- a/Core/Stateflows/Common/Interfaces/IStateflowsStorage.cs +++ b/Core/Stateflows/Common/Interfaces/IStateflowsStorage.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using Stateflows.Common.Context; -using Stateflows.Common.Trace.Models; namespace Stateflows.Common.Interfaces { @@ -9,9 +8,8 @@ public interface IStateflowsStorage { Task HydrateAsync(BehaviorId behaviorId); Task DehydrateAsync(StateflowsContext context); - Task> GetContextsAsync(IEnumerable behaviorClasses); - Task> GetContextsToTimeTriggerAsync(IEnumerable behaviorClasses); - Task SaveTraceAsync(BehaviorTrace behaviorTrace); - Task> GetTracesAsync(BehaviorId behaviorId); + Task> GetAllContextsAsync(IEnumerable behaviorClasses); + Task> GetTimeTriggeredContextsAsync(IEnumerable behaviorClasses); + Task> GetStartupTriggeredContextsAsync(IEnumerable behaviorClasses); } } diff --git a/Core/Stateflows/Common/Scheduler/ScheduleExecutor.cs b/Core/Stateflows/Common/Scheduler/ScheduleExecutor.cs index bde0b3ca..0ab71012 100644 --- a/Core/Stateflows/Common/Scheduler/ScheduleExecutor.cs +++ b/Core/Stateflows/Common/Scheduler/ScheduleExecutor.cs @@ -47,7 +47,7 @@ public async Task ExecuteAsync() await using (await Lock.AquireLockAsync(HandlingLockId, LockTimeout)) { - var contexts = await storage.GetContextsToTimeTriggerAsync(BehaviorClassesProvider.LocalBehaviorClasses); + var contexts = await storage.GetTimeTriggeredContextsAsync(BehaviorClassesProvider.LocalBehaviorClasses); foreach (var context in contexts) { diff --git a/Core/Stateflows/Common/Scheduler/StartupExecutor.cs b/Core/Stateflows/Common/Scheduler/StartupExecutor.cs new file mode 100644 index 00000000..5e85dc15 --- /dev/null +++ b/Core/Stateflows/Common/Scheduler/StartupExecutor.cs @@ -0,0 +1,72 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; +using Stateflows.Common.Interfaces; + +namespace Stateflows.Common.Scheduler +{ + internal class StartupExecutor + { + private readonly IStateflowsLock Lock; + + private readonly IBehaviorClassesProvider BehaviorClassesProvider; + + private readonly IBehaviorLocator Locator; + + private readonly ILogger Logger; + + private readonly TimeSpan LockTimeout = new TimeSpan(0, 0, 10); + + private BehaviorId HandlingLockId; + + private readonly IServiceProvider Services; + + public StartupExecutor( + IServiceProvider services, + IStateflowsLock @lock, + IBehaviorClassesProvider behaviorClassesProvider, + IBehaviorLocator behaviorLocator, + ILogger logger + ) + { + Services = services; + Lock = @lock; + BehaviorClassesProvider = behaviorClassesProvider; + Locator = behaviorLocator; + Logger = logger; + HandlingLockId = new BehaviorId(nameof(ThreadScheduler), nameof(HandlingLockId), new BehaviorClass("", "").Environment); + } + + public async Task ExecuteAsync() + { + try + { + var storage = Services.GetRequiredService(); + + await using (await Lock.AquireLockAsync(HandlingLockId, LockTimeout)) + { + var contexts = await storage.GetStartupTriggeredContextsAsync(BehaviorClassesProvider.LocalBehaviorClasses); + + foreach (var context in contexts) + { + var startupEvents = context.PendingStartupEvents.Values.ToArray(); + + if (startupEvents.Any() && Locator.TryLocateBehavior(context.Id, out var behavior)) + { + foreach (var startupEvent in startupEvents) + { + _ = behavior.SendAsync(startupEvent); + } + } + } + } + } + catch (Exception e) + { + Logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(StartupExecutor).FullName, nameof(ExecuteAsync), e.GetType().Name, e.Message); + } + } + } +} \ No newline at end of file diff --git a/Core/Stateflows/Common/Scheduler/ThreadScheduler.cs b/Core/Stateflows/Common/Scheduler/ThreadScheduler.cs index 5d5bc0d2..2c0b60fb 100644 --- a/Core/Stateflows/Common/Scheduler/ThreadScheduler.cs +++ b/Core/Stateflows/Common/Scheduler/ThreadScheduler.cs @@ -26,7 +26,11 @@ public ThreadScheduler(IServiceProvider serviceProvider) public Task StartAsync(CancellationToken cancellationToken) { - _ = Task.Run(() => TimingLoop(CancellationTokenSource.Token)); + _ = Task.Run(async () => + { + await HandleStartupEvents(); + await TimingLoop(CancellationTokenSource.Token); + }); return Task.CompletedTask; } @@ -76,6 +80,22 @@ private async Task HandleTimeEvents() } } + private async Task HandleStartupEvents() + { + using var scope = ServiceProvider.CreateScope(); + + try + { + var runner = scope.ServiceProvider.GetRequiredService(); + + await runner.ExecuteAsync(); + } + catch (Exception e) + { + Logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(ThreadScheduler).FullName, nameof(HandleStartupEvents), e.GetType().Name, e.Message); + } + } + public Task StopAsync(CancellationToken cancellationToken) { CancellationTokenSource.Cancel(); diff --git a/Core/Stateflows/Common/Storage/InMemoryStorage.cs b/Core/Stateflows/Common/Storage/InMemoryStorage.cs index 43ee74b9..e33bbebb 100644 --- a/Core/Stateflows/Common/Storage/InMemoryStorage.cs +++ b/Core/Stateflows/Common/Storage/InMemoryStorage.cs @@ -5,7 +5,6 @@ using Stateflows.Common.Context; using Stateflows.Common.Utilities; using Stateflows.Common.Interfaces; -using Stateflows.Common.Trace.Models; namespace Stateflows.Common.Storage { @@ -19,7 +18,7 @@ public Task HydrateAsync(BehaviorId behaviorId) { var context = Contexts.TryGetValue(behaviorId, out var contextStr) ? StateflowsJsonConverter.DeserializeObject(contextStr) - : new StateflowsContext() { Id = behaviorId }; + : new StateflowsContext(behaviorId); return Task.FromResult(context); } @@ -29,13 +28,21 @@ public Task DehydrateAsync(StateflowsContext context) { lock (Contexts) { - Contexts[context.Id] = StateflowsJsonConverter.SerializePolymorphicObject(context); + if (context.Deleted) + { + Contexts.Remove(context.Id); + } + else + { + Contexts[context.Id] = StateflowsJsonConverter.SerializePolymorphicObject(context); + context.Stored = true; + } } return Task.CompletedTask; } - public Task> GetContextsAsync(IEnumerable behaviorClasses) + public Task> GetAllContextsAsync(IEnumerable behaviorClasses) { IEnumerable result; @@ -50,16 +57,13 @@ public Task> GetContextsAsync(IEnumerable> GetContextsToTimeTriggerAsync(IEnumerable behaviorClasses) - => (await GetContextsAsync(behaviorClasses)).Where(context => + public async Task> GetTimeTriggeredContextsAsync(IEnumerable behaviorClasses) + => (await GetAllContextsAsync(behaviorClasses)).Where(context => context.TriggerTime != null && context.TriggerTime < DateTime.Now ); - public Task SaveTraceAsync(BehaviorTrace behaviorTrace) - => Task.CompletedTask; - - public Task> GetTracesAsync(BehaviorId behaviorId) - => Task.FromResult(Array.Empty() as IEnumerable); + public async Task> GetStartupTriggeredContextsAsync(IEnumerable behaviorClasses) + => (await GetAllContextsAsync(behaviorClasses)).Where(context => context.TriggerOnStartup); } } diff --git a/Core/Stateflows/Common/Trace/Models/BehaviorTrace.cs b/Core/Stateflows/Common/Trace/Models/BehaviorTrace.cs deleted file mode 100644 index 7d89002f..00000000 --- a/Core/Stateflows/Common/Trace/Models/BehaviorTrace.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common.Context; - -namespace Stateflows.Common.Trace.Models -{ - public class BehaviorTrace : BehaviorTraceStep - { - public BehaviorId BehaviorId { get; set; } - - public Event Event { get; set; } - - public StateflowsContext Context { get; set; } - } -} diff --git a/Core/Stateflows/Common/Trace/Models/BehaviorTraceStep.cs b/Core/Stateflows/Common/Trace/Models/BehaviorTraceStep.cs deleted file mode 100644 index e76912ad..00000000 --- a/Core/Stateflows/Common/Trace/Models/BehaviorTraceStep.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; - -namespace Stateflows.Common.Trace.Models -{ - public class BehaviorTraceStep - { - public BehaviorTraceStep AddStep(string actionName, string elementName, TimeSpan duration, object customData = null) - { - var step = new BehaviorTraceStep() - { - ActionName = actionName, - ElementName = elementName, - ExecutedAt = DateTime.Now, - Duration = duration, - CustomData = customData - }; - - Steps.Add(step); - return step; - } - - public bool ShouldSerializeSteps() - => Steps != null && Steps.Any(); - - public List Steps { get; set; } = new List(); - - public DateTime ExecutedAt { get; set; } - - public TimeSpan Duration { get; set; } - - public string ActionName { get; set; } - - public string ElementName { get; set; } - - public bool ShouldSerializeExceptions() - => Exceptions != null && Exceptions.Any(); - - public List Exceptions { get; set; } = new List(); - - public bool ShouldSerializeCustomData() - => CustomData != null; - - public object CustomData { get; set; } - - - } -} diff --git a/Core/Stateflows/DependencyInjection.cs b/Core/Stateflows/DependencyInjection.cs index f8b67325..1ba3fc9e 100644 --- a/Core/Stateflows/DependencyInjection.cs +++ b/Core/Stateflows/DependencyInjection.cs @@ -10,14 +10,10 @@ using Stateflows.Common.Extensions; using Stateflows.Common.Interfaces; using Stateflows.Common.Initializer; +using Stateflows.Common.Subscription; using Stateflows.Common.Registration.Builders; using Stateflows.Common.Registration.Interfaces; -using Stateflows.System; -using Stateflows.Activities; -using ActivityTracer = Stateflows.Activities.Engine.Tracer; -using StateMachineTracer = Stateflows.StateMachines.Engine.Tracer; using Stateflows.StateMachines; -using Stateflows.Common.Subscription; namespace Stateflows { @@ -28,7 +24,6 @@ internal static IStateflowsBuilder EnsureStateflowServices(this IStateflowsBuild if (!stateflowsBuilder.ServiceCollection.Any(x => x.ServiceType == typeof(StateflowsEngine))) { stateflowsBuilder - .EnsureSystemServices() .ServiceCollection .AddSingleton() .AddHostedService(provider => provider.GetService()) @@ -38,6 +33,7 @@ internal static IStateflowsBuilder EnsureStateflowServices(this IStateflowsBuild .AddHostedService() .AddHostedService() .AddTransient() + .AddTransient() .AddSingleton() .AddScoped() .AddScoped() @@ -82,13 +78,6 @@ public static IStateflowsBuilder AddDefaultInstance(this IStateflowsBuilder stat return stateflowsBuilder; } - public static IStateflowsBuilder AddAutoInitialization(this IStateflowsBuilder stateflowsBuilder, BehaviorClass behaviorClass, AutoInitializationRequestFactoryAsync initializationRequestFactoryAsync = null) - { - BehaviorClassesInitializations.Instance.AddAutoInitialization(behaviorClass, initializationRequestFactoryAsync); - - return stateflowsBuilder; - } - public static IStateflowsBuilder AddInterceptor(this IStateflowsBuilder stateflowsBuilder) where TInterceptor : class, IBehaviorInterceptor { @@ -118,15 +107,5 @@ public static IStateflowsBuilder AddClientInterceptor(this IStateflowsBuilder st return stateflowsBuilder; } - - public static IStateflowsBuilder AddTracing(this IStateflowsBuilder stateflowsBuilder) - { - stateflowsBuilder.ServiceCollection - //.AddScoped() - .AddScoped() - ; - - return stateflowsBuilder; - } } } diff --git a/Core/Stateflows/GlobalSuppressions.cs b/Core/Stateflows/GlobalSuppressions.cs index 2cfbe8f0..216c40c4 100644 --- a/Core/Stateflows/GlobalSuppressions.cs +++ b/Core/Stateflows/GlobalSuppressions.cs @@ -5,5 +5,5 @@ using System.Diagnostics.CodeAnalysis; -[assembly: SuppressMessage("Major Code Smell", "S3246:Generic type parameters should be co/contravariant when possible", Justification = "", Scope = "type", Target = "~T:Stateflows.Activities.Registration.Interfaces.Base.IElseDecisionFlow`2")] -[assembly: SuppressMessage("Major Code Smell", "S3246:Generic type parameters should be co/contravariant when possible", Justification = "", Scope = "type", Target = "~T:Stateflows.Activities.Registration.Interfaces.Base.IDecisionFlow`2")] +[assembly: SuppressMessage("Major Code Smell", "S3246:Generic type parameters should be co/contravariant when possible", Justification = "", Scope = "type", Target = "~T:Stateflows.Activities.Registration.Interfaces.Base.IElseDecisionFlowBase`2")] +[assembly: SuppressMessage("Major Code Smell", "S3246:Generic type parameters should be co/contravariant when possible", Justification = "", Scope = "type", Target = "~T:Stateflows.Activities.Registration.Interfaces.Base.IDecisionFlowBase`2")] diff --git a/Core/Stateflows/StateMachines/Classes/BaseState.cs b/Core/Stateflows/StateMachines/Classes/BaseState.cs deleted file mode 100644 index 9db17552..00000000 --- a/Core/Stateflows/StateMachines/Classes/BaseState.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using Stateflows.StateMachines.Context.Interfaces; - -namespace Stateflows.StateMachines -{ - public abstract class BaseState - { - public IStateActionContext Context { get; internal set; } - - public virtual Task OnEntryAsync() - => Task.CompletedTask; - - public virtual Task OnExitAsync() - => Task.CompletedTask; - } - - public static class StateInfo - where TState : BaseState - { - public static string Name => typeof(TState).FullName; - } -} diff --git a/Core/Stateflows/StateMachines/Classes/BaseTransition.cs b/Core/Stateflows/StateMachines/Classes/BaseTransition.cs deleted file mode 100644 index ed258021..00000000 --- a/Core/Stateflows/StateMachines/Classes/BaseTransition.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Stateflows.Common; -using Stateflows.StateMachines.Context.Interfaces; - -namespace Stateflows.StateMachines -{ - public abstract class BaseTransition - where TEvent : Event, new() - { - public ITransitionContext Context { get; internal set; } - - public virtual Task GuardAsync() - => Task.FromResult(true); - - public virtual Task EffectAsync() - => Task.CompletedTask; - } -} diff --git a/Core/Stateflows/StateMachines/Classes/CompositeState.cs b/Core/Stateflows/StateMachines/Classes/CompositeState.cs deleted file mode 100644 index 0e61ccd1..00000000 --- a/Core/Stateflows/StateMachines/Classes/CompositeState.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Threading.Tasks; - -namespace Stateflows.StateMachines -{ - public abstract class CompositeState : BaseState - { - public virtual Task OnInitializeAsync() - => Task.CompletedTask; - - public virtual Task OnFinalizeAsync() - => Task.CompletedTask; - } - - public static class CompositeStateInfo - where TCompositeState : CompositeState - { - public static string Name => typeof(TCompositeState).FullName; - } -} diff --git a/Core/Stateflows/StateMachines/Classes/ElseTransition.cs b/Core/Stateflows/StateMachines/Classes/ElseTransition.cs deleted file mode 100644 index 2e747cfb..00000000 --- a/Core/Stateflows/StateMachines/Classes/ElseTransition.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Threading.Tasks; -using Stateflows.Common; - -namespace Stateflows.StateMachines -{ - public abstract class ElseTransition : BaseTransition - where TEvent : Event, new() - { - public override sealed Task GuardAsync() - => Task.FromResult(true); - } -} diff --git a/Core/Stateflows/StateMachines/Classes/FinalState.cs b/Core/Stateflows/StateMachines/Classes/FinalState.cs index b4c56d9a..4932abee 100644 --- a/Core/Stateflows/StateMachines/Classes/FinalState.cs +++ b/Core/Stateflows/StateMachines/Classes/FinalState.cs @@ -1,15 +1,7 @@ -using System.Threading.Tasks; - -namespace Stateflows.StateMachines +namespace Stateflows.StateMachines { - public class FinalState : BaseState + public sealed class FinalState : IFinalState { public const string Name = "Stateflows.StateMachines.FinalState"; - - public sealed override Task OnEntryAsync() - => Task.CompletedTask; - - public sealed override Task OnExitAsync() - => Task.CompletedTask; } } diff --git a/Core/Stateflows/StateMachines/Classes/State.cs b/Core/Stateflows/StateMachines/Classes/State.cs deleted file mode 100644 index c6321f3e..00000000 --- a/Core/Stateflows/StateMachines/Classes/State.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Stateflows.StateMachines -{ - public abstract class State : BaseState - { } -} diff --git a/Core/Stateflows/StateMachines/Classes/StateMachine.cs b/Core/Stateflows/StateMachines/Classes/StateMachine.cs deleted file mode 100644 index d097a439..00000000 --- a/Core/Stateflows/StateMachines/Classes/StateMachine.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Reflection; -using System.Threading.Tasks; -using Stateflows.Common; -using Stateflows.StateMachines.Attributes; -using Stateflows.StateMachines.Context.Interfaces; - -namespace Stateflows.StateMachines -{ - public abstract class StateMachine - { - public IStateMachineActionContext Context { get; internal set; } - - public virtual Task OnInitializeAsync() - => Task.FromResult(true); - - public virtual Task OnFinalizeAsync() - => Task.CompletedTask; - - public abstract void Build(ITypedStateMachineBuilder builder); - } - - public abstract class StateMachine : StateMachine, IInitializedBy - where TInitializationRequest : InitializationRequest, new() - { - public abstract Task OnInitializeAsync(TInitializationRequest initializationRequest); - } - - public abstract class StateMachine : StateMachine, IInitializedBy - where TInitializationRequest1 : InitializationRequest, new() - where TInitializationRequest2 : InitializationRequest, new() - { - public abstract Task OnInitializeAsync(TInitializationRequest2 initializationRequest); - } - - public abstract class StateMachine : StateMachine, IInitializedBy - where TInitializationRequest1 : InitializationRequest, new() - where TInitializationRequest2 : InitializationRequest, new() - where TInitializationRequest3 : InitializationRequest, new() - { - public abstract Task OnInitializeAsync(TInitializationRequest3 initializationRequest); - } - - public static class StateMachineInfo - where TStateMachine : StateMachine - { - public static string Name - { - get - { - var stateMachineType = typeof(TStateMachine); - var attribute = stateMachineType.GetCustomAttribute(); - return attribute != null && attribute.Name != null - ? attribute.Name - : stateMachineType.FullName; - } - } - - public static BehaviorClass ToClass() - => new BehaviorClass(BehaviorType.StateMachine, Name); - - public static BehaviorId ToId(string instance) - => new BehaviorId(ToClass(), instance); - } -} diff --git a/Core/Stateflows/StateMachines/Classes/Transition.cs b/Core/Stateflows/StateMachines/Classes/Transition.cs deleted file mode 100644 index 11b87d79..00000000 --- a/Core/Stateflows/StateMachines/Classes/Transition.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Stateflows.Common; - -namespace Stateflows.StateMachines -{ - public abstract class Transition : BaseTransition - where TEvent : Event, new() - { } -} diff --git a/Core/Stateflows/StateMachines/Context/Classes/RootContext.cs b/Core/Stateflows/StateMachines/Context/Classes/RootContext.cs index 4b283eae..b7ecd705 100644 --- a/Core/Stateflows/StateMachines/Context/Classes/RootContext.cs +++ b/Core/Stateflows/StateMachines/Context/Classes/RootContext.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; @@ -152,6 +153,8 @@ public void ClearEvent() ? EventsStack.Peek() : null; + public readonly List Exceptions = new List(); + public EventStatus? ForceStatus { get; set; } = null; public async Task Send(TEvent @event) diff --git a/Core/Stateflows/StateMachines/Context/Classes/StateContext.cs b/Core/Stateflows/StateMachines/Context/Classes/StateContext.cs index 801575d3..f0f79d12 100644 --- a/Core/Stateflows/StateMachines/Context/Classes/StateContext.cs +++ b/Core/Stateflows/StateMachines/Context/Classes/StateContext.cs @@ -22,7 +22,7 @@ public StateContext(Vertex vertex, RootContext context) Vertex = vertex; Context = context; StateValues = Context.GetStateValues(Name); - Values = new ContextValues(StateValues.Values); + Values = new ContextValuesCollection(StateValues.Values); } public IContextValues Values { get; } diff --git a/Core/Stateflows/StateMachines/Context/Classes/StateMachineActionContext.cs b/Core/Stateflows/StateMachines/Context/Classes/StateMachineActionContext.cs index 997ac5ef..b9b95770 100644 --- a/Core/Stateflows/StateMachines/Context/Classes/StateMachineActionContext.cs +++ b/Core/Stateflows/StateMachines/Context/Classes/StateMachineActionContext.cs @@ -3,7 +3,7 @@ namespace Stateflows.StateMachines.Context.Classes { - internal class StateMachineActionContext : BaseContext, IStateMachineActionContext, IStateMachineActionInspectionContext + internal class StateMachineActionContext : BaseContext, IStateMachineActionContext, IStateMachineActionInspectionContext, IRootContext { IStateMachineContext IStateMachineActionContext.StateMachine => StateMachine; diff --git a/Core/Stateflows/StateMachines/Context/Classes/StateMachineContext.cs b/Core/Stateflows/StateMachines/Context/Classes/StateMachineContext.cs index 0e300830..846d983b 100644 --- a/Core/Stateflows/StateMachines/Context/Classes/StateMachineContext.cs +++ b/Core/Stateflows/StateMachines/Context/Classes/StateMachineContext.cs @@ -21,7 +21,7 @@ private BehaviorSubscriber Subscriber public StateMachineContext(RootContext context) : base(context) { - Values = new ContextValues(Context.GlobalValues); + Values = new ContextValuesCollection(Context.GlobalValues); } public IStateMachineInspection Inspection => Context.Executor.Inspector.Inspection; diff --git a/Core/Stateflows/StateMachines/Context/Classes/StateMachineInitializationContext.cs b/Core/Stateflows/StateMachines/Context/Classes/StateMachineInitializationContext.cs index fa42fce9..fe65adc1 100644 --- a/Core/Stateflows/StateMachines/Context/Classes/StateMachineInitializationContext.cs +++ b/Core/Stateflows/StateMachines/Context/Classes/StateMachineInitializationContext.cs @@ -7,23 +7,23 @@ namespace Stateflows.StateMachines.Context.Classes internal class StateMachineInitializationContext : BaseContext, IStateMachineInitializationContext - where TInitializationRequest : InitializationRequest, new() + where TInitializationRequest : Event, new() { public StateMachineInitializationContext(RootContext context, TInitializationRequest initializationRequest) : base(context) { - InitializationRequest = initializationRequest; + InitializationEvent = initializationRequest; } - public TInitializationRequest InitializationRequest { get; } + public TInitializationRequest InitializationEvent { get; } IStateMachineContext IStateMachineActionContext.StateMachine => StateMachine; } internal class StateMachineInitializationContext : - StateMachineInitializationContext, + StateMachineInitializationContext, IStateMachineInitializationInspectionContext { - public StateMachineInitializationContext(RootContext context, InitializationRequest initializationRequest) + public StateMachineInitializationContext(RootContext context, Event initializationRequest) : base(context, initializationRequest) { } diff --git a/Core/Stateflows/StateMachines/Context/Classes/StateValues.cs b/Core/Stateflows/StateMachines/Context/Classes/StateValues.cs index 6bd41803..ca2e1a4f 100644 --- a/Core/Stateflows/StateMachines/Context/Classes/StateValues.cs +++ b/Core/Stateflows/StateMachines/Context/Classes/StateValues.cs @@ -20,5 +20,10 @@ public bool ShouldSerializeTimeEventIds() => TimeEventIds.Any(); public Dictionary TimeEventIds { get; set; } = new Dictionary(); + + public bool ShouldSerializeStartupEventIds() + => StartupEventIds.Any(); + + public Dictionary StartupEventIds { get; set; } = new Dictionary(); } } diff --git a/Core/Stateflows/StateMachines/Context/ContextHolder.cs b/Core/Stateflows/StateMachines/Context/ContextHolder.cs new file mode 100644 index 00000000..f770fd75 --- /dev/null +++ b/Core/Stateflows/StateMachines/Context/ContextHolder.cs @@ -0,0 +1,13 @@ +using System.Threading; +using Stateflows.StateMachines.Context.Interfaces; + +namespace Stateflows.StateMachines.Context +{ + public static class ContextHolder + { + public static readonly AsyncLocal StateMachineContext = new AsyncLocal(); + public static readonly AsyncLocal StateContext = new AsyncLocal(); + public static readonly AsyncLocal TransitionContext = new AsyncLocal(); + public static readonly AsyncLocal ExecutionContext = new AsyncLocal(); + } +} diff --git a/Core/Stateflows/StateMachines/Context/Interfaces/IEventActionContext.cs b/Core/Stateflows/StateMachines/Context/Interfaces/IEventActionContext.cs new file mode 100644 index 00000000..dad4b75c --- /dev/null +++ b/Core/Stateflows/StateMachines/Context/Interfaces/IEventActionContext.cs @@ -0,0 +1,14 @@ +using Stateflows.Common; + +namespace Stateflows.StateMachines.Context.Interfaces +{ + public interface IEventContext + where TEvent : Event, new() + { + TEvent Event { get; } + } + + public interface IEventActionContext : IEventContext, IStateMachineActionContext + where TEvent : Event, new() + { } +} diff --git a/Core/Stateflows/StateMachines/Context/Interfaces/IEventContext.cs b/Core/Stateflows/StateMachines/Context/Interfaces/IEventContext.cs deleted file mode 100644 index b8f5122d..00000000 --- a/Core/Stateflows/StateMachines/Context/Interfaces/IEventContext.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Stateflows.Common; - -namespace Stateflows.StateMachines.Context.Interfaces -{ - public interface IEventContext : IStateMachineActionContext - where TEvent : Event, new() - { - TEvent Event { get; } - } -} diff --git a/Core/Stateflows/StateMachines/Context/Interfaces/IStateMachineActionContext.cs b/Core/Stateflows/StateMachines/Context/Interfaces/IStateMachineActionContext.cs index a6335640..3981a41f 100644 --- a/Core/Stateflows/StateMachines/Context/Interfaces/IStateMachineActionContext.cs +++ b/Core/Stateflows/StateMachines/Context/Interfaces/IStateMachineActionContext.cs @@ -2,10 +2,18 @@ namespace Stateflows.StateMachines.Context.Interfaces { - public interface IStateMachineActionContext : IBehaviorLocator + public interface IExecutionContext { - IStateMachineContext StateMachine { get; } - Event ExecutionTrigger { get; } } + + public interface IInitializationContext + { + Event InitializationEvent { get; } + } + + public interface IStateMachineActionContext : IBehaviorLocator, IExecutionContext + { + IStateMachineContext StateMachine { get; } + } } diff --git a/Core/Stateflows/StateMachines/Context/Interfaces/IStateMachineInitializationContext.cs b/Core/Stateflows/StateMachines/Context/Interfaces/IStateMachineInitializationContext.cs index 04941c4c..b21a3a54 100644 --- a/Core/Stateflows/StateMachines/Context/Interfaces/IStateMachineInitializationContext.cs +++ b/Core/Stateflows/StateMachines/Context/Interfaces/IStateMachineInitializationContext.cs @@ -2,12 +2,12 @@ namespace Stateflows.StateMachines.Context.Interfaces { - public interface IStateMachineInitializationContext : IStateMachineActionContext - where TInitializationRequest : InitializationRequest, new() + public interface IStateMachineInitializationContext : IStateMachineActionContext + { } + + public interface IStateMachineInitializationContext : IStateMachineInitializationContext + where TInitializationEvent : Event, new() { - TInitializationRequest InitializationRequest { get; } + TInitializationEvent InitializationEvent { get; } } - - public interface IStateMachineInitializationContext : IStateMachineInitializationContext - { } } diff --git a/Core/Stateflows/StateMachines/Context/Interfaces/ITransitionContext.cs b/Core/Stateflows/StateMachines/Context/Interfaces/ITransitionContext.cs index e9dbe24b..a07c7442 100644 --- a/Core/Stateflows/StateMachines/Context/Interfaces/ITransitionContext.cs +++ b/Core/Stateflows/StateMachines/Context/Interfaces/ITransitionContext.cs @@ -2,11 +2,14 @@ namespace Stateflows.StateMachines.Context.Interfaces { - public interface ITransitionContext : IEventContext - where TEvent : Event, new() + public interface ITransitionContext { IStateContext SourceState { get; } IStateContext TargetState { get; } } + + public interface ITransitionContext : IEventActionContext, ITransitionContext + where TEvent : Event, new() + { } } diff --git a/Core/Stateflows/StateMachines/Engine/Executor.cs b/Core/Stateflows/StateMachines/Engine/Executor.cs index 8994b41d..cc541275 100644 --- a/Core/Stateflows/StateMachines/Engine/Executor.cs +++ b/Core/Stateflows/StateMachines/Engine/Executor.cs @@ -7,13 +7,15 @@ using Microsoft.Extensions.DependencyInjection; using Stateflows.Common; using Stateflows.Common.Context; +using Stateflows.Common.Classes; using Stateflows.StateMachines.Models; using Stateflows.StateMachines.Events; +using Stateflows.StateMachines.Context; using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Context.Classes; using Stateflows.StateMachines.Context.Interfaces; -using Stateflows.Common.Classes; +using Stateflows.Common.Exceptions; namespace Stateflows.StateMachines.Engine { @@ -27,9 +29,17 @@ internal sealed class Executor : IDisposable public IServiceProvider ServiceProvider => ScopesStack.Peek().ServiceProvider; - //private readonly IServiceScope Scope; private readonly Stack ScopesStack = new Stack(); + private EventStatus EventStatus; + private bool IsEventStatusOverriden = false; + + public void OverrideEventStatus(EventStatus eventStatus) + { + EventStatus = eventStatus; + IsEventStatusOverriden = true; + } + public Executor(StateMachinesRegister register, Graph graph, IServiceProvider serviceProvider, StateflowsContext stateflowsContext, Event @event) { Register = register; @@ -42,7 +52,10 @@ public Executor(StateMachinesRegister register, Graph graph, IServiceProvider se public void Dispose() { - //Scope.Dispose(); + while (ScopesStack.Any()) + { + EndScope(); + } } public void BeginScope() @@ -120,20 +133,48 @@ public bool Finalized _ => BehaviorStatus.NotInitialized }; - public async Task InitializeAsync(InitializationRequest @event) + public async Task InitializeAsync(Event @event) { Debug.Assert(Context != null, $"Context is unavailable. Is state machine '{Graph.Name}' hydrated?"); - if (!Initialized && await DoInitializeStateMachineAsync(@event)) + if (!Initialized) { - await DoInitializeCascadeAsync(Graph.InitialVertex); + var result = await DoInitializeStateMachineAsync(@event); + + if ( + result == InitializationStatus.InitializedImplicitly || + result == InitializationStatus.InitializedExplicitly + ) + { + await DoInitializeCascadeAsync(Graph.InitialVertex); - await DoCompletion(); + await DoCompletion(); - return true; + if (result == InitializationStatus.InitializedExplicitly) + { + return EventStatus.Initialized; + } + else + { + if (@event is Initialize) + { + return EventStatus.Initialized; + } + else + { + return EventStatus.Consumed; + } + } + } + else + { + return result == InitializationStatus.NoSuitableInitializer + ? EventStatus.Rejected + : EventStatus.NotInitialized; + } } - return false; + return EventStatus.NotInitialized; } public async Task ExitAsync() @@ -158,16 +199,22 @@ public async Task ExitAsync() return false; } - public void Reset(bool keepVersion) + public void Reset(ResetMode resetMode) { Debug.Assert(Context != null, $"Context is unavailable. Is state machine '{Graph.Name}' hydrated?"); if (Initialized) { Context.Context.Values.Clear(); - if (!keepVersion) + + if (resetMode != ResetMode.KeepVersionAndSubscriptions) // KeepSubscriptions || Full { Context.Context.Version = 0; + + if (resetMode != ResetMode.KeepSubscriptions) // Full + { + Context.Context.Deleted = true; + } } } } @@ -213,6 +260,7 @@ private async Task DoInitializeCascadeAsync2(Vertex vertex) public IEnumerable GetExpectedEventNames() => GetExpectedEvents() .Where(type => !type.IsSubclassOf(typeof(TimeEvent))) + .Where(type => type != typeof(Startup)) .Where(type => type != typeof(CompletionEvent)) .Select(type => type.GetEventName()) .ToArray(); @@ -222,20 +270,14 @@ public IEnumerable GetExpectedEvents() var currentStack = VerticesStack.ToList(); currentStack.Reverse(); - if (currentStack.Any()) - { - return currentStack + return currentStack.Any() + ? currentStack .SelectMany(vertex => vertex.Edges.Values) .Select(edge => edge.TriggerType) .Distinct() + .ToArray() + : Graph.InitializerTypes .ToArray(); - } - else - { - return Graph.InitializerTypes.Any() - ? Graph.InitializerTypes - : new List() { typeof(InitializationRequest) }; - } } private List GetNestedVertices(Vertex vertex) @@ -261,6 +303,11 @@ public async Task ProcessAsync(TEvent @event) result = await DoProcessAsync(@event); } + if (IsEventStatusOverriden) + { + result = EventStatus; + } + return result; } @@ -374,36 +421,53 @@ private async Task DoEffectAsync(Edge edge) EndScope(); } - public async Task DoInitializeStateMachineAsync(InitializationRequest @event) + public async Task DoInitializeStateMachineAsync(Event @event) { BeginScope(); - var result = false; + InitializationStatus result; - if ( - Graph.Initializers.TryGetValue(@event.Name, out var initializer) || - ( - @event.Name == EventInfo.Name && - !Graph.Initializers.Any() - ) - ) - { - var context = new StateMachineInitializationContext(Context, @event); - await Inspector.BeforeStateMachineInitializeAsync(context); + var initializer = Graph.Initializers.ContainsKey(@event.Name) + ? Graph.Initializers[@event.Name] + : Graph.DefaultInitializer; + + var context = new StateMachineInitializationContext(Context, @event); + await Inspector.BeforeStateMachineInitializeAsync(context); + if (initializer != null) + { try { - result = (initializer == null) || await initializer.WhenAll(Context); + result = await initializer.WhenAll(Context) + ? initializer == Graph.DefaultInitializer + ? InitializationStatus.InitializedImplicitly + : InitializationStatus.InitializedExplicitly + : InitializationStatus.NotInitialized; } catch (Exception e) { - await Inspector.OnStateMachineInitializationExceptionAsync(context, e); - - result = false; + if (!await Inspector.OnStateMachineInitializationExceptionAsync(context, e)) + { + throw; + } + else + { + throw new ExecutionException(e); + } } - - await Inspector.AfterStateMachineInitializeAsync(context); } + else + { + result = Graph.Initializers.Any() + ? InitializationStatus.NoSuitableInitializer + : InitializationStatus.InitializedImplicitly; + } + + await Inspector.AfterStateMachineInitializeAsync( + context, + result == InitializationStatus.InitializedImplicitly || + result == InitializationStatus.InitializedExplicitly + ); EndScope(); @@ -417,7 +481,22 @@ public async Task DoFinalizeStateMachineAsync() var context = new StateMachineActionContext(Context); await Inspector.BeforeStateMachineFinalizeAsync(context); - await Graph.Finalize.WhenAll(Context); + + try + { + await Graph.Finalize.WhenAll(Context); + } + catch (Exception e) + { + if (!await Inspector.OnStateMachineFinalizationExceptionAsync(context, e)) + { + throw; + } + else + { + throw new ExecutionException(e); + } + } await Inspector.AfterStateMachineFinalizeAsync(context); @@ -571,56 +650,121 @@ private async Task DoCompletion() Context.ClearEvent(); } - public StateMachine GetStateMachine(Type stateMachineType, RootContext context) + public IStateMachine GetStateMachine(Type stateMachineType) { - var stateMachine = ServiceProvider.GetService(stateMachineType) as StateMachine; - stateMachine.Context = new StateMachineActionContext(context); + var stateMachine = ServiceProvider.GetService(stateMachineType) as IStateMachine; return stateMachine; } + public TDefaultInitializer GetDefaultInitializer(IStateMachineInitializationContext context) + where TDefaultInitializer : class, IDefaultInitializer + { + ContextValues.GlobalValuesHolder.Value = context.StateMachine.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.StateContext.Value = null; + ContextHolder.TransitionContext.Value = null; + ContextHolder.StateMachineContext.Value = context.StateMachine; + ContextHolder.ExecutionContext.Value = context; + + var initializer = ServiceProvider.GetService(); + + return initializer; + } + + public TInitializer GetInitializer(IStateMachineInitializationContext context) + where TInitializer : class, IInitializer + where TInitializationEvent : Event, new() + { + ContextValues.GlobalValuesHolder.Value = context.StateMachine.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.StateContext.Value = null; + ContextHolder.TransitionContext.Value = null; + ContextHolder.StateMachineContext.Value = context.StateMachine; + ContextHolder.ExecutionContext.Value = context; + + var initializer = ServiceProvider.GetService(); + + return initializer; + } + + public TFinalizer GetFinalizer(IStateMachineActionContext context) + where TFinalizer : class, IFinalizer + { + ContextValues.GlobalValuesHolder.Value = context.StateMachine.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.StateContext.Value = null; + ContextHolder.TransitionContext.Value = null; + ContextHolder.StateMachineContext.Value = context.StateMachine; + ContextHolder.ExecutionContext.Value = context; + + var initializer = ServiceProvider.GetService(); + + return initializer; + } + public TState GetState(IStateActionContext context) - where TState : BaseState + where TState : class, IBaseState { - ContextValuesHolder.GlobalValues.Value = context.StateMachine.Values; - ContextValuesHolder.StateValues.Value = context.CurrentState.Values; - ContextValuesHolder.SourceStateValues.Value = null; - ContextValuesHolder.TargetStateValues.Value = null; + ContextValues.GlobalValuesHolder.Value = context.StateMachine.Values; + ContextValues.StateValuesHolder.Value = context.CurrentState.Values; + ContextValues.SourceStateValuesHolder.Value = null; + ContextValues.TargetStateValuesHolder.Value = null; + + ContextHolder.StateContext.Value = context.CurrentState; + ContextHolder.TransitionContext.Value = null; + ContextHolder.StateMachineContext.Value = context.StateMachine; + ContextHolder.ExecutionContext.Value = context; var state = ServiceProvider.GetService(); - state.Context = context; - + return state; } public TTransition GetTransition(ITransitionContext context) - where TTransition : Transition + where TTransition : class, IBaseTransition where TEvent : Event, new() { - ContextValuesHolder.GlobalValues.Value = context.StateMachine.Values; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = context.SourceState.Values; - ContextValuesHolder.TargetStateValues.Value = context.TargetState?.Values; + ContextValues.GlobalValuesHolder.Value = context.StateMachine.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = context.SourceState.Values; + ContextValues.TargetStateValuesHolder.Value = context.TargetState?.Values; + + ContextHolder.StateContext.Value = null; + ContextHolder.TransitionContext.Value = context; + ContextHolder.StateMachineContext.Value = context.StateMachine; + ContextHolder.ExecutionContext.Value = context; var transition = ServiceProvider.GetService(); - transition.Context = context; - + return transition; } - public TElseTransition GetElseTransition(ITransitionContext context) - where TElseTransition : ElseTransition - where TEvent : Event, new() + public TDefaultTransition GetDefaultTransition(ITransitionContext context) + where TDefaultTransition : class, IBaseDefaultTransition { - ContextValuesHolder.GlobalValues.Value = context.StateMachine.Values; - ContextValuesHolder.StateValues.Value = null; - ContextValuesHolder.SourceStateValues.Value = context.SourceState.Values; - ContextValuesHolder.TargetStateValues.Value = context.TargetState?.Values; + ContextValues.GlobalValuesHolder.Value = context.StateMachine.Values; + ContextValues.StateValuesHolder.Value = null; + ContextValues.SourceStateValuesHolder.Value = context.SourceState.Values; + ContextValues.TargetStateValuesHolder.Value = context.TargetState?.Values; + + ContextHolder.StateContext.Value = null; + ContextHolder.TransitionContext.Value = context; + ContextHolder.StateMachineContext.Value = context.StateMachine; + ContextHolder.ExecutionContext.Value = context; - var elseTransition = ServiceProvider.GetService(); - elseTransition.Context = context; - - return elseTransition; + var transition = ServiceProvider.GetService(); + + return transition; } } } diff --git a/Core/Stateflows/StateMachines/Engine/Inspector.cs b/Core/Stateflows/StateMachines/Engine/Inspector.cs index 3b84f6f7..7f43ad51 100644 --- a/Core/Stateflows/StateMachines/Engine/Inspector.cs +++ b/Core/Stateflows/StateMachines/Engine/Inspector.cs @@ -94,11 +94,11 @@ public async Task BeforeStateMachineInitializeAsync(StateMachineInitializationCo await Observers.RunSafe(o => o.BeforeStateMachineInitializeAsync(context), nameof(BeforeStateMachineInitializeAsync), Logger); } - public async Task AfterStateMachineInitializeAsync(StateMachineInitializationContext context) + public async Task AfterStateMachineInitializeAsync(StateMachineInitializationContext context, bool initialized) { - await Observers.RunSafe(o => o.AfterStateMachineInitializeAsync(context), nameof(AfterStateMachineInitializeAsync), Logger); - await Inspectors.RunSafe(i => i.AfterStateMachineInitializeAsync(context), nameof(AfterStateMachineInitializeAsync), Logger); - await Plugins.RunSafe(o => o.AfterStateMachineInitializeAsync(context), nameof(AfterStateMachineInitializeAsync), Logger); + await Observers.RunSafe(o => o.AfterStateMachineInitializeAsync(context, initialized), nameof(AfterStateMachineInitializeAsync), Logger); + await Inspectors.RunSafe(i => i.AfterStateMachineInitializeAsync(context, initialized), nameof(AfterStateMachineInitializeAsync), Logger); + await Plugins.RunSafe(o => o.AfterStateMachineInitializeAsync(context, initialized), nameof(AfterStateMachineInitializeAsync), Logger); if (InitializeInspection != null) { @@ -312,56 +312,153 @@ public async Task AfterProcessEventAsync(Context.Classes.EventContext i.AfterProcessEventAsync(context), nameof(AfterProcessEventAsync), Logger); } - public async Task OnStateMachineInitializationExceptionAsync(StateMachineInitializationContext context, Exception exception) - where TInitializationRequest : InitializationRequest, new() + private static bool ShouldPropagateException(Graph graph, bool handled) + => !handled; + + public async Task OnStateMachineInitializationExceptionAsync(StateMachineInitializationContext context, Exception exception) { - var exceptionContext = new StateMachineInitializationContext(context.Context, context.InitializationRequest); - await ExceptionHandlers.RunSafe(h => h.OnStateMachineInitializationExceptionAsync(exceptionContext, exception), nameof(OnStateMachineInitializationExceptionAsync), Logger); - await Inspectors.RunSafe(i => i.OnStateMachineInitializationExceptionAsync(exceptionContext, exception), nameof(OnStateMachineInitializationExceptionAsync), Logger); + var handled = await ExceptionHandlers.RunSafe(h => h.OnStateMachineInitializationExceptionAsync(context, exception), nameof(OnStateMachineInitializationExceptionAsync), Logger, false); + await Inspectors.RunSafe(i => i.OnStateMachineInitializationExceptionAsync(context, exception), nameof(OnStateMachineInitializationExceptionAsync), Logger); + + if (!handled) + { + await Plugins.RunSafe(i => i.OnStateMachineInitializationExceptionAsync(context, exception), nameof(OnStateMachineInitializationExceptionAsync), Logger); + } + + if (ShouldPropagateException(context.Context.Executor.Graph, handled)) + { + context.Context.Exceptions.Add(exception); + } + + return handled; } - public async Task OnStateMachineFinalizationExceptionAsync(StateMachineActionContext context, Exception exception) + public async Task OnStateMachineFinalizationExceptionAsync(StateMachineActionContext context, Exception exception) { - await ExceptionHandlers.RunSafe(h => h.OnStateMachineFinalizationExceptionAsync(context, exception), nameof(OnStateMachineFinalizationExceptionAsync), Logger); + var handled = await ExceptionHandlers.RunSafe(h => h.OnStateMachineFinalizationExceptionAsync(context, exception), nameof(OnStateMachineFinalizationExceptionAsync), Logger, false); await Inspectors.RunSafe(i => i.OnStateMachineFinalizationExceptionAsync(context, exception), nameof(OnStateMachineFinalizationExceptionAsync), Logger); + + if (!handled) + { + await Plugins.RunSafe(i => i.OnStateMachineFinalizationExceptionAsync(context, exception), nameof(OnStateMachineFinalizationExceptionAsync), Logger); + } + + if (ShouldPropagateException(context.Context.Executor.Graph, handled)) + { + context.Context.Exceptions.Add(exception); + } + + return handled; } - public async Task OnTransitionGuardExceptionAsync(GuardContext context, Exception exception) + public async Task OnTransitionGuardExceptionAsync(GuardContext context, Exception exception) where TEvent : Event, new() { - await ExceptionHandlers.RunSafe(h => h.OnTransitionGuardExceptionAsync(context, exception), nameof(OnTransitionGuardExceptionAsync), Logger); + var handled = await ExceptionHandlers.RunSafe(h => h.OnTransitionGuardExceptionAsync(context, exception), nameof(OnTransitionGuardExceptionAsync), Logger, false); await Inspectors.RunSafe(i => i.OnTransitionGuardExceptionAsync(context, exception), nameof(OnTransitionGuardExceptionAsync), Logger); + + if (!handled) + { + await Plugins.RunSafe(i => i.OnTransitionGuardExceptionAsync(context, exception), nameof(OnTransitionGuardExceptionAsync), Logger); + } + + if (ShouldPropagateException(context.Context.Executor.Graph, handled)) + { + context.Context.Exceptions.Add(exception); + } + + return handled; } - public async Task OnTransitionEffectExceptionAsync(TransitionContext context, Exception exception) + public async Task OnTransitionEffectExceptionAsync(TransitionContext context, Exception exception) where TEvent : Event, new() { - await ExceptionHandlers.RunSafe(h => h.OnTransitionEffectExceptionAsync(context, exception), nameof(OnTransitionEffectExceptionAsync), Logger); + var handled = await ExceptionHandlers.RunSafe(h => h.OnTransitionEffectExceptionAsync(context, exception), nameof(OnTransitionEffectExceptionAsync), Logger, false); await Inspectors.RunSafe(h => h.OnTransitionEffectExceptionAsync(context, exception), nameof(OnTransitionEffectExceptionAsync), Logger); + + if (!handled) + { + await Plugins.RunSafe(h => h.OnTransitionEffectExceptionAsync(context, exception), nameof(OnTransitionEffectExceptionAsync), Logger); + } + + if (ShouldPropagateException(context.Context.Executor.Graph, handled)) + { + context.Context.Exceptions.Add(exception); + } + + return handled; } - public async Task OnStateInitializeExceptionAsync(StateActionContext context, Exception exception) + public async Task OnStateInitializeExceptionAsync(StateActionContext context, Exception exception) { - await ExceptionHandlers.RunSafe(h => h.OnStateInitializationExceptionAsync(context, exception), nameof(OnStateInitializeExceptionAsync), Logger); + var handled = await ExceptionHandlers.RunSafe(h => h.OnStateInitializationExceptionAsync(context, exception), nameof(OnStateInitializeExceptionAsync), Logger, false); await Inspectors.RunSafe(i => i.OnStateInitializeExceptionAsync(context, exception), nameof(OnStateInitializeExceptionAsync), Logger); + + if (!handled) + { + await Plugins.RunSafe(i => i.OnStateInitializationExceptionAsync(context, exception), nameof(OnStateInitializeExceptionAsync), Logger); + } + + if (ShouldPropagateException(context.Context.Executor.Graph, handled)) + { + context.Context.Exceptions.Add(exception); + } + + return handled; } - public async Task OnStateFinalizeExceptionAsync(StateActionContext context, Exception exception) + public async Task OnStateFinalizeExceptionAsync(StateActionContext context, Exception exception) { - await ExceptionHandlers.RunSafe(h => h.OnStateFinalizationExceptionAsync(context, exception), nameof(OnStateFinalizeExceptionAsync), Logger); + var handled = await ExceptionHandlers.RunSafe(h => h.OnStateFinalizationExceptionAsync(context, exception), nameof(OnStateFinalizeExceptionAsync), Logger, false); await Inspectors.RunSafe(i => i.OnStateFinalizeExceptionAsync(context, exception), nameof(OnStateFinalizeExceptionAsync), Logger); + + if (!handled) + { + await Plugins.RunSafe(i => i.OnStateFinalizationExceptionAsync(context, exception), nameof(OnStateFinalizeExceptionAsync), Logger); + } + + if (ShouldPropagateException(context.Context.Executor.Graph, handled)) + { + context.Context.Exceptions.Add(exception); + } + + return handled; } - public async Task OnStateEntryExceptionAsync(StateActionContext context, Exception exception) + public async Task OnStateEntryExceptionAsync(StateActionContext context, Exception exception) { - await ExceptionHandlers.RunSafe(h => h.OnStateEntryExceptionAsync(context, exception), nameof(OnStateEntryExceptionAsync), Logger); + var handled = await ExceptionHandlers.RunSafe(h => h.OnStateEntryExceptionAsync(context, exception), nameof(OnStateEntryExceptionAsync), Logger, false); await Inspectors.RunSafe(i => i.OnStateEntryExceptionAsync(context, exception), nameof(OnStateEntryExceptionAsync), Logger); + + if (!handled) + { + await Plugins.RunSafe(i => i.OnStateEntryExceptionAsync(context, exception), nameof(OnStateEntryExceptionAsync), Logger); + } + + if (ShouldPropagateException(context.Context.Executor.Graph, handled)) + { + context.Context.Exceptions.Add(exception); + } + + return handled; } - public async Task OnStateExitExceptionAsync(StateActionContext context, Exception exception) + public async Task OnStateExitExceptionAsync(StateActionContext context, Exception exception) { - await ExceptionHandlers.RunSafe(h => h.OnStateExitExceptionAsync(context, exception), nameof(OnStateExitExceptionAsync), Logger); + var handled = await ExceptionHandlers.RunSafe(h => h.OnStateExitExceptionAsync(context, exception), nameof(OnStateExitExceptionAsync), Logger, false); await Inspectors.RunSafe(i => i.OnStateExitExceptionAsync(context, exception), nameof(OnStateExitExceptionAsync), Logger); + + if (!handled) + { + await Plugins.RunSafe(i => i.OnStateExitExceptionAsync(context, exception), nameof(OnStateExitExceptionAsync), Logger); + } + + if (ShouldPropagateException(context.Context.Executor.Graph, handled)) + { + context.Context.Exceptions.Add(exception); + } + + return handled; } } } diff --git a/Core/Stateflows/StateMachines/Engine/Plugins/Behaviors.cs b/Core/Stateflows/StateMachines/Engine/Plugins/Behaviors.cs index d8df0edf..1b69b195 100644 --- a/Core/Stateflows/StateMachines/Engine/Plugins/Behaviors.cs +++ b/Core/Stateflows/StateMachines/Engine/Plugins/Behaviors.cs @@ -8,7 +8,7 @@ namespace Stateflows.StateMachines.Engine { internal class Behaviors : IStateMachinePlugin { - public Task AfterStateEntryAsync(IStateActionContext context) + public async Task AfterStateEntryAsync(IStateActionContext context) { var vertex = (context as StateActionContext).Vertex; @@ -27,12 +27,13 @@ public Task AfterStateEntryAsync(IStateActionContext context) _ = behavior.SendAsync(vertex.GetSubscriptionRequest(context.StateMachine.Id)); } - var initializationRequest = vertex.BehaviorInitializationBuilder?.Invoke(context) ?? new InitializationRequest(); - _ = behavior.InitializeAsync(initializationRequest); + var initializationRequest = vertex.BehaviorInitializationBuilder != null + ? await vertex.BehaviorInitializationBuilder(context) ?? new Initialize() + : new Initialize(); + + _ = behavior.SendAsync(initializationRequest); } } - - return Task.CompletedTask; } public Task BeforeStateExitAsync(IStateActionContext context) diff --git a/Core/Stateflows/StateMachines/Engine/Plugins/Notifications.cs b/Core/Stateflows/StateMachines/Engine/Plugins/Notifications.cs index 13927c47..2c4a08d8 100644 --- a/Core/Stateflows/StateMachines/Engine/Plugins/Notifications.cs +++ b/Core/Stateflows/StateMachines/Engine/Plugins/Notifications.cs @@ -1,10 +1,10 @@ -using System; +using System.Diagnostics; using System.Threading.Tasks; using Stateflows.Common; using Stateflows.StateMachines.Events; using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Context.Interfaces; -using System.Diagnostics; +using System; namespace Stateflows.StateMachines.Engine { @@ -12,35 +12,35 @@ internal class Notifications : IStateMachinePlugin { public Task AfterStateEntryAsync(IStateActionContext context) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': entered state '{context.CurrentState.Name}'"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': entered state '{context.CurrentState.Name}'"); return Task.CompletedTask; } public Task AfterStateExitAsync(IStateActionContext context) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': exited state '{context.CurrentState.Name}'"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': exited state '{context.CurrentState.Name}'"); return Task.CompletedTask; } public Task AfterStateInitializeAsync(IStateActionContext context) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': initialized state '{context.CurrentState.Name}'"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': initialized state '{context.CurrentState.Name}'"); return Task.CompletedTask; } public Task AfterStateFinalizeAsync(IStateActionContext context) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': finalized state '{context.CurrentState.Name}'"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': finalized state '{context.CurrentState.Name}'"); return Task.CompletedTask; } - public Task AfterStateMachineInitializeAsync(IStateMachineInitializationContext context) + public Task AfterStateMachineInitializeAsync(IStateMachineInitializationContext context, bool initialized) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': initialized"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': {(initialized ? "" : "not ")}initialized"); var executor = context.StateMachine.GetExecutor(); var notification = new BehaviorStatusNotification() @@ -56,7 +56,7 @@ public Task AfterStateMachineInitializeAsync(IStateMachineInitializationContext public Task AfterStateMachineFinalizeAsync(IStateMachineActionContext context) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': finalized"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': finalized"); var notification = new BehaviorStatusNotification() { BehaviorStatus = BehaviorStatus.Finalized }; @@ -74,38 +74,38 @@ public Task AfterTransitionGuardAsync(IGuardContext context, bool guardRe { if (context.TargetState != null) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': event '{context.Event.Name}' triggered transition from state '{context.SourceState.Name}' to state '{context.TargetState.Name}'"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': event '{context.Event.Name}' triggered transition from state '{context.SourceState.Name}' to state '{context.TargetState.Name}'"); } else { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': event '{context.Event.Name}' triggered reaction in state '{context.SourceState.Name}'"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': event '{context.Event.Name}' triggered reaction in state '{context.SourceState.Name}'"); } } else { if (context.TargetState != null) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': guard stopped event '{context.Event.Name}' from triggering transition from state '{context.SourceState.Name}' to state '{context.TargetState.Name}'"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': guard stopped event '{context.Event.Name}' from triggering transition from state '{context.SourceState.Name}' to state '{context.TargetState.Name}'"); } else { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': guard stopped event '{context.Event.Name}' from triggering reaction in state '{context.SourceState.Name}'"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': guard stopped event '{context.Event.Name}' from triggering reaction in state '{context.SourceState.Name}'"); } } return Task.CompletedTask; } - public Task BeforeProcessEventAsync(IEventContext context) + public Task BeforeProcessEventAsync(IEventActionContext context) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': received event '{context.Event.Name}', trying to process it"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': received event '{context.Event.Name}', trying to process it"); return Task.FromResult(true); } - public Task AfterProcessEventAsync(IEventContext context) + public Task AfterProcessEventAsync(IEventActionContext context) { - Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}': processed event '{context.Event.Name}'"); + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': processed event '{context.Event.Name}'"); var executor = context.StateMachine.GetExecutor(); if (executor.StateHasChanged) @@ -122,5 +122,61 @@ public Task AfterProcessEventAsync(IEventContext context) return Task.CompletedTask; } + + public Task OnStateMachineInitializationExceptionAsync(IStateMachineInitializationContext context, Exception exception) + { + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': unhandled exception '{exception.GetType().Name}' with message '{exception.Message}' on State Machine initialization"); + + return Task.CompletedTask; + } + + public Task OnStateMachineFinalizationExceptionAsync(IStateMachineActionContext context, Exception exception) + { + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': unhandled exception '{exception.GetType().Name}' with message '{exception.Message}' on State Machine finalization"); + + return Task.CompletedTask; + } + + public Task OnTransitionGuardExceptionAsync(IGuardContext context, Exception exception) + { + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': unhandled exception '{exception.GetType().Name}' with message '{exception.Message}' on transition guard"); + + return Task.CompletedTask; + } + + public Task OnTransitionEffectExceptionAsync(ITransitionContext context, Exception exception) + { + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': unhandled exception '{exception.GetType().Name}' with message '{exception.Message}' on transition effect"); + + return Task.CompletedTask; + } + + public Task OnStateInitializationExceptionAsync(IStateActionContext context, Exception exception) + { + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': unhandled exception '{exception.GetType().Name}' with message '{exception.Message}' on state initialization"); + + return Task.CompletedTask; + } + + public Task OnStateFinalizationExceptionAsync(IStateActionContext context, Exception exception) + { + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': unhandled exception '{exception.GetType().Name}' with message '{exception.Message}' on state finalization"); + + return Task.CompletedTask; + } + + public Task OnStateEntryExceptionAsync(IStateActionContext context, Exception exception) + { + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': unhandled exception '{exception.GetType().Name}' with message '{exception.Message}' on state entry"); + + return Task.CompletedTask; + } + + public Task OnStateExitExceptionAsync(IStateActionContext context, Exception exception) + { + Trace.WriteLine($"⦗→s⦘ State Machine '{context.StateMachine.Id.Name}:{context.StateMachine.Id.Instance}': unhandled exception '{exception.GetType().Name}' with message '{exception.Message}' on state exit"); + + return Task.CompletedTask; + } } } diff --git a/Core/Stateflows/StateMachines/Engine/Plugins/TimeEvents.cs b/Core/Stateflows/StateMachines/Engine/Plugins/TimeEvents.cs index be03cfaf..d33562ee 100644 --- a/Core/Stateflows/StateMachines/Engine/Plugins/TimeEvents.cs +++ b/Core/Stateflows/StateMachines/Engine/Plugins/TimeEvents.cs @@ -15,6 +15,8 @@ internal class TimeEvents : IStateMachinePlugin, IEqualityComparer private readonly List TimeEventIdsToClear = new List(); + private readonly List StartupEventIdsToClear = new List(); + private Edge ConsumedInTransition { get; set; } private RootContext Context { get; set; } @@ -31,13 +33,17 @@ public Task AfterStateExitAsync(IStateActionContext context) { var vertex = (context as StateActionContext).Vertex; var stateValues = Context.GetStateValues(vertex.Name); + var timeEventIds = stateValues.TimeEventIds.Values.ToArray(); TimeEventIdsToClear.AddRange(timeEventIds); + var startupEventIds = stateValues.StartupEventIds.Values.ToArray(); + StartupEventIdsToClear.AddRange(startupEventIds); + return Task.CompletedTask; } - public Task BeforeProcessEventAsync(IEventContext context) + public Task BeforeProcessEventAsync(IEventActionContext context) { var result = true; @@ -56,9 +62,10 @@ public Task BeforeProcessEventAsync(IEventContext context) return Task.FromResult(result); } - public Task AfterProcessEventAsync(IEventContext context) + public Task AfterProcessEventAsync(IEventActionContext context) { ClearTimeEvents(TimeEventIdsToClear); + ClearStartupEvents(StartupEventIdsToClear); if ( ConsumedInTransition != null && @@ -78,6 +85,7 @@ public Task AfterProcessEventAsync(IEventContext context) .ToArray(); RegisterTimeEvents(enteredStack); + RegisterStartupEvents(enteredStack); if ( context.Event.GetType().IsSubclassOf(typeof(RecurringEvent)) && @@ -101,6 +109,8 @@ public Task AfterProcessEventAsync(IEventContext context) Context.Context.TriggerTime = null; } + Context.Context.TriggerOnStartup = Context.Context.PendingStartupEvents.Any(); + return Task.CompletedTask; } @@ -120,6 +130,58 @@ public Task AfterHydrateAsync(IStateMachineActionContext context) public Task BeforeDehydrateAsync(IStateMachineActionContext context) => Task.CompletedTask; + private void RegisterStartupEvent(Edge edge) + { + var startupEventIds = Context.GetStateValues(edge.Source.Name).StartupEventIds; + if (startupEventIds.ContainsKey(edge.Identifier)) + { + return; + } + + var startupEvent = Activator.CreateInstance(edge.TriggerType) as Startup; + startupEvent.ConsumerSignature = edge.Identifier; + Context.Context.PendingStartupEvents.Add(startupEvent.Id, startupEvent); + startupEventIds.Add(edge.Identifier, startupEvent.Id); + } + + private void RegisterStartupEvents(IEnumerable edges) + { + foreach (var edge in edges) + { + RegisterStartupEvent(edge); + } + } + + private void RegisterStartupEvents(IEnumerable vertices) + { + foreach (var currentVertex in vertices) + { + var timeEventIds = Context.GetStateValues(currentVertex.Name).StartupEventIds; + + var edges = currentVertex.Edges.Values + .Where(edge => + !edge.IsElse && + edge.TriggerType == typeof(Startup) && + !timeEventIds.ContainsKey(edge.Identifier) + ) + .Distinct(this) + .ToArray(); + + RegisterStartupEvents(edges); + } + } + + private void ClearStartupEvents(IEnumerable startupEventIds) + { + foreach (var startupEventId in startupEventIds) + { + ClearStartupEvent(startupEventId); + } + } + + private void ClearStartupEvent(Guid startupEventId) + => Context.Context.PendingStartupEvents.Remove(startupEventId); + private void RegisterTimeEvent(Edge edge) { var timeEventIds = Context.GetStateValues(edge.Source.Name).TimeEventIds; diff --git a/Core/Stateflows/StateMachines/Engine/Plugins/Tracer.cs b/Core/Stateflows/StateMachines/Engine/Plugins/Tracer.cs deleted file mode 100644 index b57f81d1..00000000 --- a/Core/Stateflows/StateMachines/Engine/Plugins/Tracer.cs +++ /dev/null @@ -1,213 +0,0 @@ -using System; -using System.Diagnostics; -using System.Reflection; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Stateflows.Common; -using Stateflows.Common.Interfaces; -using Stateflows.Common.Trace.Models; -using Stateflows.StateMachines.Context.Interfaces; - -namespace Stateflows.StateMachines.Engine -{ - internal class Tracer : IStateMachinePlugin - { - private readonly IServiceProvider ServiceProvider; - - private BehaviorTrace Trace { get; set; } = new BehaviorTrace(); - - private Exception Exception { get; set; } = null; - - private Stopwatch Stopwatch { get; set; } = new Stopwatch(); - - private Stopwatch OverallStopwatch { get; set; } = new Stopwatch(); - - public Tracer(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider.CreateScope().ServiceProvider; - } - - private Task StartMeasureAsync() - { - if (Trace.Event != null) - { - Exception = null; - Stopwatch.Reset(); - } - - return Task.CompletedTask; - } - - private Task StopMeasureAsync(string actionName, string elementName) - { - if (Trace.Event != null) - { - Stopwatch.Stop(); - var step = Trace.AddStep(actionName, elementName, Stopwatch.Elapsed); - step.Exceptions.Add(Exception); - } - - return Task.CompletedTask; - } - - private Task SetExceptionAsync(Exception exception) - { - if (Trace.Event != null) - { - Exception = exception; - } - - return Task.CompletedTask; - } - - public Task StopMeasurementAsync() - { - if (Trace.Event != null) - { - Exception = null; - Stopwatch.Reset(); - Stopwatch.Start(); - } - - return Task.CompletedTask; - } - - public Task BeforeStateEntryAsync(IStateActionContext context) - => StartMeasureAsync(); - - public Task AfterStateEntryAsync(IStateActionContext context) - => StopMeasureAsync(context.ActionName, context.CurrentState.Name); - - public Task BeforeStateExitAsync(IStateActionContext context) - => StopMeasurementAsync(); - - public Task AfterStateExitAsync(IStateActionContext context) - => StopMeasureAsync(context.ActionName, context.CurrentState.Name); - - public Task BeforeStateFinalizeAsync(IStateActionContext context) - => StopMeasurementAsync(); - - public Task AfterStateFinalizeAsync(IStateActionContext context) - => StopMeasureAsync(context.ActionName, context.CurrentState.Name); - - public Task BeforeStateInitializeAsync(IStateActionContext context) - => StopMeasurementAsync(); - - public Task AfterStateInitializeAsync(IStateActionContext context) - => StopMeasureAsync(context.ActionName, context.CurrentState.Name); - - public Task BeforeStateMachineFinalizeAsync(IStateMachineActionContext context) - => StopMeasurementAsync(); - - public Task AfterStateMachineFinalizeAsync(IStateMachineActionContext context) - => StopMeasureAsync("Finalize", context.StateMachine.Id.Name); - - public Task BeforeStateMachineInitializeAsync(IStateMachineInitializationContext context) - => StopMeasurementAsync(); - - public Task AfterStateMachineInitializeAsync(IStateMachineInitializationContext context) - => StopMeasureAsync("Initialize", context.StateMachine.Id.Name); - - public Task BeforeTransitionEffectAsync(ITransitionContext context) - => StopMeasurementAsync(); - - public Task AfterTransitionEffectAsync(ITransitionContext context) - { - if (Trace.Event != null) - { - Stopwatch.Stop(); - - var step = Trace.AddStep( - "Effect", - context.TargetState != null - ? $"{context.SourceState.Name} - {context.Event.Name} -> {context.TargetState.Name}" - : $"{context.SourceState.Name} - {context.Event.Name} ->", - Stopwatch.Elapsed - ); - - step.Exceptions.Add(Exception); - } - - return Task.CompletedTask; - } - - public Task BeforeTransitionGuardAsync(IGuardContext context) - => StopMeasurementAsync(); - - public Task AfterTransitionGuardAsync(IGuardContext context, bool guardResult) - { - if (Trace.Event != null) - { - Stopwatch.Stop(); - - var step = Trace.AddStep( - "Guard", - context.TargetState != null - ? $"{context.SourceState.Name} - {context.Event.Name} -> {context.TargetState.Name}" - : $"{context.SourceState.Name} - {context.Event.Name} ->", - Stopwatch.Elapsed - ); - - step.Exceptions.Add(Exception); - } - - return Task.CompletedTask; - } - - public Task OnStateEntryExceptionAsync(IStateActionContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnStateExitExceptionAsync(IStateActionContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnStateMachineFinalizationExceptionAsync(IStateMachineActionContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnStateMachineInitializationExceptionAsync(IStateMachineInitializationContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnTransitionGuardExceptionAsync(IGuardContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnTransitionEffectExceptionAsync(ITransitionContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnStateInitializationExceptionAsync(IStateActionContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task OnStateFinalizationExceptionAsync(IStateActionContext context, Exception exception) - => SetExceptionAsync(exception); - - public Task AfterHydrateAsync(IStateMachineActionContext context) - => Task.CompletedTask; - - public Task BeforeDehydrateAsync(IStateMachineActionContext context) - => Task.CompletedTask; - - public Task BeforeProcessEventAsync(IEventContext context) - { - if (context.Event.GetType().GetCustomAttribute() == null) - { - Trace.Event = context.Event; - OverallStopwatch.Start(); - } - - return Task.FromResult(true); - } - - public Task AfterProcessEventAsync(IEventContext context) - { - if (Trace.Event != null) - { - OverallStopwatch.Stop(); - Trace.ExecutedAt = DateTime.Now; - Trace.Duration = OverallStopwatch.Elapsed; - Trace.Context = ((IStateflowsContextProvider)context).Context; - Trace.BehaviorId = Trace.Context.Id; - _ = Task.Run(() => ServiceProvider.GetRequiredService().SaveTraceAsync(Trace)); - } - - return Task.CompletedTask; - } - } -} diff --git a/Core/Stateflows/StateMachines/Engine/Processor.cs b/Core/Stateflows/StateMachines/Engine/Processor.cs index 177a317e..710cdb8e 100644 --- a/Core/Stateflows/StateMachines/Engine/Processor.cs +++ b/Core/Stateflows/StateMachines/Engine/Processor.cs @@ -2,22 +2,22 @@ using System.Linq; using System.Threading.Tasks; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using Microsoft.Extensions.DependencyInjection; using Stateflows.Common; +using Stateflows.Common.Context; using Stateflows.Common.Interfaces; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Models; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Context.Classes; -using Stateflows.Common.Context; -using Stateflows.StateMachines.Models; -using Stateflows.Common.Extensions; -using System.ComponentModel.DataAnnotations; -using Stateflows.Common.Initializer; +using System.Reflection; namespace Stateflows.StateMachines.Engine { internal class Processor : IEventProcessor { - public string BehaviorType => nameof(StateMachine); + public string BehaviorType => Constants.StateMachine; public readonly StateMachinesRegister Register; public readonly IEnumerable EventHandlers; @@ -44,7 +44,7 @@ private Task TryHandleEventAsync(EventContext conte : Task.FromResult(EventStatus.NotConsumed); } - public async Task ProcessEventAsync(BehaviorId id, TEvent @event, IServiceProvider serviceProvider) + public async Task ProcessEventAsync(BehaviorId id, TEvent @event, IServiceProvider serviceProvider, List exceptions) where TEvent : Event, new() { var result = EventStatus.Undelivered; @@ -66,51 +66,62 @@ public async Task ProcessEventAsync(BehaviorId id, TEvent @ { await executor.HydrateAsync(); - if (@event is CompoundRequest compoundRequest) + try { - result = EventStatus.Consumed; - var results = new List(); - foreach (var ev in compoundRequest.Events) + if (@event is CompoundRequest compoundRequest) { - ev.Headers.AddRange(@event.Headers); + result = EventStatus.Consumed; + var results = new List(); + foreach (var ev in compoundRequest.Events) + { + ev.Headers.AddRange(@event.Headers); + + executor.Context.SetEvent(ev); - executor.Context.SetEvent(ev); + executor.BeginScope(); + try + { + var status = await ExecuteBehaviorAsync(ev, result, stateflowsContext, graph, executor); + results.Add(new RequestResult(ev, ev.GetResponse(), status, new EventValidation(true, new List()))); + } + finally + { + executor.EndScope(); + + executor.Context.ClearEvent(); + } + } + + if (compoundRequest.Response == null) + { + compoundRequest.Respond(new CompoundResponse() + { + Results = results + }); + } + } + else + { executor.BeginScope(); try { - var status = await ExecuteBehaviorAsync(ev, result, stateflowsContext, graph, executor); - - results.Add(new RequestResult(ev, ev.GetResponse(), status, new EventValidation(true, new List()))); + result = await ExecuteBehaviorAsync(@event, result, stateflowsContext, graph, executor); } finally { executor.EndScope(); - - executor.Context.ClearEvent(); } } - - compoundRequest.Respond(new CompoundResponse() - { - Results = results - }); } - else + finally { - executor.BeginScope(); - try - { - result = await ExecuteBehaviorAsync(@event, result, stateflowsContext, graph, executor); - } - finally - { - executor.EndScope(); - } - } + exceptions.AddRange(executor.Context.Exceptions); - await executor.DehydrateAsync(); + await executor.DehydrateAsync(); + } + // out of try-finally to make sure that context won't be saved when execution fails await storage.DehydrateAsync(executor.Context.Context); } @@ -123,37 +134,43 @@ public async Task ProcessEventAsync(BehaviorId id, TEvent @ if (await executor.Inspector.BeforeProcessEventAsync(eventContext)) { - if (!executor.Initialized) + try { - var token = BehaviorClassesInitializations.Instance.AutoInitializationTokens.Find(token => token.BehaviorClass == executor.Context.Id.StateMachineClass); + var attributes = @event.GetType().GetCustomAttributes(); + if (!executor.Initialized && !attributes.Any()) + { + result = await executor.InitializeAsync(@event); + } - InitializationRequest initializationRequest; - if (token != null && (initializationRequest = await token.InitializationRequestFactory.Invoke(executor.ServiceProvider, executor.Context.Id)) != null) + if (result != EventStatus.Initialized) { - executor.Context.SetEvent(initializationRequest); + var handlingResult = await TryHandleEventAsync(eventContext); - executor.BeginScope(); - try + if (executor.Initialized) { - await executor.InitializeAsync(initializationRequest); + if (handlingResult != EventStatus.Consumed && handlingResult != EventStatus.NotInitialized) + { + result = await executor.ProcessAsync(@event); + } + else + { + result = handlingResult; + } } - finally + else { - executor.EndScope(); - - executor.Context.ClearEvent(); + result = result == EventStatus.NotInitialized + ? EventStatus.NotInitialized + : attributes.Any() + ? handlingResult + : EventStatus.Rejected; } } } - - result = await TryHandleEventAsync(eventContext); - - if (result != EventStatus.Consumed) + finally { - result = await executor.ProcessAsync(@event); + await executor.Inspector.AfterProcessEventAsync(eventContext); } - - await executor.Inspector.AfterProcessEventAsync(eventContext); } else { diff --git a/Core/Stateflows/StateMachines/Engine/Provider.cs b/Core/Stateflows/StateMachines/Engine/Provider.cs index e452f501..645166e8 100644 --- a/Core/Stateflows/StateMachines/Engine/Provider.cs +++ b/Core/Stateflows/StateMachines/Engine/Provider.cs @@ -30,7 +30,7 @@ public Provider(StateMachinesRegister register, StateflowsEngine engine, IServic public bool TryProvideBehavior(BehaviorId id, out IBehavior behavior) { - behavior = id.Type == nameof(StateMachine) && Register.StateMachines.ContainsKey($"{id.Name}.current") + behavior = id.Type == Constants.StateMachine && Register.StateMachines.ContainsKey($"{id.Name}.current") ? new Behavior(Engine, ServiceProvider, id) : null; @@ -38,6 +38,6 @@ public bool TryProvideBehavior(BehaviorId id, out IBehavior behavior) } public IEnumerable BehaviorClasses - => Register.StateMachines.Values.Select(sm => new BehaviorClass(nameof(StateMachine), sm.Name)).Distinct(); + => Register.StateMachines.Values.Select(sm => new BehaviorClass(Constants.StateMachine, sm.Name)).Distinct(); } } diff --git a/Core/Stateflows/StateMachines/EventHandlers/InitializationHandler.cs b/Core/Stateflows/StateMachines/EventHandlers/InitializationHandler.cs deleted file mode 100644 index 67a091d6..00000000 --- a/Core/Stateflows/StateMachines/EventHandlers/InitializationHandler.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Threading.Tasks; -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Inspection.Interfaces; - -namespace Stateflows.StateMachines.EventHandlers -{ - internal class InitializationHandler : IStateMachineEventHandler - { - public Type EventType => typeof(InitializationRequest); - - public async Task TryHandleEventAsync(IEventInspectionContext context) - where TEvent : Event, new() - { - if (context.Event is InitializationRequest request) - { - var executor = context.StateMachine.GetExecutor(); - - var initialized = await executor.InitializeAsync(request); - - request.Respond(new InitializationResponse() { InitializationSuccessful = initialized }); - - return EventStatus.Consumed; - } - - return EventStatus.NotConsumed; - } - } -} diff --git a/Core/Stateflows/StateMachines/EventHandlers/InitializeHandler.cs b/Core/Stateflows/StateMachines/EventHandlers/InitializeHandler.cs new file mode 100644 index 00000000..b1a20aed --- /dev/null +++ b/Core/Stateflows/StateMachines/EventHandlers/InitializeHandler.cs @@ -0,0 +1,20 @@ +using System; +using System.Threading.Tasks; +using Stateflows.Common; +using Stateflows.StateMachines.Inspection.Interfaces; + +namespace Stateflows.StateMachines.EventHandlers +{ + internal class InitializeHandler : IStateMachineEventHandler + { + public Type EventType => typeof(Initialize); + + public Task TryHandleEventAsync(IEventInspectionContext context) + where TEvent : Event, new() + => Task.FromResult( + context.Event is Initialize + ? EventStatus.NotInitialized + : EventStatus.NotConsumed + ); + } +} diff --git a/Core/Stateflows/StateMachines/EventHandlers/ResetHandler.cs b/Core/Stateflows/StateMachines/EventHandlers/ResetHandler.cs index fd353871..cecfbde4 100644 --- a/Core/Stateflows/StateMachines/EventHandlers/ResetHandler.cs +++ b/Core/Stateflows/StateMachines/EventHandlers/ResetHandler.cs @@ -15,7 +15,7 @@ public Task TryHandleEventAsync(IEventInspectionContext(this IStateEvents builder) + where TState : class, IBaseState { - if (typeof(StateMachine).GetMethod(nameof(StateMachine.OnInitializeAsync)).IsOverridenIn(stateMachineType)) + if (typeof(IStateEntry).IsAssignableFrom(typeof(TState))) { - builder.AddOnInitialize(c => - { - var context = (c as BaseContext).Context; - return context.Executor.GetStateMachine(stateMachineType, context).OnInitializeAsync(); - }); + builder.AddOnEntry(c => ((c as BaseContext).Context.Executor.GetState(c) as IStateEntry)?.OnEntryAsync()); } - if (typeof(StateMachine).GetMethod(nameof(StateMachine.OnFinalizeAsync)).IsOverridenIn(stateMachineType)) + if (typeof(IStateExit).IsAssignableFrom(typeof(TState))) { - builder.AddOnFinalize(c => - { - var context = (c as BaseContext).Context; - context.Executor.GetStateMachine(stateMachineType, context)?.OnFinalizeAsync(); - }); + builder.AddOnExit(c => ((c as BaseContext).Context.Executor.GetState(c) as IStateExit)?.OnExitAsync()); } + } - var baseInterfaceType = typeof(IInitializedBy<>); - foreach (var interfaceType in stateMachineType.GetInterfaces()) + public static void AddCompositeStateEvents(this ICompositeStateEvents builder) + where TCompositeState : class, IBaseCompositeState + { + if (typeof(ICompositeStateInitialization).IsAssignableFrom(typeof(TCompositeState))) { - if (interfaceType.GetGenericTypeDefinition() == baseInterfaceType) - { - var methodInfo = interfaceType.GetMethods().First(m => m.Name == "OnInitializeAsync"); - var requestType = interfaceType.GenericTypeArguments[0]; - var requestName = Stateflows.Common.EventInfo.GetName(requestType); - (builder as StateMachineBuilder).AddInitializer(requestType, requestName, c => - { - var stateMachine = c.Executor.GetStateMachine(stateMachineType, c); - return methodInfo.Invoke(stateMachine, new object[] { c.Event }) as Task; - }); - } + builder.AddOnInitialize(c => ((c as BaseContext).Context.Executor.GetState(c) as ICompositeStateInitialization)?.OnInitializeAsync()); } - } - public static void AddStateEvents(this IStateEvents builder) - where TState : BaseState - { - if (typeof(BaseState).GetMethod(nameof(BaseState.OnEntryAsync)).IsOverridenIn()) + if (typeof(ICompositeStateFinalization).IsAssignableFrom(typeof(TCompositeState))) { - builder.AddOnEntry(c => (c as BaseContext).Context.Executor.GetState(c)?.OnEntryAsync()); + builder.AddOnFinalize(c => ((c as BaseContext).Context.Executor.GetState(c) as ICompositeStateFinalization)?.OnFinalizeAsync()); } + } - if (typeof(BaseState).GetMethod(nameof(BaseState.OnExitAsync)).IsOverridenIn()) + public static void AddElseTransitionEvents(this IElseTransitionBuilder builder) + where TElseTransition : class, ITransitionEffect + where TEvent : Event, new() + { + if (typeof(ITransitionEffect).IsAssignableFrom(typeof(TElseTransition))) { - builder.AddOnExit(c => (c as BaseContext).Context.Executor.GetState(c)?.OnExitAsync()); + builder.AddEffect(c => ((c as BaseContext).Context.Executor.GetTransition(c) as ITransitionEffect)?.EffectAsync(c.Event)); } } - public static void AddCompositeStateEvents(this ICompositeStateEvents builder) - where TCompositeState : CompositeState + public static void AddTransitionEvents(this ITransitionBuilder builder) + where TTransition : class, IBaseTransition + where TEvent : Event, new() { - if (typeof(CompositeState).GetMethod(nameof(CompositeState.OnInitializeAsync)).IsOverridenIn()) + if (typeof(ITransitionGuard).IsAssignableFrom(typeof(TTransition))) { - builder.AddOnInitialize(c => (c as BaseContext).Context.Executor.GetState(c)?.OnInitializeAsync()); + builder.AddGuard(c => ((c as BaseContext).Context.Executor.GetTransition(c) as ITransitionGuard)?.GuardAsync(c.Event)); } - if (typeof(CompositeState).GetMethod(nameof(CompositeState.OnFinalizeAsync)).IsOverridenIn()) + if (typeof(ITransitionEffect).IsAssignableFrom(typeof(TTransition))) { - builder.AddOnFinalize(c => (c as BaseContext).Context.Executor.GetState(c)?.OnFinalizeAsync()); + builder.AddEffect(c => ((c as BaseContext).Context.Executor.GetTransition(c) as ITransitionEffect)?.EffectAsync(c.Event)); } } - public static void AddElseTransitionEvents(this IElseTransitionBuilder builder) - where TElseTransition : ElseTransition - where TEvent : Event, new() + public static void AddDefaultTransitionEvents(this IDefaultTransitionBuilder builder) + where TTransition : class, IBaseDefaultTransition { - if (typeof(BaseTransition).GetMethod(nameof(BaseTransition.EffectAsync)).IsOverridenIn()) + if (typeof(IDefaultTransitionGuard).IsAssignableFrom(typeof(TTransition))) { - builder.AddEffect(c => (c as BaseContext).Context.Executor.GetElseTransition(c)?.EffectAsync()); + builder.AddGuard(c => ((c as BaseContext).Context.Executor.GetDefaultTransition(c) as IDefaultTransitionGuard)?.GuardAsync()); } - } - public static void AddTransitionEvents(this ITransitionBuilder builder) - where TTransition : Transition - where TEvent : Event, new() - { - if (typeof(BaseTransition).GetMethod(nameof(BaseTransition.GuardAsync)).IsOverridenIn()) + if (typeof(IDefaultTransitionEffect).IsAssignableFrom(typeof(TTransition))) { - builder.AddGuard(c => (c as BaseContext).Context.Executor.GetTransition(c)?.GuardAsync()); + builder.AddEffect(c => ((c as BaseContext).Context.Executor.GetDefaultTransition(c) as IDefaultTransitionEffect)?.EffectAsync()); } + } - if (typeof(BaseTransition).GetMethod(nameof(BaseTransition.EffectAsync)).IsOverridenIn()) + public static void AddElseDefaultTransitionEvents(this IElseDefaultTransitionBuilder builder) + where TElseTransition : class, IDefaultTransitionEffect + { + if (typeof(IDefaultTransitionEffect).IsAssignableFrom(typeof(TElseTransition))) { - builder.AddEffect(c => (c as BaseContext).Context.Executor.GetTransition(c)?.EffectAsync()); + builder.AddEffect(c => ((c as BaseContext).Context.Executor.GetDefaultTransition(c) as IDefaultTransitionEffect)?.EffectAsync()); } } } diff --git a/Core/Stateflows/StateMachines/Extensions/IServiceCollectionExtensions.cs b/Core/Stateflows/StateMachines/Extensions/IServiceCollectionExtensions.cs deleted file mode 100644 index bc7e6277..00000000 --- a/Core/Stateflows/StateMachines/Extensions/IServiceCollectionExtensions.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using Stateflows.Common; -using Stateflows.Common.Extensions; - -namespace Stateflows.StateMachines.Extensions -{ - internal static class IServiceCollectionExtensions - { - public static IServiceCollection RegisterStateMachine(this IServiceCollection services) - where TStateMachine : StateMachine - => services?.AddServiceType(); - - public static IServiceCollection RegisterStateMachine(this IServiceCollection services, Type stateMachineType) - => services?.AddServiceType(stateMachineType); - - public static IServiceCollection RegisterState(this IServiceCollection services) - where TState : BaseState - => services?.AddServiceType(); - - public static IServiceCollection RegisterTransition(this IServiceCollection services) - where TTransition : Transition - where TEvent : Event, new() - => services?.AddServiceType(); - - public static IServiceCollection RegisterElseTransition(this IServiceCollection services) - where TElseTransition : ElseTransition - where TEvent : Event, new() - => services?.AddServiceType(); - - public static IServiceCollection RegisterExceptionHandler(this IServiceCollection services) - where TExceptionHandler : class, IStateMachineExceptionHandler - => services?.AddServiceType(); - - public static IServiceCollection RegisterObserver(this IServiceCollection services) - where TObserver : class, IStateMachineObserver - => services?.AddServiceType(); - - public static IServiceCollection RegisterInterceptor(this IServiceCollection services) - where TInterceptor : class, IStateMachineInterceptor - => services?.AddServiceType(); - } -} diff --git a/Core/Stateflows/StateMachines/Helpers/StateMachineAction.cs b/Core/Stateflows/StateMachines/Helpers/StateMachineAction.cs index 6a43b60b..867a31ea 100644 --- a/Core/Stateflows/StateMachines/Helpers/StateMachineAction.cs +++ b/Core/Stateflows/StateMachines/Helpers/StateMachineAction.cs @@ -10,8 +10,8 @@ public static class StateMachineAction public static Func> ToAsync(this Func stateMachineAction) => c => Task.Run(() => stateMachineAction(c)); - public static Func, Task> ToAsync(this Func, bool> stateMachineAction) - where TInitializationRequest : InitializationRequest, new() + public static Func, Task> ToAsync(this Func, bool> stateMachineAction) + where TInitializationEvent : Event, new() => c => Task.Run(() => stateMachineAction(c)); public static Func ToAsync(this Action stateMachineAction) diff --git a/Core/Stateflows/StateMachines/Inspection/Interfaces/IEventInspectionContext.cs b/Core/Stateflows/StateMachines/Inspection/Interfaces/IEventInspectionContext.cs index e7829874..3d1d16b0 100644 --- a/Core/Stateflows/StateMachines/Inspection/Interfaces/IEventInspectionContext.cs +++ b/Core/Stateflows/StateMachines/Inspection/Interfaces/IEventInspectionContext.cs @@ -4,7 +4,7 @@ namespace Stateflows.StateMachines.Inspection.Interfaces { - public interface IEventInspectionContext : IEventContext + public interface IEventInspectionContext : IEventActionContext where TEvent : Event, new() { new IStateMachineInspectionContext StateMachine { get; } diff --git a/Core/Stateflows/StateMachines/Interfaces/IStateMachineExceptionHandler.cs b/Core/Stateflows/StateMachines/Interfaces/IStateMachineExceptionHandler.cs index d3ca00ee..2f50d968 100644 --- a/Core/Stateflows/StateMachines/Interfaces/IStateMachineExceptionHandler.cs +++ b/Core/Stateflows/StateMachines/Interfaces/IStateMachineExceptionHandler.cs @@ -7,28 +7,28 @@ namespace Stateflows.StateMachines { public interface IStateMachineExceptionHandler { - Task OnStateMachineInitializationExceptionAsync(IStateMachineInitializationContext context, Exception exception) - => Task.CompletedTask; + Task OnStateMachineInitializationExceptionAsync(IStateMachineInitializationContext context, Exception exception) + => Task.FromResult(false); - Task OnStateMachineFinalizationExceptionAsync(IStateMachineActionContext context, Exception exception) - => Task.CompletedTask; + Task OnStateMachineFinalizationExceptionAsync(IStateMachineActionContext context, Exception exception) + => Task.FromResult(false); - Task OnTransitionGuardExceptionAsync(IGuardContext context, Exception exception) - => Task.CompletedTask; + Task OnTransitionGuardExceptionAsync(IGuardContext context, Exception exception) + => Task.FromResult(false); - Task OnTransitionEffectExceptionAsync(ITransitionContext context, Exception exception) - => Task.CompletedTask; + Task OnTransitionEffectExceptionAsync(ITransitionContext context, Exception exception) + => Task.FromResult(false); - Task OnStateInitializationExceptionAsync(IStateActionContext context, Exception exception) - => Task.CompletedTask; + Task OnStateInitializationExceptionAsync(IStateActionContext context, Exception exception) + => Task.FromResult(false); - Task OnStateFinalizationExceptionAsync(IStateActionContext context, Exception exception) - => Task.CompletedTask; + Task OnStateFinalizationExceptionAsync(IStateActionContext context, Exception exception) + => Task.FromResult(false); - Task OnStateEntryExceptionAsync(IStateActionContext context, Exception exception) - => Task.CompletedTask; + Task OnStateEntryExceptionAsync(IStateActionContext context, Exception exception) + => Task.FromResult(false); - Task OnStateExitExceptionAsync(IStateActionContext context, Exception exception) - => Task.CompletedTask; + Task OnStateExitExceptionAsync(IStateActionContext context, Exception exception) + => Task.FromResult(false); } } diff --git a/Core/Stateflows/StateMachines/Interfaces/IStateMachineInspector.cs b/Core/Stateflows/StateMachines/Interfaces/IStateMachineInspector.cs index fd527bd6..176298d4 100644 --- a/Core/Stateflows/StateMachines/Interfaces/IStateMachineInspector.cs +++ b/Core/Stateflows/StateMachines/Interfaces/IStateMachineInspector.cs @@ -8,7 +8,7 @@ namespace Stateflows.StateMachines public interface IStateMachineInspector { Task BeforeStateMachineInitializeAsync(IStateMachineInitializationInspectionContext context); - Task AfterStateMachineInitializeAsync(IStateMachineInitializationInspectionContext context); + Task AfterStateMachineInitializeAsync(IStateMachineInitializationInspectionContext context, bool initialized); Task BeforeStateMachineFinalizeAsync(IStateMachineActionInspectionContext context); Task AfterStateMachineFinalizeAsync(IStateMachineActionInspectionContext context); Task BeforeStateInitializeAsync(IStateActionInspectionContext context); diff --git a/Core/Stateflows/StateMachines/Interfaces/IStateMachineInterceptor.cs b/Core/Stateflows/StateMachines/Interfaces/IStateMachineInterceptor.cs index 04d56da3..435b8335 100644 --- a/Core/Stateflows/StateMachines/Interfaces/IStateMachineInterceptor.cs +++ b/Core/Stateflows/StateMachines/Interfaces/IStateMachineInterceptor.cs @@ -12,10 +12,10 @@ Task AfterHydrateAsync(IStateMachineActionContext context) Task BeforeDehydrateAsync(IStateMachineActionContext context) => Task.CompletedTask; - Task BeforeProcessEventAsync(IEventContext context) + Task BeforeProcessEventAsync(IEventActionContext context) => Task.FromResult(true); - Task AfterProcessEventAsync(IEventContext context) + Task AfterProcessEventAsync(IEventActionContext context) => Task.CompletedTask; } } diff --git a/Core/Stateflows/StateMachines/Interfaces/IStateMachineObserver.cs b/Core/Stateflows/StateMachines/Interfaces/IStateMachineObserver.cs index ebc9aa6c..c5a4dde8 100644 --- a/Core/Stateflows/StateMachines/Interfaces/IStateMachineObserver.cs +++ b/Core/Stateflows/StateMachines/Interfaces/IStateMachineObserver.cs @@ -9,7 +9,7 @@ public interface IStateMachineObserver Task BeforeStateMachineInitializeAsync(IStateMachineInitializationContext context) => Task.CompletedTask; - Task AfterStateMachineInitializeAsync(IStateMachineInitializationContext context) + Task AfterStateMachineInitializeAsync(IStateMachineInitializationContext context, bool initialized) => Task.CompletedTask; Task BeforeStateMachineFinalizeAsync(IStateMachineActionContext context) diff --git a/Core/Stateflows/StateMachines/Interfaces/IStateMachinesBuilder.cs b/Core/Stateflows/StateMachines/Interfaces/IStateMachinesBuilder.cs index 202e35fa..6d64bd89 100644 --- a/Core/Stateflows/StateMachines/Interfaces/IStateMachinesBuilder.cs +++ b/Core/Stateflows/StateMachines/Interfaces/IStateMachinesBuilder.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; using System.Collections.Generic; using Stateflows.StateMachines.Registration.Interfaces; @@ -8,13 +9,14 @@ public interface IStateMachinesBuilder { IStateMachinesBuilder AddFromAssembly(Assembly assembly); IStateMachinesBuilder AddFromAssemblies(IEnumerable assemblies); + [Obsolete("AddFromLoadedAssemblies() is deprecated, use AddFromAssembly(), AddFromAssemblies() or AddStateMachine() instead.")] IStateMachinesBuilder AddFromLoadedAssemblies(); IStateMachinesBuilder AddStateMachine(string stateMachineName, StateMachineBuildAction buildAction); IStateMachinesBuilder AddStateMachine(string stateMachineName, int version, StateMachineBuildAction buildAction); IStateMachinesBuilder AddStateMachine(string stateMachineName = null, int version = 1) - where TStateMachine : StateMachine; + where TStateMachine : class, IStateMachine; IStateMachinesBuilder AddStateMachine(int version) - where TStateMachine : StateMachine; + where TStateMachine : class, IStateMachine; IStateMachinesBuilder AddInterceptor() where TInterceptor : class, IStateMachineInterceptor; IStateMachinesBuilder AddInterceptor(StateMachineInterceptorFactory interceptorFactory); diff --git a/Core/Stateflows/StateMachines/Interfaces/Model/ICompositeState.cs b/Core/Stateflows/StateMachines/Interfaces/Model/ICompositeState.cs new file mode 100644 index 00000000..024412cf --- /dev/null +++ b/Core/Stateflows/StateMachines/Interfaces/Model/ICompositeState.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; + +namespace Stateflows.StateMachines +{ + public interface IBaseCompositeState : IBaseState + { } + + public interface ICompositeStateEntry : IBaseCompositeState + { + Task OnEntryAsync(); + } + + public interface ICompositeStateExit : IBaseCompositeState + { + Task OnExitAsync(); + } + + public interface ICompositeStateInitialization : IBaseCompositeState + { + Task OnInitializeAsync(); + } + + public interface ICompositeStateFinalization : IBaseCompositeState + { + Task OnFinalizeAsync(); + } +} diff --git a/Core/Stateflows/StateMachines/Interfaces/Model/IFinalizer.cs b/Core/Stateflows/StateMachines/Interfaces/Model/IFinalizer.cs new file mode 100644 index 00000000..9430cf30 --- /dev/null +++ b/Core/Stateflows/StateMachines/Interfaces/Model/IFinalizer.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Stateflows.StateMachines +{ + public interface IFinalizer + { + Task OnFinalizeAsync(); + } +} diff --git a/Core/Stateflows/StateMachines/Interfaces/Model/IInitializer.cs b/Core/Stateflows/StateMachines/Interfaces/Model/IInitializer.cs new file mode 100644 index 00000000..364cd1e9 --- /dev/null +++ b/Core/Stateflows/StateMachines/Interfaces/Model/IInitializer.cs @@ -0,0 +1,16 @@ +using Stateflows.Common; +using System.Threading.Tasks; + +namespace Stateflows.StateMachines +{ + public interface IInitializer + where TInitializationEvent : Event, new() + { + Task OnInitializeAsync(TInitializationEvent initializationEvent); + } + + public interface IDefaultInitializer + { + Task OnInitializeAsync(); + } +} diff --git a/Core/Stateflows/StateMachines/Interfaces/Model/IState.cs b/Core/Stateflows/StateMachines/Interfaces/Model/IState.cs new file mode 100644 index 00000000..8d7e9422 --- /dev/null +++ b/Core/Stateflows/StateMachines/Interfaces/Model/IState.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; + +namespace Stateflows.StateMachines +{ + public interface IVertex + { } + + public interface IBaseState : IVertex + { } + + public interface IStateEntry : IBaseState + { + Task OnEntryAsync(); + } + + public interface IStateExit : IBaseState + { + Task OnExitAsync(); + } + + public interface IFinalState : IVertex + { } + + public static class State + where TState : class, IVertex + { + public static string Name => typeof(TState).FullName; + } +} diff --git a/Core/Stateflows/StateMachines/Interfaces/Model/IStateMachine.cs b/Core/Stateflows/StateMachines/Interfaces/Model/IStateMachine.cs new file mode 100644 index 00000000..c7106ccf --- /dev/null +++ b/Core/Stateflows/StateMachines/Interfaces/Model/IStateMachine.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using Stateflows.StateMachines.Attributes; + +namespace Stateflows.StateMachines +{ + public interface IStateMachine + { + void Build(IStateMachineBuilder builder); + } + + public static class StateMachine + where TStateMachine : class, IStateMachine + { + public static string Name + { + get + { + var stateMachineType = typeof(TStateMachine); + var attribute = stateMachineType.GetCustomAttribute(); + return attribute != null && attribute.Name != null + ? attribute.Name + : stateMachineType.FullName; + } + } + + public static BehaviorClass ToClass() + => new BehaviorClass(BehaviorType.StateMachine, Name); + + public static BehaviorId ToId(string instance) + => new BehaviorId(ToClass(), instance); + } +} diff --git a/Core/Stateflows/StateMachines/Interfaces/Model/ITransition.cs b/Core/Stateflows/StateMachines/Interfaces/Model/ITransition.cs new file mode 100644 index 00000000..c60f57d5 --- /dev/null +++ b/Core/Stateflows/StateMachines/Interfaces/Model/ITransition.cs @@ -0,0 +1,34 @@ +using Stateflows.Common; +using System.Threading.Tasks; + +namespace Stateflows.StateMachines +{ + public interface IBaseTransition + where TEvent : Event, new() + { } + + public interface ITransitionEffect : IBaseTransition + where TEvent : Event, new() + { + Task EffectAsync(TEvent @event); + } + + public interface ITransitionGuard : IBaseTransition + where TEvent : Event, new() + { + Task GuardAsync(TEvent @event); + } + + public interface IBaseDefaultTransition + { } + + public interface IDefaultTransitionEffect : IBaseDefaultTransition + { + Task EffectAsync(); + } + + public interface IDefaultTransitionGuard : IBaseDefaultTransition + { + Task GuardAsync(); + } +} diff --git a/Core/Stateflows/StateMachines/Models/Graph.cs b/Core/Stateflows/StateMachines/Models/Graph.cs index be33317e..a0d01e6a 100644 --- a/Core/Stateflows/StateMachines/Models/Graph.cs +++ b/Core/Stateflows/StateMachines/Models/Graph.cs @@ -30,8 +30,10 @@ public Graph(string name, int version) public readonly Dictionary Vertices = new Dictionary(); public readonly Dictionary AllVertices = new Dictionary(); public readonly List AllEdges = new List(); + public readonly Dictionary> Initializers = new Dictionary>(); public readonly List InitializerTypes = new List(); + public Logic DefaultInitializer = null; private Logic finalize = null; public Logic Finalize diff --git a/Core/Stateflows/StateMachines/Models/Vertex.cs b/Core/Stateflows/StateMachines/Models/Vertex.cs index ae37b465..b49d8625 100644 --- a/Core/Stateflows/StateMachines/Models/Vertex.cs +++ b/Core/Stateflows/StateMachines/Models/Vertex.cs @@ -46,7 +46,7 @@ internal class Vertex public Dictionary Vertices { get; set; } = new Dictionary(); public List DeferredEvents { get; set; } = new List(); - public StateActionInitializationBuilder BehaviorInitializationBuilder { get; set; } + public StateActionInitializationBuilderAsync BehaviorInitializationBuilder { get; set; } public string BehaviorName { get; set; } public string BehaviorType { get; set; } public List BehaviorSubscriptions { get; set; } = new List(); diff --git a/Core/Stateflows/StateMachines/Registration/Builders/CompositeStateBuilder.cs b/Core/Stateflows/StateMachines/Registration/Builders/CompositeStateBuilder.cs index 0b7af0ef..cb50e180 100644 --- a/Core/Stateflows/StateMachines/Registration/Builders/CompositeStateBuilder.cs +++ b/Core/Stateflows/StateMachines/Registration/Builders/CompositeStateBuilder.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Stateflows.Common; +using Stateflows.Common.Registration; using Stateflows.StateMachines.Events; using Stateflows.StateMachines.Models; using Stateflows.StateMachines.Exceptions; @@ -10,7 +11,6 @@ using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Base; using Stateflows.StateMachines.Registration.Interfaces.Internal; -using Stateflows.Common.Registration; namespace Stateflows.StateMachines.Registration.Builders { @@ -28,7 +28,7 @@ internal class CompositeStateBuilder : public IServiceCollection Services { get; } - BehaviorClass IBehaviorBuilder.BehaviorClass => new BehaviorClass(nameof(StateMachine), Vertex.Graph.Name); + BehaviorClass IBehaviorBuilder.BehaviorClass => new BehaviorClass(Constants.StateMachine, Vertex.Graph.Name); int IBehaviorBuilder.BehaviorVersion => Vertex.Graph.Version; @@ -111,28 +111,28 @@ public IInitializedCompositeStateBuilder AddOnExit(Func(string targetVertexName, TransitionBuildAction transitionBuildAction = null) + public IInitializedCompositeStateBuilder AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() { - Builder.AddTransition(targetVertexName, transitionBuildAction); + Builder.AddTransition(targetStateName, transitionBuildAction); return this; } [DebuggerHidden] - public IInitializedCompositeStateBuilder AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction = null) + public IInitializedCompositeStateBuilder AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() { - Builder.AddElseTransition(targetVertexName, transitionBuildAction); + Builder.AddElseTransition(targetStateName, transitionBuildAction); return this; } [DebuggerHidden] - public IInitializedCompositeStateBuilder AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction = null) - => AddTransition(targetVertexName, builder => transitionBuildAction?.Invoke(builder as IDefaultTransitionBuilder)); + public IInitializedCompositeStateBuilder AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction = null) + => AddTransition(targetStateName, builder => transitionBuildAction?.Invoke(builder as IDefaultTransitionBuilder)); [DebuggerHidden] - public IInitializedCompositeStateBuilder AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction = null) - => AddElseTransition(targetVertexName, builder => transitionBuildAction?.Invoke(builder as IElseDefaultTransitionBuilder)); + public IInitializedCompositeStateBuilder AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction = null) + => AddElseTransition(targetStateName, builder => transitionBuildAction?.Invoke(builder as IElseDefaultTransitionBuilder)); [DebuggerHidden] public IInitializedCompositeStateBuilder AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) @@ -145,28 +145,28 @@ public IInitializedCompositeStateBuilder AddElseInternalTransition(ElseI => AddElseTransition(Constants.DefaultTransitionTarget, builder => transitionBuildAction?.Invoke(builder as IElseInternalTransitionBuilder)); [DebuggerHidden] - ITypedInitializedCompositeStateBuilder IStateTransitions.AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction) - => AddTransition(targetVertexName, transitionBuildAction) as ITypedInitializedCompositeStateBuilder; + ITypedInitializedCompositeStateBuilder IStateTransitions.AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction) + => AddTransition(targetStateName, transitionBuildAction) as ITypedInitializedCompositeStateBuilder; [DebuggerHidden] - ITypedInitializedCompositeStateBuilder IStateTransitions.AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction) - => AddElseTransition(targetVertexName, transitionBuildAction) as ITypedInitializedCompositeStateBuilder; + ITypedInitializedCompositeStateBuilder IStateTransitions.AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction) + => AddElseTransition(targetStateName, transitionBuildAction) as ITypedInitializedCompositeStateBuilder; [DebuggerHidden] - ITypedInitializedCompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction) - => AddDefaultTransition(targetVertexName, transitionBuildAction) as ITypedInitializedCompositeStateBuilder; + ITypedInitializedCompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction) + => AddDefaultTransition(targetStateName, transitionBuildAction) as ITypedInitializedCompositeStateBuilder; [DebuggerHidden] - ITypedInitializedCompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction) - => AddElseDefaultTransition(targetVertexName, transitionBuildAction) as ITypedInitializedCompositeStateBuilder; + ITypedInitializedCompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction) + => AddElseDefaultTransition(targetStateName, transitionBuildAction) as ITypedInitializedCompositeStateBuilder; [DebuggerHidden] ITypedInitializedCompositeStateBuilder IStateTransitions.AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) - => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder as IInternalTransitionBuilder)) as ITypedInitializedCompositeStateBuilder; + => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as ITypedInitializedCompositeStateBuilder; [DebuggerHidden] ITypedInitializedCompositeStateBuilder IStateTransitions.AddElseInternalTransition(ElseInternalTransitionBuildAction transitionBuildAction) - => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder as IElseInternalTransitionBuilder)) as ITypedInitializedCompositeStateBuilder; + => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as ITypedInitializedCompositeStateBuilder; #endregion #region AddState @@ -185,18 +185,18 @@ ITypedInitializedCompositeStateBuilder IStateMachineInitial AddVertex(stateName, VertexType.FinalState) as IFinalizedCompositeStateBuilder; + public IFinalizedCompositeStateBuilder AddFinalState(string finalStateName = FinalState.Name) + => AddVertex(finalStateName, VertexType.FinalState) as IFinalizedCompositeStateBuilder; [DebuggerHidden] - ITypedFinalizedCompositeStateBuilder IStateMachineFinal.AddFinalState(string stateName) - => AddVertex(stateName, VertexType.FinalState) as ITypedFinalizedCompositeStateBuilder; + ITypedFinalizedCompositeStateBuilder IStateMachineFinal.AddFinalState(string finalStateName) + => AddVertex(finalStateName, VertexType.FinalState) as ITypedFinalizedCompositeStateBuilder; #endregion #region AddCompositeState [DebuggerHidden] - public IInitializedCompositeStateBuilder AddCompositeState(string stateName, CompositeStateBuildAction compositeStateBuildAction) - => AddVertex(stateName, VertexType.CompositeState, vertex => compositeStateBuildAction?.Invoke(new CompositeStateBuilder(vertex, Services))); + public IInitializedCompositeStateBuilder AddCompositeState(string compositeStateName, CompositeStateBuildAction compositeStateBuildAction) + => AddVertex(compositeStateName, VertexType.CompositeState, vertex => compositeStateBuildAction?.Invoke(new CompositeStateBuilder(vertex, Services))); [DebuggerHidden] public IInitializedCompositeStateBuilder AddInitialState(string stateName, StateBuildAction stateBuildAction = null) @@ -213,12 +213,12 @@ public IInitializedCompositeStateBuilder AddInitialCompositeState(string stateNa } [DebuggerHidden] - ITypedInitializedCompositeStateBuilder IStateMachine.AddCompositeState(string stateName, CompositeStateBuildAction compositeStateBuildAction) - => AddCompositeState(stateName, compositeStateBuildAction) as ITypedInitializedCompositeStateBuilder; + ITypedInitializedCompositeStateBuilder IStateMachine.AddCompositeState(string compositeStateName, CompositeStateBuildAction compositeStateBuildAction) + => AddCompositeState(compositeStateName, compositeStateBuildAction) as ITypedInitializedCompositeStateBuilder; [DebuggerHidden] - ITypedInitializedCompositeStateBuilder IStateMachineInitial.AddInitialCompositeState(string stateName, CompositeStateBuildAction compositeStateBuildAction) - => AddInitialCompositeState(stateName, compositeStateBuildAction) as ITypedInitializedCompositeStateBuilder; + ITypedInitializedCompositeStateBuilder IStateMachineInitial.AddInitialCompositeState(string compositeStateName, CompositeStateBuildAction compositeStateBuildAction) + => AddInitialCompositeState(compositeStateName, compositeStateBuildAction) as ITypedInitializedCompositeStateBuilder; #endregion [DebuggerHidden] @@ -242,32 +242,32 @@ IInitializedCompositeStateBuilder IStateMachineInitial AddInitialState(stateName, stateBuildAction); [DebuggerHidden] - IInitializedCompositeStateBuilder IStateMachineInitial.AddInitialCompositeState(string stateName, CompositeStateBuildAction compositeStateBuildAction) - => AddInitialCompositeState(stateName, compositeStateBuildAction); + IInitializedCompositeStateBuilder IStateMachineInitial.AddInitialCompositeState(string compositeStateName, CompositeStateBuildAction compositeStateBuildAction) + => AddInitialCompositeState(compositeStateName, compositeStateBuildAction); [DebuggerHidden] - ICompositeStateBuilder IStateTransitions.AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction) - => AddTransition(targetVertexName, transitionBuildAction) as ICompositeStateBuilder; + ICompositeStateBuilder IStateTransitions.AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction) + => AddTransition(targetStateName, transitionBuildAction) as ICompositeStateBuilder; [DebuggerHidden] - ICompositeStateBuilder IStateTransitions.AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction) - => AddElseTransition(targetVertexName, transitionBuildAction) as ICompositeStateBuilder; + ICompositeStateBuilder IStateTransitions.AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction) + => AddElseTransition(targetStateName, transitionBuildAction) as ICompositeStateBuilder; [DebuggerHidden] - ICompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction) - => AddDefaultTransition(targetVertexName, transitionBuildAction) as ICompositeStateBuilder; + ICompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction) + => AddDefaultTransition(targetStateName, transitionBuildAction) as ICompositeStateBuilder; [DebuggerHidden] - ICompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction) - => AddElseDefaultTransition(targetVertexName, transitionBuildAction) as ICompositeStateBuilder; + ICompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction) + => AddElseDefaultTransition(targetStateName, transitionBuildAction) as ICompositeStateBuilder; [DebuggerHidden] ICompositeStateBuilder IStateTransitions.AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) - => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder as IInternalTransitionBuilder)) as ICompositeStateBuilder; + => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as ICompositeStateBuilder; [DebuggerHidden] ICompositeStateBuilder IStateTransitions.AddElseInternalTransition(ElseInternalTransitionBuildAction transitionBuildAction) - => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder as IElseInternalTransitionBuilder)) as ICompositeStateBuilder; + => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as ICompositeStateBuilder; [DebuggerHidden] ICompositeStateBuilder IStateUtils.AddDeferredEvent() @@ -282,28 +282,28 @@ ITypedCompositeStateBuilder IStateUtils.AddDeferred => AddDeferredEvent() as ITypedCompositeStateBuilder; [DebuggerHidden] - ITypedCompositeStateBuilder IStateTransitions.AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction) - => AddTransition(targetVertexName, transitionBuildAction) as ITypedCompositeStateBuilder; + ITypedCompositeStateBuilder IStateTransitions.AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction) + => AddTransition(targetStateName, transitionBuildAction) as ITypedCompositeStateBuilder; [DebuggerHidden] - ITypedCompositeStateBuilder IStateTransitions.AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction) - => AddElseTransition(targetVertexName, transitionBuildAction) as ITypedCompositeStateBuilder; + ITypedCompositeStateBuilder IStateTransitions.AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction) + => AddElseTransition(targetStateName, transitionBuildAction) as ITypedCompositeStateBuilder; [DebuggerHidden] - ITypedCompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction) - => AddDefaultTransition(targetVertexName, transitionBuildAction) as ITypedCompositeStateBuilder; + ITypedCompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction) + => AddDefaultTransition(targetStateName, transitionBuildAction) as ITypedCompositeStateBuilder; [DebuggerHidden] - ITypedCompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction) - => AddElseDefaultTransition(targetVertexName, transitionBuildAction) as ITypedCompositeStateBuilder; + ITypedCompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction) + => AddElseDefaultTransition(targetStateName, transitionBuildAction) as ITypedCompositeStateBuilder; [DebuggerHidden] ITypedCompositeStateBuilder IStateTransitions.AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) - => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder as IInternalTransitionBuilder)) as ITypedCompositeStateBuilder; + => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as ITypedCompositeStateBuilder; [DebuggerHidden] ITypedCompositeStateBuilder IStateTransitions.AddElseInternalTransition(ElseInternalTransitionBuildAction transitionBuildAction) - => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder as IElseInternalTransitionBuilder)) as ITypedCompositeStateBuilder; + => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as ITypedCompositeStateBuilder; [DebuggerHidden] IFinalizedCompositeStateBuilder IStateEntry.AddOnEntry(Func actionAsync) @@ -318,56 +318,56 @@ IFinalizedCompositeStateBuilder IStateUtils.Add => AddDeferredEvent() as IFinalizedCompositeStateBuilder; [DebuggerHidden] - IFinalizedCompositeStateBuilder IStateTransitions.AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction) - => AddTransition(targetVertexName, transitionBuildAction) as IFinalizedCompositeStateBuilder; + IFinalizedCompositeStateBuilder IStateTransitions.AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction) + => AddTransition(targetStateName, transitionBuildAction) as IFinalizedCompositeStateBuilder; [DebuggerHidden] - IFinalizedCompositeStateBuilder IStateTransitions.AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction) - => AddElseTransition(targetVertexName, transitionBuildAction) as IFinalizedCompositeStateBuilder; + IFinalizedCompositeStateBuilder IStateTransitions.AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction) + => AddElseTransition(targetStateName, transitionBuildAction) as IFinalizedCompositeStateBuilder; [DebuggerHidden] - IFinalizedCompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction) - => AddDefaultTransition(targetVertexName, transitionBuildAction) as IFinalizedCompositeStateBuilder; + IFinalizedCompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction) + => AddDefaultTransition(targetStateName, transitionBuildAction) as IFinalizedCompositeStateBuilder; [DebuggerHidden] - IFinalizedCompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction) - => AddElseDefaultTransition(targetVertexName, transitionBuildAction) as IFinalizedCompositeStateBuilder; + IFinalizedCompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction) + => AddElseDefaultTransition(targetStateName, transitionBuildAction) as IFinalizedCompositeStateBuilder; [DebuggerHidden] IFinalizedCompositeStateBuilder IStateTransitions.AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) - => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder as IInternalTransitionBuilder)) as IFinalizedCompositeStateBuilder; + => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as IFinalizedCompositeStateBuilder; [DebuggerHidden] IFinalizedCompositeStateBuilder IStateTransitions.AddElseInternalTransition(ElseInternalTransitionBuildAction transitionBuildAction) - => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder as IElseInternalTransitionBuilder)) as IFinalizedCompositeStateBuilder; + => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as IFinalizedCompositeStateBuilder; [DebuggerHidden] ITypedFinalizedCompositeStateBuilder IStateUtils.AddDeferredEvent() => AddDeferredEvent() as ITypedFinalizedCompositeStateBuilder; [DebuggerHidden] - ITypedFinalizedCompositeStateBuilder IStateTransitions.AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction) - => AddTransition(targetVertexName, transitionBuildAction) as ITypedFinalizedCompositeStateBuilder; + ITypedFinalizedCompositeStateBuilder IStateTransitions.AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction) + => AddTransition(targetStateName, transitionBuildAction) as ITypedFinalizedCompositeStateBuilder; [DebuggerHidden] - ITypedFinalizedCompositeStateBuilder IStateTransitions.AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction) - => AddElseTransition(targetVertexName, transitionBuildAction) as ITypedFinalizedCompositeStateBuilder; + ITypedFinalizedCompositeStateBuilder IStateTransitions.AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction) + => AddElseTransition(targetStateName, transitionBuildAction) as ITypedFinalizedCompositeStateBuilder; [DebuggerHidden] - ITypedFinalizedCompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction) - => AddDefaultTransition(targetVertexName, transitionBuildAction) as ITypedFinalizedCompositeStateBuilder; + ITypedFinalizedCompositeStateBuilder IStateTransitions.AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction) + => AddDefaultTransition(targetStateName, transitionBuildAction) as ITypedFinalizedCompositeStateBuilder; [DebuggerHidden] - ITypedFinalizedCompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction) - => AddElseDefaultTransition(targetVertexName, transitionBuildAction) as ITypedFinalizedCompositeStateBuilder; + ITypedFinalizedCompositeStateBuilder IStateTransitions.AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction) + => AddElseDefaultTransition(targetStateName, transitionBuildAction) as ITypedFinalizedCompositeStateBuilder; [DebuggerHidden] ITypedFinalizedCompositeStateBuilder IStateTransitions.AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) - => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder as IInternalTransitionBuilder)) as ITypedFinalizedCompositeStateBuilder; + => AddInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as ITypedFinalizedCompositeStateBuilder; [DebuggerHidden] ITypedFinalizedCompositeStateBuilder IStateTransitions.AddElseInternalTransition(ElseInternalTransitionBuildAction transitionBuildAction) - => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder as IElseInternalTransitionBuilder)) as ITypedFinalizedCompositeStateBuilder; + => AddElseInternalTransition(builder => transitionBuildAction?.Invoke(builder)) as ITypedFinalizedCompositeStateBuilder; [DebuggerHidden] IFinalizedCompositeStateBuilder ICompositeStateEvents.AddOnInitialize(Func actionAsync) diff --git a/Core/Stateflows/StateMachines/Registration/Builders/StateBuilder.cs b/Core/Stateflows/StateMachines/Registration/Builders/StateBuilder.cs index 1bd1d4b3..10984798 100644 --- a/Core/Stateflows/StateMachines/Registration/Builders/StateBuilder.cs +++ b/Core/Stateflows/StateMachines/Registration/Builders/StateBuilder.cs @@ -14,6 +14,7 @@ using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Base; using Stateflows.StateMachines.Registration.Interfaces.Internal; +using Stateflows.StateMachines.Extensions; namespace Stateflows.StateMachines.Registration.Builders { @@ -30,7 +31,7 @@ internal partial class StateBuilder : public IServiceCollection Services { get; } - BehaviorClass IBehaviorBuilder.BehaviorClass => new BehaviorClass(nameof(StateMachine), Vertex.Graph.Name); + BehaviorClass IBehaviorBuilder.BehaviorClass => new BehaviorClass(Constants.StateMachine, Vertex.Graph.Name); int IBehaviorBuilder.BehaviorVersion => Vertex.Graph.Version; @@ -63,7 +64,14 @@ public IStateBuilder AddOnInitialize(Func actionAsync } else { - await c.Executor.Inspector.OnStateInitializeExceptionAsync(context, e); + if (!await c.Executor.Inspector.OnStateInitializeExceptionAsync(context, e)) + { + throw; + } + else + { + throw new ExecutionException(e); + } } } } @@ -94,7 +102,14 @@ public IStateBuilder AddOnFinalize(Func actionAsync) } else { - await c.Executor.Inspector.OnStateFinalizeExceptionAsync(context, e); + if (!await c.Executor.Inspector.OnStateFinalizeExceptionAsync(context, e)) + { + throw; + } + else + { + throw new ExecutionException(e); + } } } } @@ -125,7 +140,14 @@ public IStateBuilder AddOnEntry(Func actionAsync) } else { - await c.Executor.Inspector.OnStateEntryExceptionAsync(context, e); + if (!await c.Executor.Inspector.OnStateEntryExceptionAsync(context, e)) + { + throw; + } + else + { + throw new ExecutionException(e); + } } } } @@ -156,7 +178,14 @@ public IStateBuilder AddOnExit(Func actionAsync) } else { - await c.Executor.Inspector.OnStateExitExceptionAsync(context, e); + if (!await c.Executor.Inspector.OnStateExitExceptionAsync(context, e)) + { + throw; + } + else + { + throw new ExecutionException(e); + } } } } @@ -187,10 +216,10 @@ public IStateBuilder AddOnExit(Func actionAsync) #region Transitions [DebuggerHidden] - private IStateBuilder AddTransitionInternal(string targetVertexName, bool isElse, TransitionBuildAction transitionBuildAction = null) + private IStateBuilder AddTransitionInternal(string targetStateName, bool isElse, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() { - var targetEdgeType = targetVertexName == Constants.DefaultTransitionTarget + var targetEdgeType = targetStateName == Constants.DefaultTransitionTarget ? TriggerType.InternalTransition : TriggerType.Transition; @@ -202,14 +231,14 @@ private IStateBuilder AddTransitionInternal(string targetVertexName, boo Graph = Vertex.Graph, SourceName = Vertex.Name, Source = Vertex, - TargetName = targetVertexName, + TargetName = targetStateName, Type = EventInfo.Name == Constants.CompletionEvent ? TriggerType.DefaultTransition : targetEdgeType }; if (Vertex.Edges.ContainsKey(edge.Name)) - if (targetVertexName == Constants.DefaultTransitionTarget) + if (targetStateName == Constants.DefaultTransitionTarget) throw new TransitionDefinitionException($"Internal transition in '{edge.SourceName}' triggered by '{edge.Trigger}' is already registered", Vertex.Graph.Class); else if (edge.Trigger == Constants.CompletionEvent) @@ -226,22 +255,22 @@ private IStateBuilder AddTransitionInternal(string targetVertexName, boo } [DebuggerHidden] - public IStateBuilder AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction = null) + public IStateBuilder AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - => AddTransitionInternal(targetVertexName, false, transitionBuildAction); + => AddTransitionInternal(targetStateName, false, transitionBuildAction); [DebuggerHidden] - public IStateBuilder AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction = null) + public IStateBuilder AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - => AddTransitionInternal(targetVertexName, true, builder => transitionBuildAction?.Invoke(builder as IElseTransitionBuilder)); + => AddTransitionInternal(targetStateName, true, builder => transitionBuildAction?.Invoke(builder as IElseTransitionBuilder)); [DebuggerHidden] - public IStateBuilder AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction = null) - => AddTransition(targetVertexName, builder => transitionBuildAction?.Invoke(builder as IDefaultTransitionBuilder)); + public IStateBuilder AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction = null) + => AddTransition(targetStateName, builder => transitionBuildAction?.Invoke(builder as IDefaultTransitionBuilder)); [DebuggerHidden] - public IStateBuilder AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction = null) - => AddElseTransition(targetVertexName, builder => transitionBuildAction?.Invoke(builder as IElseDefaultTransitionBuilder)); + public IStateBuilder AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction = null) + => AddElseTransition(targetStateName, builder => transitionBuildAction?.Invoke(builder as IElseDefaultTransitionBuilder)); [DebuggerHidden] public IStateBuilder AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) @@ -254,20 +283,20 @@ public IStateBuilder AddElseInternalTransition(ElseInternalTransitionBui => AddElseTransition(Constants.DefaultTransitionTarget, builder => transitionBuildAction?.Invoke(builder as IElseInternalTransitionBuilder)); [DebuggerHidden] - ITypedStateBuilder IStateTransitions.AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction) - => AddTransition(targetVertexName, transitionBuildAction) as ITypedStateBuilder; + ITypedStateBuilder IStateTransitions.AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction) + => AddTransition(targetStateName, transitionBuildAction) as ITypedStateBuilder; [DebuggerHidden] - ITypedStateBuilder IStateTransitions.AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction) - => AddElseTransition(targetVertexName, transitionBuildAction) as ITypedStateBuilder; + ITypedStateBuilder IStateTransitions.AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction) + => AddElseTransition(targetStateName, transitionBuildAction) as ITypedStateBuilder; [DebuggerHidden] - ITypedStateBuilder IStateTransitions.AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction) - => AddDefaultTransition(targetVertexName, transitionBuildAction) as ITypedStateBuilder; + ITypedStateBuilder IStateTransitions.AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction) + => AddDefaultTransition(targetStateName, transitionBuildAction) as ITypedStateBuilder; [DebuggerHidden] - ITypedStateBuilder IStateTransitions.AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction) - => AddElseDefaultTransition(targetVertexName, transitionBuildAction) as ITypedStateBuilder; + ITypedStateBuilder IStateTransitions.AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction) + => AddElseDefaultTransition(targetStateName, transitionBuildAction) as ITypedStateBuilder; [DebuggerHidden] ITypedStateBuilder IStateTransitions.AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) @@ -284,7 +313,7 @@ ITypedStateBuilder IStateUtils.AddDeferredEvent() #region Submachine [DebuggerHidden] - public IBehaviorStateBuilder AddSubmachine(string submachineName, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilder initializationBuilder = null) + public IBehaviorStateBuilder AddSubmachine(string submachineName, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilderAsync initializationBuilder = null) { Vertex.BehaviorType = BehaviorType.StateMachine; Vertex.BehaviorName = submachineName; @@ -296,13 +325,13 @@ public IBehaviorStateBuilder AddSubmachine(string submachineName, EmbeddedBehavi } [DebuggerHidden] - IBehaviorTypedStateBuilder IStateSubmachine.AddSubmachine(string submachineName, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilder initializationBuilder) + IBehaviorTypedStateBuilder IStateSubmachine.AddSubmachine(string submachineName, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilderAsync initializationBuilder) => AddSubmachine(submachineName, buildAction, initializationBuilder) as IBehaviorTypedStateBuilder; #endregion #region DoActivity [DebuggerHidden] - public IBehaviorStateBuilder AddDoActivity(string doActivityName, EmbeddedBehaviorBuildAction buildAction = null, StateActionInitializationBuilder initializationBuilder = null) + public IBehaviorStateBuilder AddDoActivity(string doActivityName, EmbeddedBehaviorBuildAction buildAction = null, StateActionInitializationBuilderAsync initializationBuilder = null) { Vertex.BehaviorType = BehaviorType.Activity; Vertex.BehaviorName = doActivityName; @@ -314,7 +343,7 @@ public IBehaviorStateBuilder AddDoActivity(string doActivityName, EmbeddedBehavi } [DebuggerHidden] - IBehaviorTypedStateBuilder IStateDoActivity.AddDoActivity(string doActivityName, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilder initializationBuilder) + IBehaviorTypedStateBuilder IStateDoActivity.AddDoActivity(string doActivityName, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilderAsync initializationBuilder) => AddDoActivity(doActivityName, buildAction, initializationBuilder) as IBehaviorTypedStateBuilder; #endregion @@ -331,20 +360,20 @@ IBehaviorStateBuilder IStateUtils.AddDeferredEvent AddDeferredEvent() as IBehaviorStateBuilder; [DebuggerHidden] - IBehaviorStateBuilder IStateTransitions.AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction) - => AddTransition(targetVertexName, transitionBuildAction) as IBehaviorStateBuilder; + IBehaviorStateBuilder IStateTransitions.AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction) + => AddTransition(targetStateName, transitionBuildAction) as IBehaviorStateBuilder; [DebuggerHidden] - IBehaviorStateBuilder IStateTransitions.AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction) - => AddElseTransition(targetVertexName, transitionBuildAction) as IBehaviorStateBuilder; + IBehaviorStateBuilder IStateTransitions.AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction) + => AddElseTransition(targetStateName, transitionBuildAction) as IBehaviorStateBuilder; [DebuggerHidden] - IBehaviorStateBuilder IStateTransitions.AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction) - => AddDefaultTransition(targetVertexName, transitionBuildAction) as IBehaviorStateBuilder; + IBehaviorStateBuilder IStateTransitions.AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction) + => AddDefaultTransition(targetStateName, transitionBuildAction) as IBehaviorStateBuilder; [DebuggerHidden] - IBehaviorStateBuilder IStateTransitions.AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction) - => AddElseDefaultTransition(targetVertexName, transitionBuildAction) as IBehaviorStateBuilder; + IBehaviorStateBuilder IStateTransitions.AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction) + => AddElseDefaultTransition(targetStateName, transitionBuildAction) as IBehaviorStateBuilder; [DebuggerHidden] IBehaviorStateBuilder IStateTransitions.AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) @@ -359,20 +388,20 @@ IBehaviorTypedStateBuilder IStateUtils.AddDeferredEv => AddDeferredEvent() as IBehaviorTypedStateBuilder; [DebuggerHidden] - IBehaviorTypedStateBuilder IStateTransitions.AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction) - => AddTransition(targetVertexName, transitionBuildAction) as IBehaviorTypedStateBuilder; + IBehaviorTypedStateBuilder IStateTransitions.AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction) + => AddTransition(targetStateName, transitionBuildAction) as IBehaviorTypedStateBuilder; [DebuggerHidden] - IBehaviorTypedStateBuilder IStateTransitions.AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction) - => AddElseTransition(targetVertexName, transitionBuildAction) as IBehaviorTypedStateBuilder; + IBehaviorTypedStateBuilder IStateTransitions.AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction) + => AddElseTransition(targetStateName, transitionBuildAction) as IBehaviorTypedStateBuilder; [DebuggerHidden] - IBehaviorTypedStateBuilder IStateTransitions.AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction) - => AddDefaultTransition(targetVertexName, transitionBuildAction) as IBehaviorTypedStateBuilder; + IBehaviorTypedStateBuilder IStateTransitions.AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction) + => AddDefaultTransition(targetStateName, transitionBuildAction) as IBehaviorTypedStateBuilder; [DebuggerHidden] - IBehaviorTypedStateBuilder IStateTransitions.AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction) - => AddElseDefaultTransition(targetVertexName, transitionBuildAction) as IBehaviorTypedStateBuilder; + IBehaviorTypedStateBuilder IStateTransitions.AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction) + => AddElseDefaultTransition(targetStateName, transitionBuildAction) as IBehaviorTypedStateBuilder; [DebuggerHidden] IBehaviorTypedStateBuilder IStateTransitions.AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) @@ -386,14 +415,18 @@ public IEmbeddedBehaviorBuilder AddForwardedEvent(ForwardedEventBuildAct where TEvent : Event, new() => AddInternalTransition(b => { - b.AddEffect(c => + b.AddEffect(async c => { if (c.TryLocateBehavior(Vertex.GetBehaviorId(c.StateMachine.Id), out var behavior)) { - _ = behavior.SendAsync(c.Event); - } + var result = await behavior.SendAsync(c.Event); - return Task.CompletedTask; + c.StateMachine.GetExecutor().OverrideEventStatus( + result.Status == EventStatus.Consumed + ? EventStatus.Forwarded + : result.Status + ); + } }); buildAction?.Invoke(b as IForwardedEventBuilder); @@ -408,4 +441,3 @@ public IEmbeddedBehaviorBuilder AddSubscription() } } } - diff --git a/Core/Stateflows/StateMachines/Registration/Builders/StateMachineBuilder.cs b/Core/Stateflows/StateMachines/Registration/Builders/StateMachineBuilder.cs index 5b12fea3..e24b1516 100644 --- a/Core/Stateflows/StateMachines/Registration/Builders/StateMachineBuilder.cs +++ b/Core/Stateflows/StateMachines/Registration/Builders/StateMachineBuilder.cs @@ -13,6 +13,7 @@ using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Base; using Stateflows.StateMachines.Registration.Interfaces.Internal; +using Stateflows.Common.Extensions; namespace Stateflows.StateMachines.Registration.Builders { @@ -20,9 +21,6 @@ internal class StateMachineBuilder : IInitializedStateMachineBuilder, IFinalizedStateMachineBuilder, IStateMachineBuilder, - ITypedInitializedStateMachineBuilder, - ITypedFinalizedStateMachineBuilder, - ITypedStateMachineBuilder, IInternal, IBehaviorBuilder { @@ -30,7 +28,7 @@ internal class StateMachineBuilder : public IServiceCollection Services { get; } - BehaviorClass IBehaviorBuilder.BehaviorClass => new BehaviorClass(nameof(StateMachine), Result.Name); + BehaviorClass IBehaviorBuilder.BehaviorClass => new BehaviorClass(Constants.StateMachine, Result.Name); int IBehaviorBuilder.BehaviorVersion => Result.Version; @@ -58,54 +56,49 @@ public IInitializedStateMachineBuilder AddInitializer(Type initializerType, stri return this; } - public IInitializedStateMachineBuilder AddOnInitialize(Func> actionAsync) - => AddOnInitialize(c => + public IInitializedStateMachineBuilder AddDefaultInitializer(Func> actionAsync) + { + Result.DefaultInitializer = new Logic() { - var ctx = (c as BaseContext).Context; - var context = new StateMachineInitializationContext(ctx, ctx.Event as InitializationRequest); + Name = Constants.Initialize + }; + + Result.DefaultInitializer.Actions.Add(c => + { + var context = new StateMachineInitializationContext(c, c.Event as Initialize); return actionAsync(context); }); - public IInitializedStateMachineBuilder AddOnInitialize(Func, Task> actionAsync) - where TInitializationRequest : InitializationRequest, new() + return this; + } + + public IInitializedStateMachineBuilder AddInitializer(Func, Task> actionAsync) + where TInitializationEvent : Event, new() { actionAsync.ThrowIfNull(nameof(actionAsync)); - var initializerName = EventInfo.Name; + var initializerName = EventInfo.Name; - return AddInitializer(typeof(TInitializationRequest), initializerName, async c => + return AddInitializer(typeof(TInitializationEvent), initializerName, async c => { var result = false; - var context = new StateMachineInitializationContext(c, c.Event as TInitializationRequest); - try - { - result = await actionAsync(context); - } - catch (Exception e) - { - await c.Executor.Inspector.OnStateMachineInitializationExceptionAsync(context, e); - result = false; - } + var context = new StateMachineInitializationContext(c, c.Event as TInitializationEvent); + + result = await actionAsync(context); return result; }); } - public IInitializedStateMachineBuilder AddOnFinalize(Func actionAsync) + public IInitializedStateMachineBuilder AddFinalizer(Func actionAsync) { actionAsync.ThrowIfNull(nameof(actionAsync)); Result.Finalize.Actions.Add(async c => { var context = new StateMachineActionContext(c); - try - { - await actionAsync(context); - } - catch (Exception e) - { - await c.Executor.Inspector.OnStateMachineFinalizationExceptionAsync(context, e); - } + + await actionAsync(context); }); return this; @@ -164,7 +157,7 @@ public IInitializedStateMachineBuilder AddInitialCompositeState(string stateName public IInitializedStateMachineBuilder AddExceptionHandler() where TExceptionHandler : class, IStateMachineExceptionHandler { - Services.RegisterExceptionHandler(); + Services.AddServiceType(); AddExceptionHandler(serviceProvider => serviceProvider.GetRequiredService()); return this; @@ -180,7 +173,7 @@ public IInitializedStateMachineBuilder AddExceptionHandler(StateMachineException public IInitializedStateMachineBuilder AddInterceptor() where TInterceptor : class, IStateMachineInterceptor { - Services.RegisterInterceptor(); + Services.AddServiceType(); AddInterceptor(serviceProvider => serviceProvider.GetRequiredService()); return this; @@ -196,7 +189,7 @@ public IInitializedStateMachineBuilder AddInterceptor(StateMachineInterceptorFac public IInitializedStateMachineBuilder AddObserver() where TObserver : class, IStateMachineObserver { - Services.RegisterObserver(); + Services.AddServiceType(); AddObserver(serviceProvider => serviceProvider.GetRequiredService()); return this; @@ -227,14 +220,14 @@ IStateMachineBuilder IStateMachineUtils.AddExceptionHandle IStateMachineBuilder IStateMachineUtils.AddExceptionHandler() => AddExceptionHandler() as IStateMachineBuilder; - IStateMachineBuilder IStateMachineEvents.AddOnInitialize(Func> actionAsync) - => AddOnInitialize(actionAsync) as IStateMachineBuilder; + IStateMachineBuilder IStateMachineEvents.AddDefaultInitializer(Func> actionAsync) + => AddDefaultInitializer(actionAsync) as IStateMachineBuilder; - IStateMachineBuilder IStateMachineEvents.AddOnInitialize(Func, Task> actionAsync) - => AddOnInitialize(actionAsync) as IStateMachineBuilder; + IStateMachineBuilder IStateMachineEvents.AddInitializer(Func, Task> actionAsync) + => AddInitializer(actionAsync) as IStateMachineBuilder; - IStateMachineBuilder IStateMachineEvents.AddOnFinalize(Func actionAsync) - => AddOnFinalize(actionAsync) as IStateMachineBuilder; + IStateMachineBuilder IStateMachineEvents.AddFinalizer(Func actionAsync) + => AddFinalizer(actionAsync) as IStateMachineBuilder; IFinalizedStateMachineBuilder IStateMachineUtils.AddInterceptor(StateMachineInterceptorFactory interceptorFactory) => AddInterceptor(interceptorFactory) as IFinalizedStateMachineBuilder; @@ -254,84 +247,14 @@ IFinalizedStateMachineBuilder IStateMachineUtils. IFinalizedStateMachineBuilder IStateMachineUtils.AddExceptionHandler() => AddExceptionHandler() as IFinalizedStateMachineBuilder; - IFinalizedStateMachineBuilder IStateMachineEvents.AddOnInitialize(Func> actionAsync) - => AddOnInitialize(actionAsync) as IFinalizedStateMachineBuilder; - - IFinalizedStateMachineBuilder IStateMachineEvents.AddOnInitialize(Func, Task> actionAsync) - => AddOnInitialize(actionAsync) as IFinalizedStateMachineBuilder; - - IFinalizedStateMachineBuilder IStateMachineEvents.AddOnFinalize(Func actionAsync) - => AddOnFinalize(actionAsync) as IFinalizedStateMachineBuilder; - - - ITypedInitializedStateMachineBuilder IStateMachine.AddState(string stateName, StateBuildAction stateBuildAction) - => AddState(stateName, stateBuildAction) as ITypedInitializedStateMachineBuilder; - - ITypedFinalizedStateMachineBuilder IStateMachineFinal.AddFinalState(string stateName) - => AddFinalState(stateName) as ITypedFinalizedStateMachineBuilder; - - ITypedInitializedStateMachineBuilder IStateMachine.AddCompositeState(string stateName, CompositeStateBuildAction compositeStateBuildAction) - => AddCompositeState(stateName, compositeStateBuildAction) as ITypedInitializedStateMachineBuilder; - - ITypedInitializedStateMachineBuilder IStateMachineUtils.AddInterceptor(StateMachineInterceptorFactory interceptorFactory) - => AddInterceptor(interceptorFactory) as ITypedInitializedStateMachineBuilder; - - ITypedInitializedStateMachineBuilder IStateMachineUtils.AddInterceptor() - => AddInterceptor() as ITypedInitializedStateMachineBuilder; - - ITypedInitializedStateMachineBuilder IStateMachineUtils.AddObserver(StateMachineObserverFactory observerFactory) - => AddObserver(observerFactory) as ITypedInitializedStateMachineBuilder; - - ITypedInitializedStateMachineBuilder IStateMachineUtils.AddObserver() - => AddObserver() as ITypedInitializedStateMachineBuilder; - - ITypedInitializedStateMachineBuilder IStateMachineUtils.AddExceptionHandler(StateMachineExceptionHandlerFactory exceptionHandlerFactory) - => AddExceptionHandler(exceptionHandlerFactory) as ITypedInitializedStateMachineBuilder; - - ITypedInitializedStateMachineBuilder IStateMachineUtils.AddExceptionHandler() - => AddExceptionHandler() as ITypedInitializedStateMachineBuilder; - - ITypedInitializedStateMachineBuilder IStateMachineInitial.AddInitialState(string stateName, StateBuildAction stateBuildAction) - => AddInitialState(stateName, stateBuildAction) as ITypedInitializedStateMachineBuilder; - - ITypedInitializedStateMachineBuilder IStateMachineInitial.AddInitialCompositeState(string stateName, CompositeStateBuildAction compositeStateBuildAction) - => AddInitialCompositeState(stateName, compositeStateBuildAction) as ITypedInitializedStateMachineBuilder; - - ITypedStateMachineBuilder IStateMachineUtils.AddInterceptor(StateMachineInterceptorFactory interceptorFactory) - => AddInterceptor(interceptorFactory) as ITypedStateMachineBuilder; - - ITypedStateMachineBuilder IStateMachineUtils.AddInterceptor() - => AddInterceptor() as ITypedStateMachineBuilder; - - ITypedStateMachineBuilder IStateMachineUtils.AddObserver(StateMachineObserverFactory observerFactory) - => AddObserver(observerFactory) as ITypedStateMachineBuilder; - - ITypedStateMachineBuilder IStateMachineUtils.AddObserver() - => AddObserver() as ITypedStateMachineBuilder; - - ITypedStateMachineBuilder IStateMachineUtils.AddExceptionHandler() - => AddExceptionHandler() as ITypedStateMachineBuilder; - - ITypedStateMachineBuilder IStateMachineUtils.AddExceptionHandler(StateMachineExceptionHandlerFactory exceptionHandlerFactory) - => AddExceptionHandler(exceptionHandlerFactory) as ITypedStateMachineBuilder; - - ITypedFinalizedStateMachineBuilder IStateMachineUtils.AddInterceptor(StateMachineInterceptorFactory interceptorFactory) - => AddInterceptor(interceptorFactory) as ITypedFinalizedStateMachineBuilder; - - ITypedFinalizedStateMachineBuilder IStateMachineUtils.AddInterceptor() - => AddInterceptor() as ITypedFinalizedStateMachineBuilder; - - ITypedFinalizedStateMachineBuilder IStateMachineUtils.AddObserver(StateMachineObserverFactory observerFactory) - => AddObserver(observerFactory) as ITypedFinalizedStateMachineBuilder; - - ITypedFinalizedStateMachineBuilder IStateMachineUtils.AddObserver() - => AddObserver() as ITypedFinalizedStateMachineBuilder; + IFinalizedStateMachineBuilder IStateMachineEvents.AddDefaultInitializer(Func> actionAsync) + => AddDefaultInitializer(actionAsync) as IFinalizedStateMachineBuilder; - ITypedFinalizedStateMachineBuilder IStateMachineUtils.AddExceptionHandler(StateMachineExceptionHandlerFactory exceptionHandlerFactory) - => AddExceptionHandler(exceptionHandlerFactory) as ITypedFinalizedStateMachineBuilder; + IFinalizedStateMachineBuilder IStateMachineEvents.AddInitializer(Func, Task> actionAsync) + => AddInitializer(actionAsync) as IFinalizedStateMachineBuilder; - ITypedFinalizedStateMachineBuilder IStateMachineUtils.AddExceptionHandler() - => AddExceptionHandler() as ITypedFinalizedStateMachineBuilder; + IFinalizedStateMachineBuilder IStateMachineEvents.AddFinalizer(Func actionAsync) + => AddFinalizer(actionAsync) as IFinalizedStateMachineBuilder; #endregion } } diff --git a/Core/Stateflows/StateMachines/Registration/Builders/StateMachinesBuilder.cs b/Core/Stateflows/StateMachines/Registration/Builders/StateMachinesBuilder.cs index 9eb64512..4e4e3e39 100644 --- a/Core/Stateflows/StateMachines/Registration/Builders/StateMachinesBuilder.cs +++ b/Core/Stateflows/StateMachines/Registration/Builders/StateMachinesBuilder.cs @@ -24,7 +24,7 @@ public IStateMachinesBuilder AddFromAssembly(Assembly assembly) assembly.GetAttributedTypes().ToList().ForEach(@type => { if ( - typeof(StateMachine).IsAssignableFrom(@type) && + typeof(IStateMachine).IsAssignableFrom(@type) && @type.GetCustomAttributes(typeof(StateMachineBehaviorAttribute)).FirstOrDefault() is StateMachineBehaviorAttribute attribute) { Register.AddStateMachine(attribute.Name ?? @type.FullName, attribute.Version, @type); @@ -65,18 +65,18 @@ public IStateMachinesBuilder AddStateMachine(string stateMachineName, int versio return this; } - //[DebuggerHidden] + [DebuggerHidden] public IStateMachinesBuilder AddStateMachine(string stateMachineName = null, int version = 1) - where TStateMachine : StateMachine + where TStateMachine : class, IStateMachine { - Register.AddStateMachine(stateMachineName ?? StateMachineInfo.Name, version); + Register.AddStateMachine(stateMachineName ?? StateMachine.Name, version); return this; } [DebuggerHidden] public IStateMachinesBuilder AddStateMachine(int version) - where TStateMachine : StateMachine + where TStateMachine : class, IStateMachine => AddStateMachine(null, version); #region Observability diff --git a/Core/Stateflows/StateMachines/Registration/Builders/TransitionBuilder.cs b/Core/Stateflows/StateMachines/Registration/Builders/TransitionBuilder.cs index 5e505b74..ac88c0fe 100644 --- a/Core/Stateflows/StateMachines/Registration/Builders/TransitionBuilder.cs +++ b/Core/Stateflows/StateMachines/Registration/Builders/TransitionBuilder.cs @@ -1,15 +1,15 @@ using System; using System.Threading.Tasks; using Stateflows.Common; +using Stateflows.Common.Exceptions; using Stateflows.Common.Registration; using Stateflows.StateMachines.Models; +using Stateflows.StateMachines.Events; using Stateflows.StateMachines.Context.Classes; using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Extensions; using Stateflows.StateMachines.Registration.Interfaces.Base; -using Stateflows.StateMachines.Events; -using Stateflows.Common.Exceptions; namespace Stateflows.StateMachines.Registration.Builders { @@ -26,7 +26,7 @@ internal class TransitionBuilder : { public Edge Edge; - BehaviorClass IBehaviorBuilder.BehaviorClass => new BehaviorClass(nameof(StateMachine), Edge.Source.Graph.Name); + BehaviorClass IBehaviorBuilder.BehaviorClass => new BehaviorClass(Constants.StateMachine, Edge.Source.Graph.Name); int IBehaviorBuilder.BehaviorVersion => Edge.Source.Graph.Version; @@ -57,7 +57,14 @@ public ITransitionBuilder AddGuard(Func, Task AddEffect(Func, Tas } else { - await c.Executor.Inspector.OnTransitionEffectExceptionAsync(context, e); + if (!await c.Executor.Inspector.OnTransitionEffectExceptionAsync(context, e)) + { + throw; + } + else + { + throw new ExecutionException(e); + } } } } diff --git a/Core/Stateflows/StateMachines/Registration/Constants.cs b/Core/Stateflows/StateMachines/Registration/Constants.cs index 122d8501..3dcfee1b 100644 --- a/Core/Stateflows/StateMachines/Registration/Constants.cs +++ b/Core/Stateflows/StateMachines/Registration/Constants.cs @@ -2,6 +2,7 @@ { internal static class Constants { + public static readonly string StateMachine = nameof(StateMachine); public static readonly string StatesStack = nameof(StatesStack); public static readonly string DefaultTransitionTarget = string.Empty; public static readonly string CompletionEvent = string.Empty; diff --git a/Core/Stateflows/StateMachines/Registration/Extensions/Delegates.cs b/Core/Stateflows/StateMachines/Registration/Extensions/Delegates.cs index 4d8de3ea..813af0bb 100644 --- a/Core/Stateflows/StateMachines/Registration/Extensions/Delegates.cs +++ b/Core/Stateflows/StateMachines/Registration/Extensions/Delegates.cs @@ -3,6 +3,6 @@ namespace Stateflows.StateMachines.Registration.Extensions { - public delegate BehaviorId BehaviorIdBuilder(IEventContext context) + public delegate BehaviorId BehaviorIdBuilder(IEventActionContext context) where TEvent : Event, new(); } \ No newline at end of file diff --git a/Core/Stateflows/StateMachines/Registration/Extensions/LambdaExtensions.cs b/Core/Stateflows/StateMachines/Registration/Extensions/LambdaExtensions.cs index af18c993..3aaa3842 100644 --- a/Core/Stateflows/StateMachines/Registration/Extensions/LambdaExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Extensions/LambdaExtensions.cs @@ -17,11 +17,11 @@ public static Func AddStateMachineInvocationContext { var rootContext = (context as IRootContext).Context; - var stateMachineInstance = rootContext.Executor.GetStateMachine(graph.StateMachineType, rootContext); + var stateMachineInstance = rootContext.Executor.GetStateMachine(graph.StateMachineType); return (TResult)lambdaInfo.Invoke(stateMachineInstance, new object[] { context }); } - : lambda; + : lambda; } public static Action AddStateMachineInvocationContext(this Action lambda, Graph graph) @@ -33,7 +33,7 @@ public static Action AddStateMachineInvocationContext(this A ? (TContext context) => { var rootContext = (context as IRootContext).Context; - var stateMachineInstance = rootContext.Executor.GetStateMachine(graph.StateMachineType, rootContext); + var stateMachineInstance = rootContext.Executor.GetStateMachine(graph.StateMachineType); lambdaInfo.Invoke(stateMachineInstance, new object[] { context }); } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/ICompositeStateEvents.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/ICompositeStateEvents.cs index 395a077d..3317a3b1 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/ICompositeStateEvents.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/ICompositeStateEvents.cs @@ -6,8 +6,24 @@ namespace Stateflows.StateMachines.Registration.Interfaces.Base { public interface ICompositeStateEvents { + /// + /// Adds initialization handler to current state.
+ /// Use the following pattern to implement handler: + /// async c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Action handler TReturn AddOnInitialize(Func actionAsync); + /// + /// Adds finalization handler to current state.
+ /// Use the following pattern to implement handler: + /// async c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Action handler TReturn AddOnFinalize(Func actionAsync); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateDoActivity.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateDoActivity.cs index db91b81e..abb436ea 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateDoActivity.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateDoActivity.cs @@ -2,6 +2,6 @@ { public interface IStateDoActivity { - TReturn AddDoActivity(string doActivityName, EmbeddedBehaviorBuildAction buildAction = null, StateActionInitializationBuilder initializationBuilder = null); + TReturn AddDoActivity(string doActivityName, EmbeddedBehaviorBuildAction buildAction = null, StateActionInitializationBuilderAsync initializationBuilder = null); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateEntry.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateEntry.cs index 7b1d093e..d7abca8b 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateEntry.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateEntry.cs @@ -6,6 +6,14 @@ namespace Stateflows.StateMachines.Registration.Interfaces.Base { public interface IStateEntry { + /// + /// Adds entry handler to current state.
+ /// Use the following pattern to implement handler: + /// async c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Action handler TReturn AddOnEntry(Func actionAsync); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateExit.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateExit.cs index 3d242267..39a4e07b 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateExit.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateExit.cs @@ -6,6 +6,14 @@ namespace Stateflows.StateMachines.Registration.Interfaces.Base { public interface IStateExit { + /// + /// Adds exit handler to current state.
+ /// Use the following pattern to implement handler: + /// async c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Action handler TReturn AddOnExit(Func actionAsync); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachine.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachine.cs index 34a32e62..aa92c748 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachine.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachine.cs @@ -7,7 +7,7 @@ public partial interface IStateMachine #endregion #region AddCompositeState - TReturn AddCompositeState(string stateName, CompositeStateBuildAction compositeStateBuildAction); + TReturn AddCompositeState(string compositeStateName, CompositeStateBuildAction compositeStateBuildAction); #endregion } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineEvents.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineEvents.cs index 59f94735..7e027af5 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineEvents.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineEvents.cs @@ -7,11 +7,11 @@ namespace Stateflows.StateMachines.Registration.Interfaces.Base { public interface IStateMachineEvents { - TReturn AddOnInitialize(Func> actionAsync); + TReturn AddDefaultInitializer(Func> actionAsync); - TReturn AddOnInitialize(Func, Task> actionAsync) - where TInitializationRequest : InitializationRequest, new(); + TReturn AddInitializer(Func, Task> actionAsync) + where TInitializationEvent : Event, new(); - TReturn AddOnFinalize(Func actionAsync); + TReturn AddFinalizer(Func actionAsync); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineFinal.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineFinal.cs index 92ebad6d..2ed51e1e 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineFinal.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineFinal.cs @@ -2,6 +2,10 @@ { public partial interface IStateMachineFinal { - TReturn AddFinalState(string stateName = FinalState.Name); + /// + /// Adds final state to current composite state. + /// + /// Final state name + TReturn AddFinalState(string finalStateName = FinalState.Name); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineInitial.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineInitial.cs index b417aa8c..8b43d7b1 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineInitial.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateMachineInitial.cs @@ -7,7 +7,7 @@ public partial interface IStateMachineInitial #endregion #region AddCompositeState - TReturn AddInitialCompositeState(string stateName, CompositeStateBuildAction compositeStateBuildAction); + TReturn AddInitialCompositeState(string compositeStateName, CompositeStateBuildAction compositeStateBuildAction); #endregion } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateSubmachine.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateSubmachine.cs index 3ec7e730..d6e0e1a8 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateSubmachine.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateSubmachine.cs @@ -2,6 +2,6 @@ { public interface IStateSubmachine { - TReturn AddSubmachine(string submachineName, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilder initializationBuilder = null); + TReturn AddSubmachine(string submachineName, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilderAsync initializationBuilder = null); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateTransitions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateTransitions.cs index 14a981af..4eb553c3 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateTransitions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Base/IStateTransitions.cs @@ -5,21 +5,94 @@ namespace Stateflows.StateMachines.Registration.Interfaces.Base public interface IStateTransitions { #region Transitions - TReturn AddTransition(string targetVertexName, TransitionBuildAction transitionBuildAction = null) + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - second parameter. + /// + /// + ///
+ /// Event class + /// Target state name + /// Transition build action + TReturn AddTransition(string targetStateName, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new(); - TReturn AddDefaultTransition(string targetVertexName, DefaultTransitionBuildAction transitionBuildAction = null); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - second parameter. + /// + /// + ///
+ /// Target state name + /// Transition build action + TReturn AddDefaultTransition(string targetStateName, DefaultTransitionBuildAction transitionBuildAction = null); + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state name + /// Transition build action TReturn AddInternalTransition(InternalTransitionBuildAction transitionBuildAction) where TEvent : Event, new(); #endregion #region ElseTransitions - TReturn AddElseTransition(string targetVertexName, ElseTransitionBuildAction transitionBuildAction = null) + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Target state name + /// Transition build action + TReturn AddElseTransition(string targetStateName, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new(); - TReturn AddElseDefaultTransition(string targetVertexName, ElseDefaultTransitionBuildAction transitionBuildAction = null); + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Target state name + /// Transition build action + TReturn AddElseDefaultTransition(string targetStateName, ElseDefaultTransitionBuildAction transitionBuildAction = null); + /// + /// Adds internal else alternative for all -triggered transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Event class + /// Transition build action TReturn AddElseInternalTransition(ElseInternalTransitionBuildAction transitionBuildAction) where TEvent : Event, new(); #endregion diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Delegates.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Delegates.cs index 39730b4b..d0c94b6e 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Delegates.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Delegates.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Stateflows.Common; using Stateflows.StateMachines.Context.Interfaces; @@ -43,5 +44,7 @@ public delegate void ForwardedEventBuildAction(IForwardedEventBuilder StateActionInitializationBuilderAsync(IStateActionContext context); } \ No newline at end of file diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/ElseTransitions/BehaviorStateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/ElseTransitions/BehaviorStateBuilderElseDefaultTransitionTypedExtensions.cs new file mode 100644 index 00000000..a56d45b5 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/ElseTransitions/BehaviorStateBuilderElseDefaultTransitionTypedExtensions.cs @@ -0,0 +1,70 @@ +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; +using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorStateBuilderElseDefaultTransitionTypedExtensions + { + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorStateBuilder AddElseDefaultTransition(this IBehaviorStateBuilder builder) + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); + + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static IBehaviorStateBuilder AddElseDefaultTransition(this IBehaviorStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddElseDefaultTransition( + targetStateName, + t => t.AddElseDefaultTransitionEvents() + ); + } + + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static IBehaviorStateBuilder AddElseDefaultTransition(this IBehaviorStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/ElseTransitions/BehaviorStateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/ElseTransitions/BehaviorStateBuilderElseInternalTransitionTypedExtensions.cs new file mode 100644 index 00000000..94cf0698 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/ElseTransitions/BehaviorStateBuilderElseInternalTransitionTypedExtensions.cs @@ -0,0 +1,22 @@ +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.StateMachines.Registration; +using Stateflows.StateMachines.Registration.Interfaces; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorStateBuilderElseInternalTransitionTypedExtensions + { + /// + /// Adds internal else alternative for all -triggered transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + [DebuggerHidden] + public static IBehaviorStateBuilder AddElseInternalTransition(this IBehaviorStateBuilder builder) + where TEvent : Event, new() + where TElseTransition : class, ITransitionEffect + => builder.AddElseTransition(Constants.DefaultTransitionTarget); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/ElseTransitions/BehaviorStateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/ElseTransitions/BehaviorStateBuilderElseTransitionTypedExtensions.cs new file mode 100644 index 00000000..98f3d157 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/ElseTransitions/BehaviorStateBuilderElseTransitionTypedExtensions.cs @@ -0,0 +1,77 @@ +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; +using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorStateBuilderElseTransitionTypedExtensions + { + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorStateBuilder AddElseTransition(this IBehaviorStateBuilder builder) + where TEvent : Event, new() + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); + + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static IBehaviorStateBuilder AddElseTransition(this IBehaviorStateBuilder builder, string targetStateName) + where TEvent : Event, new() + where TElseTransition : class, ITransitionEffect + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddElseTransition( + targetStateName, + t => t.AddElseTransitionEvents() + ); + } + + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static IBehaviorStateBuilder AddElseTransition(this IBehaviorStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) + where TEvent : Event, new() + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Events/BehaviorStateBuilderEventsSyncExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Events/BehaviorStateBuilderEventsSyncExtensions.cs new file mode 100644 index 00000000..ce4b2daf --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Events/BehaviorStateBuilderEventsSyncExtensions.cs @@ -0,0 +1,42 @@ +using System; +using System.Diagnostics; +using Stateflows.StateMachines.Context.Interfaces; +using Stateflows.StateMachines.Registration.Builders; +using Stateflows.StateMachines.Registration.Extensions; +using Stateflows.StateMachines.Registration.Interfaces; + +namespace Stateflows.StateMachines.Sync +{ + public static class BehaviorStateBuilderEventsSyncExtensions + { + /// + /// Adds synchronous entry handler coming from current state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IBehaviorStateBuilder AddOnEntry(this IBehaviorStateBuilder builder, Action action) + => builder.AddOnEntry(action + .AddStateMachineInvocationContext((builder as StateBuilder).Vertex.Graph) + .ToAsync() + ); + + /// + /// Adds synchronous exit handler coming from current state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IBehaviorStateBuilder AddOnExit(this IBehaviorStateBuilder builder, Action action) + => builder.AddOnExit(action + .AddStateMachineInvocationContext((builder as StateBuilder).Vertex.Graph) + .ToAsync() + ); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Transitions/BehaviorStateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Transitions/BehaviorStateBuilderDefaultTransitionTypedExtensions.cs new file mode 100644 index 00000000..c111f872 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Transitions/BehaviorStateBuilderDefaultTransitionTypedExtensions.cs @@ -0,0 +1,110 @@ +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; +using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorStateBuilderDefaultTransitionTypedExtensions + { + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorStateBuilder AddDefaultTransition(this IBehaviorStateBuilder builder) + where TTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); + + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static IBehaviorStateBuilder AddDefaultTransition(this IBehaviorStateBuilder builder, string targetStateName) + where TTransition : class, IBaseDefaultTransition + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddDefaultTransition( + targetStateName, + t => t.AddDefaultTransitionEvents() + ); + } + + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static IBehaviorStateBuilder AddDefaultTransition(this IBehaviorStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Transitions/BehaviorStateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Transitions/BehaviorStateBuilderInternalTransitionTypedExtensions.cs new file mode 100644 index 00000000..ab573587 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Transitions/BehaviorStateBuilderInternalTransitionTypedExtensions.cs @@ -0,0 +1,37 @@ +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.StateMachines.Registration; +using Stateflows.StateMachines.Registration.Interfaces; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorStateBuilderInternalTransitionTypedExtensions + { + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorStateBuilder AddInternalTransition(this IBehaviorStateBuilder builder) + where TEvent : Event, new() + where TTransition : class, IBaseTransition + => builder.AddTransition(Constants.DefaultTransitionTarget); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Transitions/BehaviorStateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Transitions/BehaviorStateBuilderTransitionTypedExtensions.cs new file mode 100644 index 00000000..2ea423f1 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorStateBuilder/Transitions/BehaviorStateBuilderTransitionTypedExtensions.cs @@ -0,0 +1,129 @@ +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; +using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorStateBuilderTransitionTypedExtensions + { + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorStateBuilder AddTransition(this IBehaviorStateBuilder builder) + where TEvent : Event, new() + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); + + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static IBehaviorStateBuilder AddTransition(this IBehaviorStateBuilder builder, string targetStateName) + where TEvent : Event, new() + where TTransition : class, IBaseTransition + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddTransition( + targetStateName, + t => t.AddTransitionEvents() + ); + } + + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static IBehaviorStateBuilder AddTransition(this IBehaviorStateBuilder builder, TransitionBuildAction transitionBuildAction = null) + where TEvent : Event, new() + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/ElseTransitions/BehaviorTypedStateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/ElseTransitions/BehaviorTypedStateBuilderElseDefaultTransitionTypedExtensions.cs new file mode 100644 index 00000000..e88f0f38 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/ElseTransitions/BehaviorTypedStateBuilderElseDefaultTransitionTypedExtensions.cs @@ -0,0 +1,70 @@ +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; +using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorTypedStateBuilderElseDefaultTransitionTypedExtensions + { + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddElseDefaultTransition(this IBehaviorTypedStateBuilder builder) + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); + + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddElseDefaultTransition(this IBehaviorTypedStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddElseDefaultTransition( + targetStateName, + t => t.AddElseDefaultTransitionEvents() + ); + } + + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddElseDefaultTransition(this IBehaviorTypedStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/ElseTransitions/BehaviorTypedStateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/ElseTransitions/BehaviorTypedStateBuilderElseInternalTransitionTypedExtensions.cs new file mode 100644 index 00000000..67b63ef9 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/ElseTransitions/BehaviorTypedStateBuilderElseInternalTransitionTypedExtensions.cs @@ -0,0 +1,22 @@ +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.StateMachines.Registration; +using Stateflows.StateMachines.Registration.Interfaces; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorTypedStateBuilderElseInternalTransitionTypedExtensions + { + /// + /// Adds internal else alternative for all -triggered transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddElseInternalTransition(this IBehaviorTypedStateBuilder builder) + where TEvent : Event, new() + where TElseTransition : class, ITransitionEffect + => builder.AddElseTransition(Constants.DefaultTransitionTarget); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/ElseTransitions/BehaviorTypedStateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/ElseTransitions/BehaviorTypedStateBuilderElseTransitionTypedExtensions.cs new file mode 100644 index 00000000..1fef1cb0 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/ElseTransitions/BehaviorTypedStateBuilderElseTransitionTypedExtensions.cs @@ -0,0 +1,77 @@ +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; +using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorTypedStateBuilderElseTransitionTypedExtensions + { + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddElseTransition(this IBehaviorTypedStateBuilder builder) + where TEvent : Event, new() + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); + + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddElseTransition(this IBehaviorTypedStateBuilder builder, string targetStateName) + where TEvent : Event, new() + where TElseTransition : class, ITransitionEffect + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddElseTransition( + targetStateName, + t => t.AddElseTransitionEvents() + ); + } + + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddElseTransition(this IBehaviorTypedStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) + where TEvent : Event, new() + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/Transitions/BehaviorTypedStateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/Transitions/BehaviorTypedStateBuilderDefaultTransitionTypedExtensions.cs new file mode 100644 index 00000000..5ece8b25 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/Transitions/BehaviorTypedStateBuilderDefaultTransitionTypedExtensions.cs @@ -0,0 +1,110 @@ +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; +using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorTypedStateBuilderDefaultTransitionTypedExtensions + { + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddDefaultTransition(this IBehaviorTypedStateBuilder builder) + where TTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); + + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddDefaultTransition(this IBehaviorTypedStateBuilder builder, string targetStateName) + where TTransition : class, IBaseDefaultTransition + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddDefaultTransition( + targetStateName, + t => t.AddDefaultTransitionEvents() + ); + } + + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddDefaultTransition(this IBehaviorTypedStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/Transitions/BehaviorTypedStateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/Transitions/BehaviorTypedStateBuilderInternalTransitionTypedExtensions.cs new file mode 100644 index 00000000..4027945c --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/Transitions/BehaviorTypedStateBuilderInternalTransitionTypedExtensions.cs @@ -0,0 +1,37 @@ +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.StateMachines.Registration; +using Stateflows.StateMachines.Registration.Interfaces; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorTypedStateBuilderInternalTransitionTypedExtensions + { + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddInternalTransition(this IBehaviorTypedStateBuilder builder) + where TEvent : Event, new() + where TTransition : class, IBaseTransition + => builder.AddTransition(Constants.DefaultTransitionTarget); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/Transitions/BehaviorTypedStateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/Transitions/BehaviorTypedStateBuilderTransitionTypedExtensions.cs new file mode 100644 index 00000000..d413824c --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/BehaviorTypedStateBuilder/Transitions/BehaviorTypedStateBuilderTransitionTypedExtensions.cs @@ -0,0 +1,129 @@ +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; +using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; + +namespace Stateflows.StateMachines.Typed +{ + public static class BehaviorTypedStateBuilderTransitionTypedExtensions + { + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddTransition(this IBehaviorTypedStateBuilder builder) + where TEvent : Event, new() + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); + + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddTransition(this IBehaviorTypedStateBuilder builder, string targetStateName) + where TEvent : Event, new() + where TTransition : class, IBaseTransition + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddTransition( + targetStateName, + t => t.AddTransitionEvents() + ); + } + + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddTransition(this IBehaviorTypedStateBuilder builder, TransitionBuildAction transitionBuildAction = null) + where TEvent : Event, new() + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseDefaultTransitionTypedExtensions.cs index 917854b8..67aaf221 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseDefaultTransitionTypedExtensions.cs @@ -1,21 +1,60 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class CompositeStateBuilderElseDefaultTransitionTypedExtensions { + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static ICompositeStateBuilder AddElseDefaultTransition(this ICompositeStateBuilder builder) - where TElseTransition : ElseTransition - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name); + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); - public static ICompositeStateBuilder AddElseDefaultTransition(this ICompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition - => builder.AddElseTransition(targetVertexName); + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static ICompositeStateBuilder AddElseDefaultTransition(this ICompositeStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + => (builder as IStateBuilder).AddElseDefaultTransition(targetStateName) as ICompositeStateBuilder; + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ICompositeStateBuilder AddElseDefaultTransition(this ICompositeStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseInternalTransitionTypedExtensions.cs index ac61267f..0e39ebc5 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,16 @@ namespace Stateflows.StateMachines.Typed { public static class CompositeStateBuilderElseInternalTransitionTypedExtensions { + /// + /// Adds internal else alternative for all -triggered transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + [DebuggerHidden] public static ICompositeStateBuilder AddElseInternalTransition(this ICompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition + where TElseTransition : class, ITransitionEffect => builder.AddElseTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 6ce6bf7c..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class CompositeStateInitialBuilderElseInternalTransitionTypedPayloadExtensions - { - public static ICompositeStateBuilder AddElseInternalDataTransition(this ICompositeStateBuilder builder) - where TElseTransition : ElseTransition> - => builder.AddElseTransition, TElseTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElsePayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElsePayloadExtensions.cs deleted file mode 100644 index 05d9b098..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElsePayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class CompositeStateBuilderElsePayloadExtensions - { - public static ICompositeStateBuilder AddElseDataTransition(this ICompositeStateBuilder builder, string targetVertexName, ElseTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseTransition>(targetVertexName, transitionBuildAction); - - public static ICompositeStateBuilder AddElseInternalDataTransition(this ICompositeStateBuilder builder, ElseInternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseTransitionTypedExtensions.cs index bbf6479b..4efc9c2f 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/CompositeStateBuilderElseTransitionTypedExtensions.cs @@ -1,33 +1,67 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class CompositeStateBuilderElseTransitionTypedExtensions { + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static ICompositeStateBuilder AddElseTransition(this ICompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition - where TTargetState : BaseState - => AddElseTransition(builder, StateInfo.Name); + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); - public static ICompositeStateBuilder AddElseTransition(this ICompositeStateBuilder builder, string targetVertexName) + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static ICompositeStateBuilder AddElseTransition(this ICompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TElseTransition : ElseTransition - { - (builder as IInternal).Services.RegisterElseTransition(); - - return builder.AddElseTransition( - targetVertexName, - t => t.AddElseTransitionEvents() - ); - } + where TElseTransition : class, ITransitionEffect + => (builder as IStateBuilder).AddElseTransition(targetStateName) as ICompositeStateBuilder; + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ICompositeStateBuilder AddElseTransition(this ICompositeStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs index 1d2439c4..6c8cc7ac 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs @@ -1,21 +1,60 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class FinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions { + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IFinalizedCompositeStateBuilder AddElseDefaultTransition(this IFinalizedCompositeStateBuilder builder) - where TElseTransition : ElseTransition - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name); + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); - public static IFinalizedCompositeStateBuilder AddElseDefaultTransition(this IFinalizedCompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition - => builder.AddElseTransition(targetVertexName); + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static IFinalizedCompositeStateBuilder AddElseDefaultTransition(this IFinalizedCompositeStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + => (builder as IStateBuilder).AddElseDefaultTransition(targetStateName) as IFinalizedCompositeStateBuilder; + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IFinalizedCompositeStateBuilder AddElseDefaultTransition(this IFinalizedCompositeStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs index 6378d673..1b4dada0 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,16 @@ namespace Stateflows.StateMachines.Typed { public static class FinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions { + /// + /// Adds internal else alternative for all -triggered transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + [DebuggerHidden] public static IFinalizedCompositeStateBuilder AddElseInternalTransition(this IFinalizedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition + where TElseTransition : class, ITransitionEffect => builder.AddElseTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 4fac125e..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class FinalizedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions - { - public static IFinalizedCompositeStateBuilder AddElseInternalDataTransition(this IFinalizedCompositeStateBuilder builder) - where TElseTransition : ElseTransition> - => builder.AddElseTransition, TElseTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElsePayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElsePayloadExtensions.cs deleted file mode 100644 index 09720a57..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElsePayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class FinalizedCompositeStateBuilderElsePayloadExtensions - { - public static IFinalizedCompositeStateBuilder AddElseDataTransition(this IFinalizedCompositeStateBuilder builder, string targetVertexName, ElseTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseTransition>(targetVertexName, transitionBuildAction); - - public static IFinalizedCompositeStateBuilder AddElseInternalDataTransition(this IFinalizedCompositeStateBuilder builder, ElseInternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseTransitionTypedExtensions.cs index 10176196..5569d8c3 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseTransitionTypedExtensions.cs @@ -1,33 +1,67 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class FinalizedCompositeStateBuilderElseTransitionTypedExtensions { + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IFinalizedCompositeStateBuilder AddElseTransition(this IFinalizedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition - where TTargetState : BaseState - => AddElseTransition(builder, StateInfo.Name); + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); - public static IFinalizedCompositeStateBuilder AddElseTransition(this IFinalizedCompositeStateBuilder builder, string targetVertexName) + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static IFinalizedCompositeStateBuilder AddElseTransition(this IFinalizedCompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TElseTransition : ElseTransition - { - (builder as IInternal).Services.RegisterElseTransition(); - - return builder.AddElseTransition( - targetVertexName, - t => t.AddElseTransitionEvents() - ); - } + where TElseTransition : class, ITransitionEffect + => (builder as IStateBuilder).AddElseTransition(targetStateName) as IFinalizedCompositeStateBuilder; + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IFinalizedCompositeStateBuilder AddElseTransition(this IFinalizedCompositeStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 858b3e40..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/FinalizedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class FinalizedCompositeStateBuilderElseTransitionTypedPayloadExtensions - { - public static IFinalizedCompositeStateBuilder AddElseDataTransition(this IFinalizedCompositeStateBuilder builder) - where TElseTransition : ElseTransition> - where TTargetState : BaseState - => AddElseDataTransition(builder, StateInfo.Name); - - public static IFinalizedCompositeStateBuilder AddElseDataTransition(this IFinalizedCompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition> - { - (builder as IInternal).Services.RegisterElseTransition>(); - - return builder.AddElseTransition>( - targetVertexName, - t => t.AddElseTransitionEvents>() - ); - } - - public static IFinalizedCompositeStateBuilder AddElseDataTransition(this IFinalizedCompositeStateBuilder builder, ElseTransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs index 228d1dff..1f1ab82a 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs @@ -1,21 +1,60 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class InitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions { + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IInitializedCompositeStateBuilder AddElseDefaultTransition(this IInitializedCompositeStateBuilder builder) - where TElseTransition : ElseTransition - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name); + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); - public static IInitializedCompositeStateBuilder AddElseDefaultTransition(this IInitializedCompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition - => builder.AddElseTransition(targetVertexName); + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static IInitializedCompositeStateBuilder AddElseDefaultTransition(this IInitializedCompositeStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + => (builder as IStateBuilder).AddElseDefaultTransition(targetStateName) as IInitializedCompositeStateBuilder; + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IInitializedCompositeStateBuilder AddElseDefaultTransition(this IInitializedCompositeStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs index f7307bbe..72ecaeb0 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,16 @@ namespace Stateflows.StateMachines.Typed { public static class InitializedCompositeStateBuilderElseInternalTransitionTypedExtensions { + /// + /// Adds internal else alternative for all -triggered transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + [DebuggerHidden] public static IInitializedCompositeStateBuilder AddElseInternalTransition(this IInitializedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition + where TElseTransition : class, ITransitionEffect => builder.AddElseTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 7ad7b99d..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class InitializedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions - { - public static IInitializedCompositeStateBuilder AddElseInternalDataTransition(this IInitializedCompositeStateBuilder builder) - where TElseTransition : ElseTransition> - => builder.AddElseTransition, TElseTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElsePayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElsePayloadExtensions.cs deleted file mode 100644 index 761055ae..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElsePayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class InitializedCompositeStateBuilderElsePayloadExtensions - { - public static IInitializedCompositeStateBuilder AddElseDataTransition(this IInitializedCompositeStateBuilder builder, string targetVertexName, ElseTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseTransition>(targetVertexName, transitionBuildAction); - - public static IInitializedCompositeStateBuilder AddElseInternalDataTransition(this IInitializedCompositeStateBuilder builder, ElseInternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseTransitionTypedExtensions.cs index 981a36a6..6e73bd86 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseTransitionTypedExtensions.cs @@ -1,35 +1,67 @@ using System.Diagnostics; using Stateflows.Common; -using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class InitializedCompositeStateBuilderElseTransitionTypedExtensions { + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IInitializedCompositeStateBuilder AddElseTransition(this IInitializedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition - where TTargetState : BaseState - => AddElseTransition(builder, StateInfo.Name); + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state name [DebuggerHidden] - public static IInitializedCompositeStateBuilder AddElseTransition(this IInitializedCompositeStateBuilder builder, string targetVertexName) + public static IInitializedCompositeStateBuilder AddElseTransition(this IInitializedCompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TElseTransition : ElseTransition - { - (builder as IInternal).Services.RegisterElseTransition(); - - return builder.AddElseTransition( - targetVertexName, - t => t.AddElseTransitionEvents() - ); - } + where TElseTransition : class, ITransitionEffect + => (builder as IStateBuilder).AddElseTransition(targetStateName) as IInitializedCompositeStateBuilder; + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IInitializedCompositeStateBuilder AddElseTransition(this IInitializedCompositeStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 71fd3e8c..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/ElseTransitions/InitializedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Diagnostics; -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class InitializedCompositeStateBuilderElseTransitionTypedPayloadExtensions - { - public static IInitializedCompositeStateBuilder AddElseDataTransition(this IInitializedCompositeStateBuilder builder) - where TElseTransition : ElseTransition> - where TTargetState : BaseState - => AddElseDataTransition(builder, StateInfo.Name); - - [DebuggerHidden] - public static IInitializedCompositeStateBuilder AddElseDataTransition(this IInitializedCompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition> - { - (builder as IInternal).Services.RegisterElseTransition>(); - - return builder.AddElseTransition>( - targetVertexName, - t => t.AddElseTransitionEvents>() - ); - } - - public static IInitializedCompositeStateBuilder AddElseDataTransition(this IInitializedCompositeStateBuilder builder, ElseTransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/CompositeStateBuilderEventsSyncExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/CompositeStateBuilderEventsSyncExtensions.cs index 33a19cf7..0fbebcab 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/CompositeStateBuilderEventsSyncExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/CompositeStateBuilderEventsSyncExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Registration.Builders; using Stateflows.StateMachines.Registration.Extensions; @@ -8,26 +9,62 @@ namespace Stateflows.StateMachines.Sync { public static class CompositeStateBuilderEventsSyncExtensions { - public static ICompositeStateBuilder AddOnInitialize(this ICompositeStateBuilder builder, Action stateAction) - => builder.AddOnInitialize(stateAction + /// + /// Adds synchronous initialization handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static ICompositeStateBuilder AddOnInitialize(this ICompositeStateBuilder builder, Action action) + => builder.AddOnInitialize(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); - public static ICompositeStateBuilder AddOnFinalize(this ICompositeStateBuilder builder, Action stateAction) - => builder.AddOnFinalize(stateAction + /// + /// Adds synchronous finalization handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static ICompositeStateBuilder AddOnFinalize(this ICompositeStateBuilder builder, Action action) + => builder.AddOnFinalize(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); - public static ICompositeStateBuilder AddOnEntry(this ICompositeStateBuilder builder, Action stateAction) - => builder.AddOnEntry(stateAction + /// + /// Adds synchronous entry handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static ICompositeStateBuilder AddOnEntry(this ICompositeStateBuilder builder, Action action) + => builder.AddOnEntry(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); - public static ICompositeStateBuilder AddOnExit(this ICompositeStateBuilder builder, Action stateAction) - => builder.AddOnExit(stateAction + /// + /// Adds synchronous exit handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static ICompositeStateBuilder AddOnExit(this ICompositeStateBuilder builder, Action action) + => builder.AddOnExit(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/FinalizedCompositeStateBuilderEventsSyncExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/FinalizedCompositeStateBuilderEventsSyncExtensions.cs index 9c6693a0..261c711c 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/FinalizedCompositeStateBuilderEventsSyncExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/FinalizedCompositeStateBuilderEventsSyncExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Registration.Builders; using Stateflows.StateMachines.Registration.Extensions; @@ -8,26 +9,62 @@ namespace Stateflows.StateMachines.Sync { public static class FinalizedCompositeStateBuilderEventsSyncExtensions { - public static IFinalizedCompositeStateBuilder AddOnInitialize(this IFinalizedCompositeStateBuilder builder, Action stateAction) - => builder.AddOnInitialize(stateAction + /// + /// Adds synchronous initialization handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IFinalizedCompositeStateBuilder AddOnInitialize(this IFinalizedCompositeStateBuilder builder, Action action) + => builder.AddOnInitialize(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); - public static IFinalizedCompositeStateBuilder AddOnFinalize(this IFinalizedCompositeStateBuilder builder, Action stateAction) - => builder.AddOnFinalize(stateAction + /// + /// Adds synchronous finalization handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IFinalizedCompositeStateBuilder AddOnFinalize(this IFinalizedCompositeStateBuilder builder, Action action) + => builder.AddOnFinalize(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); - public static IFinalizedCompositeStateBuilder AddOnEntry(this IFinalizedCompositeStateBuilder builder, Action stateAction) - => builder.AddOnEntry(stateAction + /// + /// Adds synchronous entry handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IFinalizedCompositeStateBuilder AddOnEntry(this IFinalizedCompositeStateBuilder builder, Action action) + => builder.AddOnEntry(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); - public static IFinalizedCompositeStateBuilder AddOnExit(this IFinalizedCompositeStateBuilder builder, Action stateAction) - => builder.AddOnExit(stateAction + /// + /// Adds synchronous exit handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IFinalizedCompositeStateBuilder AddOnExit(this IFinalizedCompositeStateBuilder builder, Action action) + => builder.AddOnExit(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/InitializedCompositeStateBuilderEventsSyncExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/InitializedCompositeStateBuilderEventsSyncExtensions.cs index 64ea4b01..05266752 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/InitializedCompositeStateBuilderEventsSyncExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Events/InitializedCompositeStateBuilderEventsSyncExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Registration.Builders; using Stateflows.StateMachines.Registration.Extensions; @@ -8,26 +9,62 @@ namespace Stateflows.StateMachines.Sync { public static class InitializedCompositeStateBuilderEventsSyncExtensions { - public static IInitializedCompositeStateBuilder AddOnInitialize(this IInitializedCompositeStateBuilder builder, Action stateAction) - => builder.AddOnInitialize(stateAction + /// + /// Adds synchronous initialization handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IInitializedCompositeStateBuilder AddOnInitialize(this IInitializedCompositeStateBuilder builder, Action action) + => builder.AddOnInitialize(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); - public static IInitializedCompositeStateBuilder AddOnFinalize(this IInitializedCompositeStateBuilder builder, Action stateAction) - => builder.AddOnFinalize(stateAction + /// + /// Adds synchronous finalization handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IInitializedCompositeStateBuilder AddOnFinalize(this IInitializedCompositeStateBuilder builder, Action action) + => builder.AddOnFinalize(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); - public static IInitializedCompositeStateBuilder AddOnEntry(this IInitializedCompositeStateBuilder builder, Action stateAction) - => builder.AddOnEntry(stateAction + /// + /// Adds synchronous entry handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IInitializedCompositeStateBuilder AddOnEntry(this IInitializedCompositeStateBuilder builder, Action action) + => builder.AddOnEntry(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); - public static IInitializedCompositeStateBuilder AddOnExit(this IInitializedCompositeStateBuilder builder, Action stateAction) - => builder.AddOnExit(stateAction + /// + /// Adds synchronous exit handler to current composite state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IInitializedCompositeStateBuilder AddOnExit(this IInitializedCompositeStateBuilder builder, Action action) + => builder.AddOnExit(action .AddStateMachineInvocationContext((builder as CompositeStateBuilder).Vertex.Graph) .ToAsync() ); diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/StateMachine/CompositeStateBuilderTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/StateMachine/CompositeStateBuilderTypedExtensions.cs index 21b2ba44..a48a033f 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/StateMachine/CompositeStateBuilderTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/StateMachine/CompositeStateBuilderTypedExtensions.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Internal; @@ -8,16 +9,27 @@ namespace Stateflows.StateMachines.Typed public static class CompositeStateBuilderTypedExtensions { #region AddInitialState + /// + /// Adds initial state to current composite state. + /// + /// State class; must implement at least one of following interfaces: , + /// State build action [DebuggerHidden] public static IInitializedCompositeStateBuilder AddInitialState(this ICompositeStateBuilder builder, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - => builder.AddInitialState(StateInfo.Name, stateBuildAction); + where TState : class, IBaseState + => builder.AddInitialState(State.Name, stateBuildAction); + /// + /// Adds initial state to current composite state. + /// + /// State class; must implement at least one of following interfaces: , + /// State name + /// State build action [DebuggerHidden] public static IInitializedCompositeStateBuilder AddInitialState(this ICompositeStateBuilder builder, string stateName, StateTransitionsBuildAction stateBuildAction = null) - where TState : State + where TState : class, IBaseState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddInitialState( stateName, @@ -32,22 +44,33 @@ public static IInitializedCompositeStateBuilder AddInitialState(this ICo #endregion #region AddInitialCompositeState + /// + /// Adds initial composite state to current composite state. + /// + /// Composite state class; must implement at least one of following interfaces: , , , + /// Composite state build action [DebuggerHidden] - public static IInitializedCompositeStateBuilder AddInitialCompositeState(this ICompositeStateBuilder builder, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TState : State - => builder.AddInitialCompositeState(StateInfo.Name, compositeStateBuildAction); + public static IInitializedCompositeStateBuilder AddInitialCompositeState(this ICompositeStateBuilder builder, CompositeStateTransitionsBuildAction compositeStateBuildAction) + where TCompositeState : class, IBaseCompositeState + => builder.AddInitialCompositeState(State.Name, compositeStateBuildAction); + /// + /// Adds initial composite state to current composite state. + /// + /// Composite state class; must implement at least one of following interfaces: , , , + /// Composite state name + /// Composite state build action [DebuggerHidden] - public static IInitializedCompositeStateBuilder AddInitialCompositeState(this ICompositeStateBuilder builder, string stateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TState : State + public static IInitializedCompositeStateBuilder AddInitialCompositeState(this ICompositeStateBuilder builder, string compositeStateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) + where TCompositeState : class, IBaseCompositeState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddInitialCompositeState( - stateName, + compositeStateName, b => { - (b as IInitializedCompositeStateBuilder).AddStateEvents(); + (b as IInitializedCompositeStateBuilder).AddStateEvents(); compositeStateBuildAction?.Invoke(b as ITypedCompositeStateBuilder); } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/StateMachine/InitializedCompositeStateBuilderTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/StateMachine/InitializedCompositeStateBuilderTypedExtensions.cs index f648486c..9427bad9 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/StateMachine/InitializedCompositeStateBuilderTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/StateMachine/InitializedCompositeStateBuilderTypedExtensions.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Internal; @@ -8,23 +9,40 @@ namespace Stateflows.StateMachines.Typed public static class InitializedCompositeStateBuilderTypedExtensions { #region AddFinalState + /// + /// Adds final state to current composite state. + /// + /// class + /// Final state name [DebuggerHidden] - public static IFinalizedCompositeStateBuilder AddState(this IInitializedCompositeStateBuilder builder, string stateName = FinalState.Name) - where TFinalState : FinalState - => builder.AddFinalState(stateName); + public static IFinalizedCompositeStateBuilder AddState(this IInitializedCompositeStateBuilder builder, string finalStateName = FinalState.Name) + where TFinalState : class, IFinalState + => builder.AddFinalState(finalStateName); #endregion #region AddState + /// + /// Adds state to current composite state. + /// + /// State class; must implement at least one of following interfaces: , + /// State build action [DebuggerHidden] public static IInitializedCompositeStateBuilder AddState(this IInitializedCompositeStateBuilder builder, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - => builder.AddState(StateInfo.Name, stateBuildAction); + where TState : class, IBaseState + => builder.AddState(State.Name, stateBuildAction); + /// + /// Adds state to current composite state. + /// + /// State class; must implement at least one of following interfaces: , + /// State name + /// State build action + /// [DebuggerHidden] public static IInitializedCompositeStateBuilder AddState(this IInitializedCompositeStateBuilder builder, string stateName, StateTransitionsBuildAction stateBuildAction = null) - where TState : State + where TState : class, IBaseState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddState( stateName, @@ -39,19 +57,30 @@ public static IInitializedCompositeStateBuilder AddState(this IInitializ #endregion #region AddCompositeState + /// + /// Adds initial composite state to current composite state. + /// + /// Composite state class; must implement at least one of following interfaces: , , , + /// Composite state build action [DebuggerHidden] public static IInitializedCompositeStateBuilder AddCompositeState(this IInitializedCompositeStateBuilder builder, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TCompositeState : CompositeState - => builder.AddCompositeState(StateInfo.Name, compositeStateBuildAction); + where TCompositeState : class, IBaseCompositeState + => builder.AddCompositeState(State.Name, compositeStateBuildAction); + /// + /// Adds initial composite state to current composite state. + /// + /// Composite state class; must implement at least one of following interfaces: , , , + /// Composite state name + /// Composite state build action [DebuggerHidden] - public static IInitializedCompositeStateBuilder AddCompositeState(this IInitializedCompositeStateBuilder builder, string stateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TCompositeState : CompositeState + public static IInitializedCompositeStateBuilder AddCompositeState(this IInitializedCompositeStateBuilder builder, string compositeStateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) + where TCompositeState : class, IBaseCompositeState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddCompositeState( - stateName, + compositeStateName, b => { (b as IInitializedCompositeStateBuilder).AddStateEvents(); diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderDefaultTransitionTypedExtensions.cs index 9ad12368..c6f496af 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderDefaultTransitionTypedExtensions.cs @@ -1,21 +1,100 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class CompositeStateBuilderDefaultTransitionTypedExtensions { - public static ICompositeStateBuilder AddDefaultTransition(this ICompositeStateBuilder builder) - where TTransition : Transition - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static ICompositeStateBuilder AddDefaultTransition(this ICompositeStateBuilder builder) + where TDefaultTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); - public static ICompositeStateBuilder AddDefaultTransition(this ICompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition - => builder.AddTransition(targetVertexName); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ICompositeStateBuilder AddDefaultTransition(this ICompositeStateBuilder builder, string targetStateName) + where TDefaultTransition : class, IBaseDefaultTransition + => (builder as IStateBuilder).AddDefaultTransition(targetStateName) as ICompositeStateBuilder; + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ICompositeStateBuilder AddDefaultTransition(this ICompositeStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderInternalTransitionTypedExtensions.cs index 8fa15d2b..438117bd 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,31 @@ namespace Stateflows.StateMachines.Typed { public static class CompositeStateBuilderInternalTransitionTypedExtensions { + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] public static ICompositeStateBuilder AddInternalTransition(this ICompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition + where TTransition : class, IBaseTransition => builder.AddTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index a83546bd..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class CompositeStateBuilderInternalTransitionTypedPayloadExtensions - { - public static ICompositeStateBuilder AddInternalDataTransition(this ICompositeStateBuilder builder) - where TTransition : Transition> - => builder.AddTransition, TTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderPayloadExtensions.cs deleted file mode 100644 index acda6a8e..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderPayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class CompositeStateBuilderPayloadExtensions - { - public static ICompositeStateBuilder AddDataTransition(this ICompositeStateBuilder builder, string targetVertexName, TransitionBuildAction> transitionBuildAction = null) - => builder.AddTransition>(targetVertexName, transitionBuildAction); - - public static ICompositeStateBuilder AddInternalDataTransition(this ICompositeStateBuilder builder, InternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderTransitionTypedExtensions.cs index b53c8141..7830d33b 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderTransitionTypedExtensions.cs @@ -1,33 +1,119 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class CompositeStateBuilderTransitionTypedExtensions { + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static ICompositeStateBuilder AddTransition(this ICompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition - where TTargetState : BaseState - => AddTransition(builder, StateInfo.Name); + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); - public static ICompositeStateBuilder AddTransition(this ICompositeStateBuilder builder, string targetVertexName) + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ICompositeStateBuilder AddTransition(this ICompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TTransition : Transition - { - (builder as IInternal).Services.RegisterTransition(); - - return builder.AddTransition( - targetVertexName, - t => t.AddTransitionEvents() - ); - } + where TTransition : class, IBaseTransition + => (builder as IStateBuilder).AddTransition(targetStateName) as ICompositeStateBuilder; + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ICompositeStateBuilder AddTransition(this ICompositeStateBuilder builder, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 163be874..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/CompositeStateBuilderTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class CompositeStateBuilderTransitionTypedPayloadExtensions - { - public static ICompositeStateBuilder AddDataTransition(this ICompositeStateBuilder builder) - where TTransition : Transition> - where TTargetState : BaseState - => AddDataTransition(builder, StateInfo.Name); - - public static ICompositeStateBuilder AddDataTransition(this ICompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition> - { - (builder as IInternal).Services.RegisterTransition>(); - - return builder.AddTransition>( - targetVertexName, - t => t.AddTransitionEvents>() - ); - } - - public static ICompositeStateBuilder AddDataTransition(this ICompositeStateBuilder builder, TransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderDefaultTransitionTypedExtensions.cs index a3af570e..2e665e5d 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderDefaultTransitionTypedExtensions.cs @@ -1,21 +1,100 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class FinalizedCompositeStateBuilderDefaultTransitionTypedExtensions { - public static IFinalizedCompositeStateBuilder AddDefaultTransition(this IFinalizedCompositeStateBuilder builder) - where TTransition : Transition - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IFinalizedCompositeStateBuilder AddDefaultTransition(this IFinalizedCompositeStateBuilder builder) + where TDefaultTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); - public static IFinalizedCompositeStateBuilder AddDefaultTransition(this IFinalizedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition - => builder.AddTransition(targetVertexName); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static IFinalizedCompositeStateBuilder AddDefaultTransition(this IFinalizedCompositeStateBuilder builder, string targetStateName) + where TDefaultTransition : class, IBaseDefaultTransition + => (builder as IStateBuilder).AddDefaultTransition(targetStateName) as IFinalizedCompositeStateBuilder; + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IFinalizedCompositeStateBuilder AddDefaultTransition(this IFinalizedCompositeStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderInternalTransitionTypedExtensions.cs index 14db0b5e..4ddbd2a4 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderInternalTransitionTypedExtensions.cs @@ -1,14 +1,37 @@ using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; +using System.Diagnostics; namespace Stateflows.StateMachines.Typed { public static class FinalizedCompositeStateBuilderInternalTransitionTypedExtensions { + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] public static IFinalizedCompositeStateBuilder AddInternalTransition(this IFinalizedCompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition + where TTransition : class, IBaseTransition => builder.AddTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index f95d4b99..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class FinalizedCompositeStateBuilderInternalTransitionTypedPayloadExtensions - { - public static IFinalizedCompositeStateBuilder AddInternalDataTransition(this IFinalizedCompositeStateBuilder builder) - where TTransition : Transition> - => builder.AddTransition, TTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderPayloadExtensions.cs deleted file mode 100644 index b7ad5b02..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderPayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class FinalizedCompositeStateBuilderPayloadExtensions - { - public static IFinalizedCompositeStateBuilder AddDataTransition(this IFinalizedCompositeStateBuilder builder, string targetVertexName, TransitionBuildAction> transitionBuildAction = null) - => builder.AddTransition>(targetVertexName, transitionBuildAction); - - public static IFinalizedCompositeStateBuilder AddInternalDataTransition(this IFinalizedCompositeStateBuilder builder, InternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderTransitionTypedExtensions.cs index 92172255..3a5be877 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderTransitionTypedExtensions.cs @@ -1,33 +1,119 @@ using Stateflows.Common; -using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; +using System.Diagnostics; namespace Stateflows.StateMachines.Typed { public static class FinalizedCompositeStateBuilderTransitionTypedExtensions { + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IFinalizedCompositeStateBuilder AddTransition(this IFinalizedCompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition - where TTargetState : BaseState - => AddTransition(builder, StateInfo.Name); + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); - public static IFinalizedCompositeStateBuilder AddTransition(this IFinalizedCompositeStateBuilder builder, string targetVertexName) + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static IFinalizedCompositeStateBuilder AddTransition(this IFinalizedCompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TTransition : Transition - { - (builder as IInternal).Services.RegisterTransition(); - - return builder.AddTransition( - targetVertexName, - t => t.AddTransitionEvents() - ); - } + where TTransition : class, IBaseTransition + => (builder as IStateBuilder).AddTransition(targetStateName) as IFinalizedCompositeStateBuilder; + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IFinalizedCompositeStateBuilder AddTransition(this IFinalizedCompositeStateBuilder builder, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 867e6f24..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/FinalizedCompositeStateBuilderTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class FinalizedCompositeStateBuilderTransitionTypedPayloadExtensions - { - public static IFinalizedCompositeStateBuilder AddDataTransition(this IFinalizedCompositeStateBuilder builder) - where TTransition : Transition> - where TTargetState : BaseState - => AddDataTransition(builder, StateInfo.Name); - - public static IFinalizedCompositeStateBuilder AddDataTransition(this IFinalizedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition> - { - (builder as IInternal).Services.RegisterTransition>(); - - return builder.AddTransition>( - targetVertexName, - t => t.AddTransitionEvents>() - ); - } - - public static IFinalizedCompositeStateBuilder AddDataTransition(this IFinalizedCompositeStateBuilder builder, TransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderDefaultTransitionTypedExtensions.cs index 6839a39a..7a551ae6 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderDefaultTransitionTypedExtensions.cs @@ -1,21 +1,100 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class InitializedCompositeStateBuilderDefaultTransitionTypedExtensions { - public static IInitializedCompositeStateBuilder AddDefaultTransition(this IInitializedCompositeStateBuilder builder) - where TTransition : Transition - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static IInitializedCompositeStateBuilder AddDefaultTransition(this IInitializedCompositeStateBuilder builder) + where TDefaultTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); - public static IInitializedCompositeStateBuilder AddDefaultTransition(this IInitializedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition - => builder.AddTransition(targetVertexName); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static IInitializedCompositeStateBuilder AddDefaultTransition(this IInitializedCompositeStateBuilder builder, string targetStateName) + where TDefaultTransition : class, IBaseDefaultTransition + => (builder as IStateBuilder).AddDefaultTransition(targetStateName) as IInitializedCompositeStateBuilder; + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IInitializedCompositeStateBuilder AddDefaultTransition(this IInitializedCompositeStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderInternalTransitionTypedExtensions.cs index e3d05e99..94a96f46 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderInternalTransitionTypedExtensions.cs @@ -1,14 +1,37 @@ using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; +using System.Diagnostics; namespace Stateflows.StateMachines.Typed { public static class InitializedCompositeStateBuilderInternalTransitionTypedExtensions { + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] public static IInitializedCompositeStateBuilder AddInternalTransition(this IInitializedCompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition + where TTransition : class, IBaseTransition => builder.AddTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 9117dde2..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class InitializedCompositeStateBuilderInternalTransitionTypedPayloadExtensions - { - public static IInitializedCompositeStateBuilder AddInternalDataTransition(this IInitializedCompositeStateBuilder builder) - where TTransition : Transition> - => builder.AddTransition, TTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderPayloadExtensions.cs deleted file mode 100644 index 17e57077..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderPayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class InitializedCompositeStateBuilderPayloadExtensions - { - public static IInitializedCompositeStateBuilder AddDataTransition(this IInitializedCompositeStateBuilder builder, string targetVertexName, TransitionBuildAction> transitionBuildAction = null) - => builder.AddTransition>(targetVertexName, transitionBuildAction); - - public static IInitializedCompositeStateBuilder AddInternalDataTransition(this IInitializedCompositeStateBuilder builder, InternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderTransitionTypedExtensions.cs index 4b1adc5b..7f70fd1d 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderTransitionTypedExtensions.cs @@ -1,35 +1,119 @@ using System.Diagnostics; using Stateflows.Common; -using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class InitializedCompositeStateBuilderTransitionTypedExtensions { + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IInitializedCompositeStateBuilder AddTransition(this IInitializedCompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition - where TTargetState : BaseState - => AddTransition(builder, StateInfo.Name); + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name [DebuggerHidden] - public static IInitializedCompositeStateBuilder AddTransition(this IInitializedCompositeStateBuilder builder, string targetVertexName) + public static IInitializedCompositeStateBuilder AddTransition(this IInitializedCompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TTransition : Transition - { - (builder as IInternal).Services.RegisterTransition(); - - return builder.AddTransition( - targetVertexName, - t => t.AddTransitionEvents() - ); - } + where TTransition : class, IBaseTransition + => (builder as IStateBuilder).AddTransition(targetStateName) as IInitializedCompositeStateBuilder; + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IInitializedCompositeStateBuilder AddTransition(this IInitializedCompositeStateBuilder builder, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 71da1dac..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/CompositeStateBuilder/Transitions/InitializedCompositeStateBuilderTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Diagnostics; -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class InitializedCompositeStateBuilderTransitionTypedPayloadExtensions - { - public static IInitializedCompositeStateBuilder AddDataTransition(this IInitializedCompositeStateBuilder builder) - where TTransition : Transition> - where TTargetState : BaseState - => AddDataTransition(builder, StateInfo.Name); - - [DebuggerHidden] - public static IInitializedCompositeStateBuilder AddDataTransition(this IInitializedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition> - { - (builder as IInternal).Services.RegisterTransition>(); - - return builder.AddTransition>( - targetVertexName, - t => t.AddTransitionEvents>() - ); - } - - public static IInitializedCompositeStateBuilder AddDataTransition(this IInitializedCompositeStateBuilder builder, TransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseDefaultTransitionTypedExtensions.cs index fddfb891..3ecb994f 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseDefaultTransitionTypedExtensions.cs @@ -1,21 +1,70 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class StateBuilderElseDefaultTransitionTypedExtensions { + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IStateBuilder AddElseDefaultTransition(this IStateBuilder builder) - where TElseTransition : ElseTransition - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name); + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); - public static IStateBuilder AddElseDefaultTransition(this IStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition - => builder.AddElseTransition(targetVertexName); + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static IStateBuilder AddElseDefaultTransition(this IStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + { + (builder as IInternal).Services.AddServiceType(); + return builder.AddElseDefaultTransition( + targetStateName, + t => t.AddElseDefaultTransitionEvents() + ); + } + + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IStateBuilder AddElseDefaultTransition(this IStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseInternalTransitionTypedExtensions.cs index 253177e6..5aeb5cd8 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,16 @@ namespace Stateflows.StateMachines.Typed { public static class StateBuilderElseInternalTransitionTypedExtensions { + /// + /// Adds internal else alternative for all -triggered transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + [DebuggerHidden] public static IStateBuilder AddElseInternalTransition(this IStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition + where TElseTransition : class, ITransitionEffect => builder.AddElseTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index ff065042..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class StateBuilderElseInternalTransitionTypedPayloadExtensions - { - public static IStateBuilder AddElseInternalDataTransition(this IStateBuilder builder) - where TElseTransition : ElseTransition> - => builder.AddElseTransition, TElseTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElsePayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElsePayloadExtensions.cs deleted file mode 100644 index 68bcbe83..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElsePayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class StateBuilderElsePayloadExtensions - { - public static IStateBuilder AddElseDataTransition(this IStateBuilder builder, string targetVertexName, ElseTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseTransition>(targetVertexName, transitionBuildAction); - - public static IStateBuilder AddElseInternalDataTransition(this IStateBuilder builder, ElseInternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseTransitionTypedExtensions.cs index 59bd7edf..70c0e89e 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseTransitionTypedExtensions.cs @@ -1,4 +1,6 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.Common.Extensions; using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Internal; @@ -7,27 +9,69 @@ namespace Stateflows.StateMachines.Typed { public static class StateBuilderElseTransitionTypedExtensions { + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IStateBuilder AddElseTransition(this IStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition - where TTargetState : BaseState - => AddElseTransition(builder, StateInfo.Name); + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); - public static IStateBuilder AddElseTransition(this IStateBuilder builder, string targetVertexName) + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static IStateBuilder AddElseTransition(this IStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TElseTransition : ElseTransition + where TElseTransition : class, ITransitionEffect { - (builder as IInternal).Services.RegisterElseTransition(); + (builder as IInternal).Services.AddServiceType(); return builder.AddElseTransition( - targetVertexName, + targetStateName, t => t.AddElseTransitionEvents() ); } + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IStateBuilder AddElseTransition(this IStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 2479621d..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/ElseTransitions/StateBuilderElseTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class StateBuilderElseTransitionTypedPayloadExtensions - { - public static IStateBuilder AddElseDataTransition(this IStateBuilder builder) - where TElseTransition : ElseTransition> - where TTargetState : BaseState - => AddElseDataTransition(builder, StateInfo.Name); - - public static IStateBuilder AddElseDataTransition(this IStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition> - { - (builder as IInternal).Services.RegisterElseTransition>(); - - return builder.AddElseTransition>( - targetVertexName, - t => t.AddElseTransitionEvents>() - ); - } - - public static IStateBuilder AddElseDataTransition(this IStateBuilder builder, ElseTransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Events/StateBuilderEventsSyncExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Events/StateBuilderEventsSyncExtensions.cs index 35b2fb55..430aec0a 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Events/StateBuilderEventsSyncExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Events/StateBuilderEventsSyncExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Registration.Builders; using Stateflows.StateMachines.Registration.Extensions; @@ -8,14 +9,32 @@ namespace Stateflows.StateMachines.Sync { public static class StateBuilderEventsSyncExtensions { - public static IStateBuilder AddOnEntry(this IStateBuilder builder, Action stateAction) - => builder.AddOnEntry(stateAction + /// + /// Adds synchronous entry handler coming from current state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IStateBuilder AddOnEntry(this IStateBuilder builder, Action action) + => builder.AddOnEntry(action .AddStateMachineInvocationContext((builder as StateBuilder).Vertex.Graph) .ToAsync() ); - public static IStateBuilder AddOnExit(this IStateBuilder builder, Action stateAction) - => builder.AddOnExit(stateAction + /// + /// Adds synchronous exit handler coming from current state.
+ /// Use the following pattern to implement handler: + /// c => { + /// // handler logic here; action context is available via c parameter + /// } + ///
+ /// Synchronous action handler + [DebuggerHidden] + public static IStateBuilder AddOnExit(this IStateBuilder builder, Action action) + => builder.AddOnExit(action .AddStateMachineInvocationContext((builder as StateBuilder).Vertex.Graph) .ToAsync() ); diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Submachine/StateBuilderDoActivityTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Submachine/StateBuilderDoActivityTypedExtensions.cs new file mode 100644 index 00000000..b99d7444 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Submachine/StateBuilderDoActivityTypedExtensions.cs @@ -0,0 +1,22 @@ +using System; +using System.Diagnostics; +using Stateflows.Activities; +using Stateflows.StateMachines.Registration.Interfaces; + +namespace Stateflows.StateMachines.Typed +{ + public static class StateBuilderDoActivityTypedExtensions + { + /// + /// Embeds Activity in current state.

+ /// Embedded Activity will be initialized on state entry and finalized on state exit. Events can be forwarded from State Machine to embedded Activity using + ///
+ /// Activity class; must implement interface + /// Build action + /// Initialization builder; generates initialization event for embedded State Machine + [DebuggerHidden] + public static IBehaviorStateBuilder AddDoActivity(this IStateBuilder builder, EmbeddedBehaviorBuildAction buildAction = null, StateActionInitializationBuilderAsync initializationBuilder = null) + where TActivity : class, IActivity + => builder.AddDoActivity(Activity.Name, buildAction, initializationBuilder); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Submachine/StateBuilderSubmachineTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Submachine/StateBuilderSubmachineTypedExtensions.cs index 14a6e54f..c10bf3df 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Submachine/StateBuilderSubmachineTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Submachine/StateBuilderSubmachineTypedExtensions.cs @@ -1,11 +1,20 @@ -using Stateflows.StateMachines.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class StateBuilderSubmachineTypedExtensions { - public static IBehaviorStateBuilder AddSubmachine(this IStateBuilder builder, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilder initializationBuilder = null) - where TStateMachine : StateMachine - => builder.AddSubmachine(StateMachineInfo.Name, buildAction, initializationBuilder); + /// + /// Embeds State Machine in current state.

+ /// Embedded State Machine will be initialized on state entry and finalized on state exit. Events can be forwarded from State Machine to embedded State Machine using + ///
+ /// State Machine class; must implement interface + /// Build action + /// Initialization builder; generates initialization event for embedded State Machine + [DebuggerHidden] + public static IBehaviorStateBuilder AddSubmachine(this IStateBuilder builder, EmbeddedBehaviorBuildAction buildAction = null, StateActionInitializationBuilderAsync initializationBuilder = null) + where TStateMachine : class, IStateMachine + => builder.AddSubmachine(StateMachine.Name, buildAction, initializationBuilder); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderDefaultTransitionTypedExtensions.cs index c73918a3..36c68147 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderDefaultTransitionTypedExtensions.cs @@ -1,21 +1,110 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class StateBuilderDefaultTransitionTypedExtensions { + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IStateBuilder AddDefaultTransition(this IStateBuilder builder) - where TTransition : Transition - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name); + where TTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); - public static IStateBuilder AddDefaultTransition(this IStateBuilder builder, string targetVertexName) - where TTransition : Transition - => builder.AddTransition(targetVertexName); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static IStateBuilder AddDefaultTransition(this IStateBuilder builder, string targetStateName) + where TTransition : class, IBaseDefaultTransition + { + (builder as IInternal).Services.AddServiceType(); + return builder.AddDefaultTransition( + targetStateName, + t => t.AddDefaultTransitionEvents() + ); + } + + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IStateBuilder AddDefaultTransition(this IStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderInternalTransitionTypedExtensions.cs index ff5aca01..63c197b2 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,31 @@ namespace Stateflows.StateMachines.Typed { public static class StateBuilderInternalTransitionTypedExtensions { + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] public static IStateBuilder AddInternalTransition(this IStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition + where TTransition : class, IBaseTransition => builder.AddTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index e23e4862..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class StateBuilderInternalTransitionTypedPayloadExtensions - { - public static IStateBuilder AddInternalDataTransition(this IStateBuilder builder) - where TTransition : Transition> - => builder.AddTransition, TTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderPayloadExtensions.cs deleted file mode 100644 index 7c331fff..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderPayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class StateBuilderPayloadExtensions - { - public static IStateBuilder AddDataTransition(this IStateBuilder builder, string targetVertexName, TransitionBuildAction> transitionBuildAction = null) - => builder.AddTransition>(targetVertexName, transitionBuildAction); - - public static IStateBuilder AddInternalDataTransition(this IStateBuilder builder, InternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderTransitionTypedExtensions.cs index 8b4fe3da..db8609c6 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderTransitionTypedExtensions.cs @@ -1,4 +1,6 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.Common.Extensions; using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Internal; @@ -7,27 +9,121 @@ namespace Stateflows.StateMachines.Typed { public static class StateBuilderTransitionTypedExtensions { + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static IStateBuilder AddTransition(this IStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition - where TTargetState : BaseState - => AddTransition(builder, StateInfo.Name); + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); - public static IStateBuilder AddTransition(this IStateBuilder builder, string targetVertexName) + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static IStateBuilder AddTransition(this IStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TTransition : Transition + where TTransition : class, IBaseTransition { - (builder as IInternal).Services.RegisterTransition(); + (builder as IInternal).Services.AddServiceType(); return builder.AddTransition( - targetVertexName, + targetStateName, t => t.AddTransitionEvents() ); } + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static IStateBuilder AddTransition(this IStateBuilder builder, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 965f5e32..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateBuilder/Transitions/StateBuilderTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class StateBuilderTransitionTypedPayloadExtensions - { - public static IStateBuilder AddDataTransition(this IStateBuilder builder) - where TTransition : Transition> - where TTargetState : BaseState - => AddDataTransition(builder, StateInfo.Name); - - public static IStateBuilder AddDataTransition(this IStateBuilder builder, string targetVertexName) - where TTransition : Transition> - { - (builder as IInternal).Services.RegisterTransition>(); - - return builder.AddTransition>( - targetVertexName, - t => t.AddTransitionEvents>() - ); - } - - public static IStateBuilder AddDataTransition(this IStateBuilder builder, TransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/FinalizedStateMachineBuilderEventsSyncExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/FinalizedStateMachineBuilderEventsSyncExtensions.cs index ed8abedc..aac4c6eb 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/FinalizedStateMachineBuilderEventsSyncExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/FinalizedStateMachineBuilderEventsSyncExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Stateflows.Common; using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Registration.Builders; @@ -8,21 +9,24 @@ namespace Stateflows.StateMachines.Sync { public static class FinalizedStateMachineBuilderEventsSyncExtensions { - public static IFinalizedStateMachineBuilder AddOnInitialize(this IFinalizedStateMachineBuilder builder, Func stateMachineAction) - => builder.AddOnInitialize(stateMachineAction + [DebuggerHidden] + public static IFinalizedStateMachineBuilder AddDefaultInitializer(this IFinalizedStateMachineBuilder builder, Func stateMachineAction) + => builder.AddDefaultInitializer(stateMachineAction .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) .ToAsync() ); - public static IFinalizedStateMachineBuilder AddOnInitialize(this IFinalizedStateMachineBuilder builder, Func, bool> stateMachineAction) - where TInitializationRequest : InitializationRequest, new() - => builder.AddOnInitialize(stateMachineAction + [DebuggerHidden] + public static IFinalizedStateMachineBuilder AddInitializer(this IFinalizedStateMachineBuilder builder, Func, bool> stateMachineAction) + where TInitializationEvent : Event, new() + => builder.AddInitializer(stateMachineAction .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) .ToAsync() ); - public static IFinalizedStateMachineBuilder AddOnFinalize(this IFinalizedStateMachineBuilder builder, Action stateMachineAction) - => builder.AddOnFinalize(stateMachineAction + [DebuggerHidden] + public static IFinalizedStateMachineBuilder AddFinalizer(this IFinalizedStateMachineBuilder builder, Action stateMachineAction) + => builder.AddFinalizer(stateMachineAction .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) .ToAsync() ); diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/FinalizedStateMachineBuilderEventsSyncPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/FinalizedStateMachineBuilderEventsSyncPayloadExtensions.cs deleted file mode 100644 index 4fad60a1..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/FinalizedStateMachineBuilderEventsSyncPayloadExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Stateflows.Common; -using Stateflows.StateMachines.Context.Interfaces; -using Stateflows.StateMachines.Registration.Builders; -using Stateflows.StateMachines.Registration.Extensions; - -namespace Stateflows.StateMachines.Sync.Data -{ - public static class FinalizedStateMachineBuilderEventsSyncPayloadExtensions - { - public static IFinalizedStateMachineBuilder AddOnInitialize(this IFinalizedStateMachineBuilder builder, Func>, bool> stateMachineAction) - => builder.AddOnInitialize(stateMachineAction - .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) - .ToAsync() - ); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/InitializedStateMachineBuilderEventsSyncExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/InitializedStateMachineBuilderEventsSyncExtensions.cs index 00e3ea0f..ffa4c7ca 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/InitializedStateMachineBuilderEventsSyncExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/InitializedStateMachineBuilderEventsSyncExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Stateflows.Common; using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Registration.Builders; @@ -8,21 +9,24 @@ namespace Stateflows.StateMachines.Sync { public static class InitializedStateMachineBuilderEventsSyncExtensions { - public static IInitializedStateMachineBuilder AddOnInitialize(this IInitializedStateMachineBuilder builder, Func stateMachineAction) - => builder.AddOnInitialize(stateMachineAction + [DebuggerHidden] + public static IInitializedStateMachineBuilder AddDefaultInitializer(this IInitializedStateMachineBuilder builder, Func stateMachineAction) + => builder.AddDefaultInitializer(stateMachineAction .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) .ToAsync() ); - public static IInitializedStateMachineBuilder AddOnInitialize(this IInitializedStateMachineBuilder builder, Func, bool> stateMachineAction) - where TInitializationRequest : InitializationRequest, new() - => builder.AddOnInitialize(stateMachineAction + [DebuggerHidden] + public static IInitializedStateMachineBuilder AddInitializer(this IInitializedStateMachineBuilder builder, Func, bool> stateMachineAction) + where TInitializationEvent : Event, new() + => builder.AddInitializer(stateMachineAction .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) .ToAsync() ); - public static IInitializedStateMachineBuilder AddOnFinalize(this IInitializedStateMachineBuilder builder, Action stateMachineAction) - => builder.AddOnFinalize(stateMachineAction + [DebuggerHidden] + public static IInitializedStateMachineBuilder AddFinalizer(this IInitializedStateMachineBuilder builder, Action stateMachineAction) + => builder.AddFinalizer(stateMachineAction .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) .ToAsync() ); diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/InitializedStateMachineBuilderEventsSyncPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/InitializedStateMachineBuilderEventsSyncPayloadExtensions.cs deleted file mode 100644 index 859216b2..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/InitializedStateMachineBuilderEventsSyncPayloadExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Stateflows.Common; -using Stateflows.StateMachines.Context.Interfaces; -using Stateflows.StateMachines.Registration.Builders; -using Stateflows.StateMachines.Registration.Extensions; - -namespace Stateflows.StateMachines.Sync.Data -{ - public static class InitializedStateMachineBuilderEventsSyncPayloadExtensions - { - public static IInitializedStateMachineBuilder AddOnInitialize(this IInitializedStateMachineBuilder builder, Func>, bool> stateMachineAction) - => builder.AddOnInitialize(stateMachineAction - .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) - .ToAsync() - ); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsPayloadExtensions.cs deleted file mode 100644 index c23b8536..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Threading.Tasks; -using Stateflows.Common; -using Stateflows.StateMachines.Context.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class StateMachineBuilderEventsPayloadExtensions - { - public static IStateMachineBuilder AddOnInitialize(this IStateMachineBuilder builder, Func>, Task> actionAsync) - => builder.AddOnInitialize(actionAsync); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsSyncExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsSyncExtensions.cs index a663eeb0..c65ac18d 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsSyncExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsSyncExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Stateflows.Common; using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Registration.Builders; @@ -8,21 +9,24 @@ namespace Stateflows.StateMachines.Sync { public static class StateMachineBuilderEventsSyncExtensions { - public static IStateMachineBuilder AddOnInitialize(this IStateMachineBuilder builder, Func stateMachineAction) - => builder.AddOnInitialize(stateMachineAction + [DebuggerHidden] + public static IStateMachineBuilder AddDefaultInitializer(this IStateMachineBuilder builder, Func stateMachineAction) + => builder.AddDefaultInitializer(stateMachineAction .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) .ToAsync() ); - public static IStateMachineBuilder AddOnInitialize(this IStateMachineBuilder builder, Func, bool> stateMachineAction) - where TInitializationRequest : InitializationRequest, new() - => builder.AddOnInitialize(stateMachineAction + [DebuggerHidden] + public static IStateMachineBuilder AddInitializer(this IStateMachineBuilder builder, Func, bool> stateMachineAction) + where TInitializationEvent : Event, new() + => builder.AddInitializer(stateMachineAction .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) .ToAsync() ); - public static IStateMachineBuilder AddOnFinalize(this IStateMachineBuilder builder, Action stateMachineAction) - => builder.AddOnFinalize(stateMachineAction + [DebuggerHidden] + public static IStateMachineBuilder AddFinalizer(this IStateMachineBuilder builder, Action stateMachineAction) + => builder.AddFinalizer(stateMachineAction .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) .ToAsync() ); diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsSyncPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsSyncPayloadExtensions.cs deleted file mode 100644 index f3abf32e..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsSyncPayloadExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Stateflows.Common; -using Stateflows.StateMachines.Context.Interfaces; -using Stateflows.StateMachines.Registration.Builders; -using Stateflows.StateMachines.Registration.Extensions; - -namespace Stateflows.StateMachines.Sync.Data -{ - public static class StateMachineBuilderEventsSyncPayloadExtensions - { - public static IStateMachineBuilder AddOnInitialize(this IStateMachineBuilder builder, Func>, bool> stateMachineAction) - => builder.AddOnInitialize(stateMachineAction - .AddStateMachineInvocationContext((builder as StateMachineBuilder).Result) - .ToAsync() - ); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsTypedExtensions.cs new file mode 100644 index 00000000..59976435 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/Events/StateMachineBuilderEventsTypedExtensions.cs @@ -0,0 +1,40 @@ +using Stateflows.Common; +using System.Diagnostics; +using Stateflows.StateMachines.Extensions; +using Stateflows.StateMachines.Context.Classes; +using Stateflows.StateMachines.Registration.Interfaces.Internal; +using Stateflows.Common.Extensions; + +namespace Stateflows.StateMachines.Typed +{ + public static class StateMachineBuilderEventsTypedExtensions + { + [DebuggerHidden] + public static IStateMachineBuilder AddDefaultInitializer(this IStateMachineBuilder builder) + where TInitializer : class, IDefaultInitializer + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddDefaultInitializer(c => (c as BaseContext).Context.Executor.GetDefaultInitializer(c)?.OnInitializeAsync()); + } + + [DebuggerHidden] + public static IStateMachineBuilder AddInitializer(this IStateMachineBuilder builder) + where TInitializationEvent : Event, new() + where TInitializer : class, IInitializer + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddInitializer(c => (c as BaseContext).Context.Executor.GetInitializer(c)?.OnInitializeAsync(c.InitializationEvent)); + } + + [DebuggerHidden] + public static IStateMachineBuilder AddFinalizer(this IStateMachineBuilder builder) + where TFinalizer : class, IFinalizer + { + (builder as IInternal).Services.AddServiceType(); + + return builder.AddFinalizer(c => (c as BaseContext).Context.Executor.GetFinalizer(c)?.OnFinalizeAsync()); + } + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/StateMachine/InitializedStateMachineBuilderTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/StateMachine/InitializedStateMachineBuilderTypedExtensions.cs index 588b661a..6126db60 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/StateMachine/InitializedStateMachineBuilderTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/StateMachine/InitializedStateMachineBuilderTypedExtensions.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Internal; @@ -10,21 +11,21 @@ public static class InitializedStateMachineBuilderTypedExtensions #region AddFinalState [DebuggerHidden] public static IFinalizedStateMachineBuilder AddState(this IInitializedStateMachineBuilder builder, string stateName = FinalState.Name) - where TFinalState : FinalState + where TFinalState : class, IFinalState => builder.AddFinalState(stateName); #endregion #region AddState [DebuggerHidden] public static IInitializedStateMachineBuilder AddState(this IInitializedStateMachineBuilder builder, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - => builder.AddState(StateInfo.Name, stateBuildAction); + where TState : class, IBaseState + => builder.AddState(State.Name, stateBuildAction); [DebuggerHidden] public static IInitializedStateMachineBuilder AddState(this IInitializedStateMachineBuilder builder, string stateName, StateTransitionsBuildAction stateBuildAction = null) - where TState : State + where TState : class, IBaseState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddState( stateName, @@ -41,14 +42,14 @@ public static IInitializedStateMachineBuilder AddState(this IInitialized #region AddCompositeState [DebuggerHidden] public static IInitializedStateMachineBuilder AddCompositeState(this IInitializedStateMachineBuilder builder, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TCompositeState : CompositeState - => builder.AddCompositeState(StateInfo.Name, compositeStateBuildAction); + where TCompositeState : class, IBaseCompositeState + => builder.AddCompositeState(State.Name, compositeStateBuildAction); [DebuggerHidden] public static IInitializedStateMachineBuilder AddCompositeState(this IInitializedStateMachineBuilder builder, string stateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TCompositeState : CompositeState + where TCompositeState : class, IBaseCompositeState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddCompositeState( stateName, diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/StateMachine/StateMachineBuilderTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/StateMachine/StateMachineBuilderTypedExtensions.cs index 9f81dfa2..b9f11261 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/StateMachine/StateMachineBuilderTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/StateMachineBuilder/StateMachine/StateMachineBuilderTypedExtensions.cs @@ -1,4 +1,6 @@ -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common.Extensions; +using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Internal; @@ -7,14 +9,16 @@ namespace Stateflows.StateMachines.Typed public static class StateMachineBuilderTypedExtensions { #region AddInitialState + [DebuggerHidden] public static IInitializedStateMachineBuilder AddInitialState(this IStateMachineBuilder builder, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - => builder.AddInitialState(StateInfo.Name, stateBuildAction); + where TState : class, IBaseState + => builder.AddInitialState(State.Name, stateBuildAction); + [DebuggerHidden] public static IInitializedStateMachineBuilder AddInitialState(this IStateMachineBuilder builder, string stateName, StateTransitionsBuildAction stateBuildAction = null) - where TState : State + where TState : class, IBaseState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddInitialState( stateName, @@ -29,20 +33,23 @@ public static IInitializedStateMachineBuilder AddInitialState(this IStat #endregion #region AddInitialCompositeState + [DebuggerHidden] public static IInitializedStateMachineBuilder AddInitialCompositeState(this IStateMachineBuilder builder, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TState : State - => builder.AddInitialCompositeState(StateInfo.Name, compositeStateBuildAction); + where TState : class, IBaseCompositeState + => builder.AddInitialCompositeState(State.Name, compositeStateBuildAction); + [DebuggerHidden] public static IInitializedStateMachineBuilder AddInitialCompositeState(this IStateMachineBuilder builder, string stateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TState : State + where TState : class, IBaseCompositeState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddInitialCompositeState( stateName, b => { (b as IInitializedCompositeStateBuilder).AddStateEvents(); + (b as IInitializedCompositeStateBuilder).AddCompositeStateEvents(); compositeStateBuildAction?.Invoke(b as ITypedCompositeStateBuilder); } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TransitionBuilder/TransitionBuilderSyncExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TransitionBuilder/TransitionBuilderSyncExtensions.cs index 4136376f..c1b176fe 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TransitionBuilder/TransitionBuilderSyncExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TransitionBuilder/TransitionBuilderSyncExtensions.cs @@ -1,7 +1,5 @@ using System; using System.Diagnostics; -using Stateflows.Activities.Extensions; -using System.Threading.Tasks; using Stateflows.Common; using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Events; @@ -22,26 +20,32 @@ public static ITransitionBuilder AddGuard(this ITransitionBuilde ); [DebuggerHidden] - public static ITransitionBuilder AddEffect(this ITransitionBuilder builder, Action> effect) + public static IInternalTransitionBuilder AddGuard(this IInternalTransitionBuilder builder, Func, bool> guard) where TEvent : Event, new() - => builder.AddEffect(effect + => builder.AddGuard(guard .AddStateMachineInvocationContext((builder as TransitionBuilder).Edge.Graph) .ToAsync() ); [DebuggerHidden] - public static IElseTransitionBuilder AddEffect(this IElseTransitionBuilder builder, Action> effect) + public static IDefaultTransitionBuilder AddGuard(this IDefaultTransitionBuilder builder, Func, bool> guard) + => builder.AddGuard(guard + .AddStateMachineInvocationContext((builder as TransitionBuilder).Edge.Graph) + .ToAsync() + ); + + [DebuggerHidden] + public static ITransitionBuilder AddEffect(this ITransitionBuilder builder, Action> effect) where TEvent : Event, new() => builder.AddEffect(effect .AddStateMachineInvocationContext((builder as TransitionBuilder).Edge.Graph) .ToAsync() ); - [DebuggerHidden] - public static IInternalTransitionBuilder AddGuard(this IInternalTransitionBuilder builder, Func, bool> guard) + public static IElseTransitionBuilder AddEffect(this IElseTransitionBuilder builder, Action> effect) where TEvent : Event, new() - => builder.AddGuard(guard + => builder.AddEffect(effect .AddStateMachineInvocationContext((builder as TransitionBuilder).Edge.Graph) .ToAsync() ); @@ -62,14 +66,6 @@ public static IElseInternalTransitionBuilder AddEffect(this IEls .ToAsync() ); - - [DebuggerHidden] - public static IDefaultTransitionBuilder AddGuard(this IDefaultTransitionBuilder builder, Func, bool> guard) - => builder.AddGuard(guard - .AddStateMachineInvocationContext((builder as TransitionBuilder).Edge.Graph) - .ToAsync() - ); - [DebuggerHidden] public static IDefaultTransitionBuilder AddEffect(this IDefaultTransitionBuilder builder, Action> effect) => builder.AddEffect(effect diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs index 5c239ee1..32b5fcd9 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs @@ -1,21 +1,25 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; +using Stateflows.StateMachines.Events; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class TypedCompositeStateBuilderElseDefaultTransitionTypedExtensions { + [DebuggerHidden] public static ITypedCompositeStateBuilder AddElseDefaultTransition(this ITypedCompositeStateBuilder builder) - where TElseTransition : ElseTransition - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name); + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); - public static ITypedCompositeStateBuilder AddElseDefaultTransition(this ITypedCompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition - => builder.AddElseTransition(targetVertexName); + [DebuggerHidden] + public static ITypedCompositeStateBuilder AddElseDefaultTransition(this ITypedCompositeStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + => (builder as IStateBuilder).AddElseDefaultTransition(targetStateName) as ITypedCompositeStateBuilder; + [DebuggerHidden] public static ITypedCompositeStateBuilder AddElseDefaultTransition(this ITypedCompositeStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs index 36a71b6c..50cb4cf1 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,10 @@ namespace Stateflows.StateMachines.Typed { public static class TypedCompositeStateBuilderElseInternalTransitionTypedExtensions { + [DebuggerHidden] public static ITypedCompositeStateBuilder AddElseInternalTransition(this ITypedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition + where TElseTransition : class, ITransitionEffect => builder.AddElseTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 91b8bf1e..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedCompositeStateInitialBuilderElseInternalTransitionTypedPayloadExtensions - { - public static ITypedCompositeStateBuilder AddElseInternalDataTransition(this ITypedCompositeStateBuilder builder) - where TElseTransition : ElseTransition> - => builder.AddElseTransition, TElseTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElsePayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElsePayloadExtensions.cs deleted file mode 100644 index 9dbd7ca9..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElsePayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class TypedCompositeStateBuilderElsePayloadExtensions - { - public static ITypedCompositeStateBuilder AddElseDataTransition(this ITypedCompositeStateBuilder builder, string targetVertexName, ElseTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseTransition>(targetVertexName, transitionBuildAction); - - public static ITypedCompositeStateBuilder AddElseInternalDataTransition(this ITypedCompositeStateBuilder builder, ElseInternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseTransitionTypedExtensions.cs index 4a392255..9b136c02 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedCompositeStateBuilderElseTransitionTypedExtensions.cs @@ -1,33 +1,28 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class TypedCompositeStateBuilderElseTransitionTypedExtensions { + [DebuggerHidden] public static ITypedCompositeStateBuilder AddElseTransition(this ITypedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition - where TTargetState : BaseState - => AddElseTransition(builder, StateInfo.Name); + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); - public static ITypedCompositeStateBuilder AddElseTransition(this ITypedCompositeStateBuilder builder, string targetVertexName) + [DebuggerHidden] + public static ITypedCompositeStateBuilder AddElseTransition(this ITypedCompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TElseTransition : ElseTransition - { - (builder as IInternal).Services.RegisterElseTransition(); - - return builder.AddElseTransition( - targetVertexName, - t => t.AddElseTransitionEvents() - ); - } + where TElseTransition : class, ITransitionEffect + => (builder as IStateBuilder).AddElseTransition(targetStateName) as ITypedCompositeStateBuilder; + [DebuggerHidden] public static ITypedCompositeStateBuilder AddElseTransition(this ITypedCompositeStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs index c009850e..28beecc2 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs @@ -1,21 +1,25 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; +using Stateflows.StateMachines.Events; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class TypedFinalizedCompositeStateBuilderElseDefaultTransitionTypedExtensions { + [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddElseDefaultTransition(this ITypedFinalizedCompositeStateBuilder builder) - where TElseTransition : ElseTransition - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name); + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); - public static ITypedFinalizedCompositeStateBuilder AddElseDefaultTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition - => builder.AddElseTransition(targetVertexName); + [DebuggerHidden] + public static ITypedFinalizedCompositeStateBuilder AddElseDefaultTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + => (builder as IStateBuilder).AddElseDefaultTransition(targetStateName) as ITypedFinalizedCompositeStateBuilder; + [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddElseDefaultTransition(this ITypedFinalizedCompositeStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs index 17cc60be..6232f123 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,10 @@ namespace Stateflows.StateMachines.Typed { public static class TypedFinalizedCompositeStateBuilderElseInternalTransitionTypedExtensions { + [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddElseInternalTransition(this ITypedFinalizedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition + where TElseTransition : class, ITransitionEffect => builder.AddElseTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index ab65aa24..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedFinalizedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions - { - public static ITypedFinalizedCompositeStateBuilder AddElseInternalDataTransition(this ITypedFinalizedCompositeStateBuilder builder) - where TElseTransition : ElseTransition> - => builder.AddElseTransition, TElseTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElsePayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElsePayloadExtensions.cs deleted file mode 100644 index 730e69dd..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElsePayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class TypedFinalizedCompositeStateBuilderElsePayloadExtensions - { - public static ITypedFinalizedCompositeStateBuilder AddElseDataTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetVertexName, ElseTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseTransition>(targetVertexName, transitionBuildAction); - - public static ITypedFinalizedCompositeStateBuilder AddElseInternalDataTransition(this ITypedFinalizedCompositeStateBuilder builder, ElseInternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseTransitionTypedExtensions.cs index 47b63cf8..a2918ed1 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseTransitionTypedExtensions.cs @@ -1,33 +1,28 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class TypedFinalizedCompositeStateBuilderElseTransitionTypedExtensions { + [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddElseTransition(this ITypedFinalizedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition - where TTargetState : BaseState - => AddElseTransition(builder, StateInfo.Name); + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); - public static ITypedFinalizedCompositeStateBuilder AddElseTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetVertexName) + [DebuggerHidden] + public static ITypedFinalizedCompositeStateBuilder AddElseTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TElseTransition : ElseTransition - { - (builder as IInternal).Services.RegisterElseTransition(); - - return builder.AddElseTransition( - targetVertexName, - t => t.AddElseTransitionEvents() - ); - } + where TElseTransition : class, ITransitionEffect + => (builder as IStateBuilder).AddElseTransition(targetStateName) as ITypedFinalizedCompositeStateBuilder; + [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddElseTransition(this ITypedFinalizedCompositeStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 94f1965f..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedFinalizedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedFinalizedCompositeStateBuilderElseTransitionTypedPayloadExtensions - { - public static ITypedFinalizedCompositeStateBuilder AddElseDataTransition(this ITypedFinalizedCompositeStateBuilder builder) - where TElseTransition : ElseTransition> - where TTargetState : BaseState - => AddElseDataTransition(builder, StateInfo.Name); - - public static ITypedFinalizedCompositeStateBuilder AddElseDataTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition> - { - (builder as IInternal).Services.RegisterElseTransition>(); - - return builder.AddElseTransition>( - targetVertexName, - t => t.AddElseTransitionEvents>() - ); - } - - public static ITypedFinalizedCompositeStateBuilder AddElseDataTransition(this ITypedFinalizedCompositeStateBuilder builder, ElseTransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs index 6937d095..45ceca10 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions.cs @@ -1,21 +1,25 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; +using Stateflows.StateMachines.Events; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class TypedInitializedCompositeStateBuilderElseDefaultTransitionTypedExtensions { + [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddElseDefaultTransition(this ITypedInitializedCompositeStateBuilder builder) - where TElseTransition : ElseTransition - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name); + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); - public static ITypedInitializedCompositeStateBuilder AddElseDefaultTransition(this ITypedInitializedCompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition - => builder.AddElseTransition(targetVertexName); + [DebuggerHidden] + public static ITypedInitializedCompositeStateBuilder AddElseDefaultTransition(this ITypedInitializedCompositeStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + => (builder as IStateBuilder).AddElseDefaultTransition(targetStateName) as ITypedInitializedCompositeStateBuilder; + [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddElseDefaultTransition(this ITypedInitializedCompositeStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs index 35a6a033..b143878f 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,10 @@ namespace Stateflows.StateMachines.Typed { public static class TypedInitializedCompositeStateBuilderElseInternalTransitionTypedExtensions { + [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddElseInternalTransition(this ITypedInitializedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition + where TElseTransition : class, ITransitionEffect => builder.AddElseTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 790e0d92..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedInitializedCompositeStateBuilderElseInternalTransitionTypedPayloadExtensions - { - public static ITypedInitializedCompositeStateBuilder AddElseInternalDataTransition(this ITypedInitializedCompositeStateBuilder builder) - where TElseTransition : ElseTransition> - => builder.AddElseTransition, TElseTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElsePayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElsePayloadExtensions.cs deleted file mode 100644 index 2c313d41..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElsePayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class TypedInitializedCompositeStateBuilderElsePayloadExtensions - { - public static ITypedInitializedCompositeStateBuilder AddElseDataTransition(this ITypedInitializedCompositeStateBuilder builder, string targetVertexName, ElseTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseTransition>(targetVertexName, transitionBuildAction); - - public static ITypedInitializedCompositeStateBuilder AddElseInternalDataTransition(this ITypedInitializedCompositeStateBuilder builder, ElseInternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseTransitionTypedExtensions.cs index 878e6650..725b3a28 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseTransitionTypedExtensions.cs @@ -1,33 +1,28 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class TypedInitializedCompositeStateBuilderElseTransitionTypedExtensions { + [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddElseTransition(this ITypedInitializedCompositeStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition - where TTargetState : BaseState - => AddElseTransition(builder, StateInfo.Name); + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); - public static ITypedInitializedCompositeStateBuilder AddElseTransition(this ITypedInitializedCompositeStateBuilder builder, string targetVertexName) + [DebuggerHidden] + public static ITypedInitializedCompositeStateBuilder AddElseTransition(this ITypedInitializedCompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TElseTransition : ElseTransition - { - (builder as IInternal).Services.RegisterElseTransition(); - - return builder.AddElseTransition( - targetVertexName, - t => t.AddElseTransitionEvents() - ); - } + where TElseTransition : class, ITransitionEffect + => (builder as IStateBuilder).AddElseTransition(targetStateName) as ITypedInitializedCompositeStateBuilder; + [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddElseTransition(this ITypedInitializedCompositeStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs deleted file mode 100644 index ecf7ad22..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/ElseTransitions/TypedInitializedCompositeStateBuilderElseTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Diagnostics; -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedInitializedCompositeStateBuilderElseTransitionTypedPayloadExtensions - { - public static ITypedInitializedCompositeStateBuilder AddElseDataTransition(this ITypedInitializedCompositeStateBuilder builder) - where TElseTransition : ElseTransition> - where TTargetState : BaseState - => AddElseDataTransition(builder, StateInfo.Name); - - [DebuggerHidden] - public static ITypedInitializedCompositeStateBuilder AddElseDataTransition(this ITypedInitializedCompositeStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition> - { - (builder as IInternal).Services.RegisterElseTransition>(); - - return builder.AddElseTransition>( - targetVertexName, - t => t.AddElseTransitionEvents>() - ); - } - - public static ITypedInitializedCompositeStateBuilder AddElseDataTransition(this ITypedInitializedCompositeStateBuilder builder, ElseTransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/StateMachine/TypedCompositeStateBuilderTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/StateMachine/TypedCompositeStateBuilderTypedExtensions.cs index ba65c4c1..f1025399 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/StateMachine/TypedCompositeStateBuilderTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/StateMachine/TypedCompositeStateBuilderTypedExtensions.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Internal; @@ -10,14 +11,14 @@ public static class TypedCompositeStateBuilderTypedExtensions #region AddInitialState [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddInitialState(this ITypedCompositeStateBuilder builder, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - => builder.AddInitialState(StateInfo.Name, stateBuildAction); + where TState : class, IBaseState + => builder.AddInitialState(State.Name, stateBuildAction); [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddInitialState(this ITypedCompositeStateBuilder builder, string stateName, StateTransitionsBuildAction stateBuildAction = null) - where TState : State + where TState : class, IBaseState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddInitialState( stateName, @@ -34,14 +35,14 @@ public static ITypedInitializedCompositeStateBuilder AddInitialState(thi #region AddInitialCompositeState [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddInitialCompositeState(this ITypedCompositeStateBuilder builder, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TState : State - => builder.AddInitialCompositeState(StateInfo.Name, compositeStateBuildAction); + where TState : class, IBaseState + => builder.AddInitialCompositeState(State.Name, compositeStateBuildAction); [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddInitialCompositeState(this ITypedCompositeStateBuilder builder, string stateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TState : State + where TState : class, IBaseState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddInitialCompositeState( stateName, diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/StateMachine/TypedInitializedCompositeStateBuilderTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/StateMachine/TypedInitializedCompositeStateBuilderTypedExtensions.cs index 83ce62db..19855517 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/StateMachine/TypedInitializedCompositeStateBuilderTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/StateMachine/TypedInitializedCompositeStateBuilderTypedExtensions.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using Stateflows.Common.Extensions; using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; using Stateflows.StateMachines.Registration.Interfaces.Internal; @@ -10,21 +11,21 @@ public static class TypedInitializedCompositeStateBuilderTypedExtensions #region AddFinalState [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddState(this ITypedInitializedCompositeStateBuilder builder, string stateName = FinalState.Name) - where TFinalState : FinalState + where TFinalState : class, IFinalState => builder.AddFinalState(stateName); #endregion #region AddState [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddState(this ITypedInitializedCompositeStateBuilder builder, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - => builder.AddState(StateInfo.Name, stateBuildAction); + where TState : class, IBaseState + => builder.AddState(State.Name, stateBuildAction); [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddState(this ITypedInitializedCompositeStateBuilder builder, string stateName, StateTransitionsBuildAction stateBuildAction = null) - where TState : State + where TState : class, IBaseState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddState( stateName, @@ -41,14 +42,14 @@ public static ITypedInitializedCompositeStateBuilder AddState(this IType #region AddCompositeState [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddCompositeState(this ITypedInitializedCompositeStateBuilder builder, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TCompositeState : CompositeState - => builder.AddCompositeState(StateInfo.Name, compositeStateBuildAction); + where TCompositeState : class, IBaseCompositeState + => builder.AddCompositeState(State.Name, compositeStateBuildAction); [DebuggerHidden] public static ITypedInitializedCompositeStateBuilder AddCompositeState(this ITypedInitializedCompositeStateBuilder builder, string stateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TCompositeState : CompositeState + where TCompositeState : class, IBaseCompositeState { - (builder as IInternal).Services.RegisterState(); + (builder as IInternal).Services.AddServiceType(); return builder.AddCompositeState( stateName, diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderDefaultTransitionTypedExtensions.cs index 24497502..f84fdcf5 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderDefaultTransitionTypedExtensions.cs @@ -1,21 +1,100 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class TypedCompositeStateBuilderDefaultTransitionTypedExtensions { - public static ITypedInitializedCompositeStateBuilder AddDefaultTransition(this ITypedInitializedCompositeStateBuilder builder) - where TTransition : Transition - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static ITypedCompositeStateBuilder AddDefaultTransition(this ITypedCompositeStateBuilder builder) + where TDefaultTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); - public static ITypedInitializedCompositeStateBuilder AddDefaultTransition(this ITypedInitializedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition - => builder.AddTransition(targetVertexName); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ITypedCompositeStateBuilder AddDefaultTransition(this ITypedCompositeStateBuilder builder, string targetStateName) + where TDefaultTransition : class, IBaseDefaultTransition + => (builder as IStateBuilder).AddDefaultTransition(targetStateName) as ITypedCompositeStateBuilder; - public static ITypedInitializedCompositeStateBuilder AddDefaultTransition(this ITypedInitializedCompositeStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name, transitionBuildAction); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static ITypedCompositeStateBuilder AddDefaultTransition(this ITypedCompositeStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderInternalTransitionTypedExtensions.cs index c7e5a7c7..3ba34657 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,31 @@ namespace Stateflows.StateMachines.Typed { public static class TypedCompositeStateBuilderInternalTransitionTypedExtensions { - public static ITypedInitializedCompositeStateBuilder AddInternalTransition(this ITypedInitializedCompositeStateBuilder builder) + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] + public static ITypedCompositeStateBuilder AddInternalTransition(this ITypedCompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition + where TTransition : class, IBaseTransition => builder.AddTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index b69b257b..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedCompositeStateBuilderInternalTransitionTypedPayloadExtensions - { - public static ITypedCompositeStateBuilder AddInternalDataTransition(this ITypedCompositeStateBuilder builder) - where TTransition : Transition> - => builder.AddTransition, TTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderPayloadExtensions.cs deleted file mode 100644 index 1eaeffd5..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderPayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class TypedCompositeStateBuilderPayloadExtensions - { - public static ITypedCompositeStateBuilder AddDataTransition(this ITypedCompositeStateBuilder builder, string targetVertexName, TransitionBuildAction> transitionBuildAction = null) - => builder.AddTransition>(targetVertexName, transitionBuildAction); - - public static ITypedCompositeStateBuilder AddInternalDataTransition(this ITypedCompositeStateBuilder builder, InternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderTransitionTypedExtensions.cs index ebd9b805..9b1ddb1c 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderTransitionTypedExtensions.cs @@ -1,33 +1,119 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class TypedCompositeStateBuilderTransitionTypedExtensions { - public static ITypedInitializedCompositeStateBuilder AddTransition(this ITypedInitializedCompositeStateBuilder builder) + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static ITypedCompositeStateBuilder AddTransition(this ITypedCompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition - where TTargetState : BaseState - => AddTransition(builder, StateInfo.Name); + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); - public static ITypedInitializedCompositeStateBuilder AddTransition(this ITypedInitializedCompositeStateBuilder builder, string targetVertexName) + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ITypedCompositeStateBuilder AddTransition(this ITypedCompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TTransition : Transition - { - (builder as IInternal).Services.RegisterTransition(); + where TTransition : class, IBaseTransition + => (builder as IStateBuilder).AddTransition(targetStateName) as ITypedCompositeStateBuilder; - return builder.AddTransition( - targetVertexName, - t => t.AddTransitionEvents() - ); - } - - public static ITypedInitializedCompositeStateBuilder AddTransition(this ITypedInitializedCompositeStateBuilder builder, TransitionBuildAction transitionBuildAction = null) + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static ITypedCompositeStateBuilder AddTransition(this ITypedCompositeStateBuilder builder, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 4d13322f..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateBuilderTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedCompositeStateBuilderTransitionTypedPayloadExtensions - { - public static ITypedCompositeStateBuilder AddDataTransition(this ITypedCompositeStateBuilder builder) - where TTransition : Transition> - where TTargetState : BaseState - => AddDataTransition(builder, StateInfo.Name); - - public static ITypedCompositeStateBuilder AddDataTransition(this ITypedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition> - { - (builder as IInternal).Services.RegisterTransition>(); - - return builder.AddTransition>( - targetVertexName, - t => t.AddTransitionEvents>() - ); - } - - public static ITypedCompositeStateBuilder AddDataTransition(this ITypedCompositeStateBuilder builder, TransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateInitialBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateInitialBuilderDefaultTransitionTypedExtensions.cs deleted file mode 100644 index 90df138b..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateInitialBuilderDefaultTransitionTypedExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Stateflows.StateMachines.Events; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed -{ - public static class TypedCompositeStateInitialBuilderDefaultTransitionTypedExtensions - { - public static ITypedCompositeStateBuilder AddDefaultTransition(this ITypedCompositeStateBuilder builder) - where TTransition : Transition - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name); - - public static ITypedCompositeStateBuilder AddDefaultTransition(this ITypedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition - => builder.AddTransition(targetVertexName); - - public static ITypedCompositeStateBuilder AddDefaultTransition(this ITypedCompositeStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateInitialBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateInitialBuilderInternalTransitionTypedExtensions.cs deleted file mode 100644 index 61a64188..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateInitialBuilderInternalTransitionTypedExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed -{ - public static class TypedCompositeStateInitialBuilderInternalTransitionTypedExtensions - { - public static ITypedCompositeStateBuilder AddInternalTransition(this ITypedCompositeStateBuilder builder) - where TEvent : Event, new() - where TTransition : Transition - => builder.AddTransition(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateInitialBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateInitialBuilderTransitionTypedExtensions.cs deleted file mode 100644 index 8ef0c53d..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedCompositeStateInitialBuilderTransitionTypedExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed -{ - public static class TypedCompositeStateInitialBuilderTransitionTypedExtensions - { - public static ITypedCompositeStateBuilder AddTransition(this ITypedCompositeStateBuilder builder) - where TEvent : Event, new() - where TTransition : Transition - where TTargetState : BaseState - => AddTransition(builder, StateInfo.Name); - - public static ITypedCompositeStateBuilder AddTransition(this ITypedCompositeStateBuilder builder, string targetVertexName) - where TEvent : Event, new() - where TTransition : Transition - { - (builder as IInternal).Services.RegisterTransition(); - - return builder.AddTransition( - targetVertexName, - t => t.AddTransitionEvents() - ); - } - - public static ITypedCompositeStateBuilder AddTransition(this ITypedCompositeStateBuilder builder, TransitionBuildAction transitionBuildAction = null) - where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderDefaultTransitionTypedExtensions.cs index fb708b02..3b6b012c 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderDefaultTransitionTypedExtensions.cs @@ -1,21 +1,100 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class TypedFinalizedCompositeStateBuilderDefaultTransitionTypedExtensions { - public static ITypedFinalizedCompositeStateBuilder AddDefaultTransition(this ITypedFinalizedCompositeStateBuilder builder) - where TTransition : Transition - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static ITypedFinalizedCompositeStateBuilder AddDefaultTransition(this ITypedFinalizedCompositeStateBuilder builder) + where TDefaultTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); - public static ITypedFinalizedCompositeStateBuilder AddDefaultTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition - => builder.AddTransition(targetVertexName); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ITypedFinalizedCompositeStateBuilder AddDefaultTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetStateName) + where TDefaultTransition : class, IBaseDefaultTransition + => (builder as IStateBuilder).AddDefaultTransition(targetStateName) as ITypedFinalizedCompositeStateBuilder; + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddDefaultTransition(this ITypedFinalizedCompositeStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderInternalTransitionTypedExtensions.cs index 6632a548..ef86c0b2 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderInternalTransitionTypedExtensions.cs @@ -1,14 +1,37 @@ using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; +using System.Diagnostics; namespace Stateflows.StateMachines.Typed { public static class TypedFinalizedCompositeStateBuilderInternalTransitionTypedExtensions { + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddInternalTransition(this ITypedFinalizedCompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition + where TTransition : class, IBaseTransition => builder.AddTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 0528ca96..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedFinalizedCompositeStateBuilderInternalTransitionTypedPayloadExtensions - { - public static ITypedFinalizedCompositeStateBuilder AddInternalDataTransition(this ITypedFinalizedCompositeStateBuilder builder) - where TTransition : Transition> - => builder.AddTransition, TTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderPayloadExtensions.cs deleted file mode 100644 index 5d1c59c5..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderPayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class TypedFinalizedCompositeStateBuilderPayloadExtensions - { - public static ITypedFinalizedCompositeStateBuilder AddDataTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetVertexName, TransitionBuildAction> transitionBuildAction = null) - => builder.AddTransition>(targetVertexName, transitionBuildAction); - - public static ITypedFinalizedCompositeStateBuilder AddInternalDataTransition(this ITypedFinalizedCompositeStateBuilder builder, InternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderTransitionTypedExtensions.cs index 9d71a28e..458125a7 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderTransitionTypedExtensions.cs @@ -1,33 +1,119 @@ using Stateflows.Common; -using Stateflows.StateMachines.Extensions; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; +using System.Diagnostics; namespace Stateflows.StateMachines.Typed { public static class TypedFinalizedCompositeStateBuilderTransitionTypedExtensions { + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddTransition(this ITypedFinalizedCompositeStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition - where TTargetState : BaseState - => AddTransition(builder, StateInfo.Name); + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); - public static ITypedFinalizedCompositeStateBuilder AddTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetVertexName) + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ITypedFinalizedCompositeStateBuilder AddTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TTransition : Transition - { - (builder as IInternal).Services.RegisterTransition(); - - return builder.AddTransition( - targetVertexName, - t => t.AddTransitionEvents() - ); - } + where TTransition : class, IBaseTransition + => (builder as IStateBuilder).AddTransition(targetStateName) as ITypedFinalizedCompositeStateBuilder; + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ITypedFinalizedCompositeStateBuilder AddTransition(this ITypedFinalizedCompositeStateBuilder builder, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 69742aad..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedFinalizedCompositeStateBuilderTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedFinalizedCompositeStateBuilderTransitionTypedPayloadExtensions - { - public static ITypedFinalizedCompositeStateBuilder AddDataTransition(this ITypedFinalizedCompositeStateBuilder builder) - where TTransition : Transition> - where TTargetState : BaseState - => AddDataTransition(builder, StateInfo.Name); - - public static ITypedFinalizedCompositeStateBuilder AddDataTransition(this ITypedFinalizedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition> - { - (builder as IInternal).Services.RegisterTransition>(); - - return builder.AddTransition>( - targetVertexName, - t => t.AddTransitionEvents>() - ); - } - - public static ITypedFinalizedCompositeStateBuilder AddDataTransition(this ITypedFinalizedCompositeStateBuilder builder, TransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderDefaultTransitionTypedExtensions.cs new file mode 100644 index 00000000..56c511a7 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderDefaultTransitionTypedExtensions.cs @@ -0,0 +1,100 @@ +using System.Diagnostics; +using Stateflows.StateMachines.Registration.Interfaces; + +namespace Stateflows.StateMachines.Typed +{ + public static class TypedInitializedCompositeStateBuilderDefaultTransitionTypedExtensions + { + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static ITypedInitializedCompositeStateBuilder AddDefaultTransition(this ITypedInitializedCompositeStateBuilder builder) + where TDefaultTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); + + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ITypedInitializedCompositeStateBuilder AddDefaultTransition(this ITypedInitializedCompositeStateBuilder builder, string targetStateName) + where TDefaultTransition : class, IBaseDefaultTransition + => (builder as IStateBuilder).AddDefaultTransition(targetStateName) as ITypedInitializedCompositeStateBuilder; + + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static ITypedInitializedCompositeStateBuilder AddDefaultTransition(this ITypedInitializedCompositeStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderInternalTransitionTypedExtensions.cs new file mode 100644 index 00000000..ff979b02 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderInternalTransitionTypedExtensions.cs @@ -0,0 +1,37 @@ +using Stateflows.Common; +using Stateflows.StateMachines.Registration; +using Stateflows.StateMachines.Registration.Interfaces; +using System.Diagnostics; + +namespace Stateflows.StateMachines.Typed +{ + public static class TypedInitializedCompositeStateBuilderInternalTransitionTypedExtensions + { + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] + public static ITypedInitializedCompositeStateBuilder AddInternalTransition(this ITypedInitializedCompositeStateBuilder builder) + where TEvent : Event, new() + where TTransition : class, IBaseTransition + => builder.AddTransition(Constants.DefaultTransitionTarget); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 8d62e749..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedInitializedCompositeStateBuilderInternalTransitionTypedPayloadExtensions - { - public static ITypedInitializedCompositeStateBuilder AddInternalDataTransition(this ITypedInitializedCompositeStateBuilder builder) - where TTransition : Transition> - => builder.AddTransition, TTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderPayloadExtensions.cs deleted file mode 100644 index c52d7641..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderPayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class TypedInitializedCompositeStateBuilderPayloadExtensions - { - public static ITypedInitializedCompositeStateBuilder AddDataTransition(this ITypedInitializedCompositeStateBuilder builder, string targetVertexName, TransitionBuildAction> transitionBuildAction = null) - => builder.AddTransition>(targetVertexName, transitionBuildAction); - - public static ITypedInitializedCompositeStateBuilder AddInternalDataTransition(this ITypedInitializedCompositeStateBuilder builder, InternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderTransitionTypedExtensions.cs new file mode 100644 index 00000000..4f2c4f97 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderTransitionTypedExtensions.cs @@ -0,0 +1,119 @@ +using System.Diagnostics; +using Stateflows.Common; +using Stateflows.StateMachines.Registration.Interfaces; + +namespace Stateflows.StateMachines.Typed +{ + public static class TypedInitializedCompositeStateBuilderTransitionTypedExtensions + { + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] + public static ITypedInitializedCompositeStateBuilder AddTransition(this ITypedInitializedCompositeStateBuilder builder) + where TEvent : Event, new() + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); + + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ITypedInitializedCompositeStateBuilder AddTransition(this ITypedInitializedCompositeStateBuilder builder, string targetStateName) + where TEvent : Event, new() + where TTransition : class, IBaseTransition + => (builder as IStateBuilder).AddTransition(targetStateName) as ITypedInitializedCompositeStateBuilder; + + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] + public static ITypedInitializedCompositeStateBuilder AddTransition(this ITypedInitializedCompositeStateBuilder builder, TransitionBuildAction transitionBuildAction = null) + where TEvent : Event, new() + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderTransitionTypedPayloadExtensions.cs deleted file mode 100644 index b49f685a..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedCompositeStateBuilder/Transitions/TypedInitializedCompositeStateBuilderTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Diagnostics; -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedInitializedCompositeStateBuilderTransitionTypedPayloadExtensions - { - public static ITypedInitializedCompositeStateBuilder AddDataTransition(this ITypedInitializedCompositeStateBuilder builder) - where TTransition : Transition> - where TTargetState : BaseState - => AddDataTransition(builder, StateInfo.Name); - - [DebuggerHidden] - public static ITypedInitializedCompositeStateBuilder AddDataTransition(this ITypedInitializedCompositeStateBuilder builder, string targetVertexName) - where TTransition : Transition> - { - (builder as IInternal).Services.RegisterTransition>(); - - return builder.AddTransition>( - targetVertexName, - t => t.AddTransitionEvents>() - ); - } - - public static ITypedInitializedCompositeStateBuilder AddDataTransition(this ITypedInitializedCompositeStateBuilder builder, TransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseDefaultTransitionTypedExtensions.cs index 3be0a607..ef611070 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseDefaultTransitionTypedExtensions.cs @@ -1,21 +1,60 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class TypedStateBuilderElseDefaultTransitionTypedExtensions { + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static ITypedStateBuilder AddElseDefaultTransition(this ITypedStateBuilder builder) - where TElseTransition : ElseTransition - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name); + where TElseTransition : class, IDefaultTransitionEffect + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name); - public static ITypedStateBuilder AddElseDefaultTransition(this ITypedStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition - => builder.AddElseTransition(targetVertexName); + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static ITypedStateBuilder AddElseDefaultTransition(this ITypedStateBuilder builder, string targetStateName) + where TElseTransition : class, IDefaultTransitionEffect + => (builder as IStateBuilder).AddElseDefaultTransition(targetStateName) as ITypedStateBuilder; + /// + /// Adds else alternative for all default transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ITypedStateBuilder AddElseDefaultTransition(this ITypedStateBuilder builder, ElseDefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseInternalTransitionTypedExtensions.cs index ae81bf39..7fe56f53 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,16 @@ namespace Stateflows.StateMachines.Typed { public static class TypedStateBuilderElseInternalTransitionTypedExtensions { + /// + /// Adds internal else alternative for all -triggered transitions coming from current state.

+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + [DebuggerHidden] public static ITypedStateBuilder AddElseInternalTransition(this ITypedStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition + where TElseTransition : class, ITransitionEffect => builder.AddElseTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 21799f03..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedStateBuilderElseInternalTransitionTypedPayloadExtensions - { - public static ITypedStateBuilder AddElseInternalDataTransition(this ITypedStateBuilder builder) - where TElseTransition : ElseTransition> - => builder.AddElseTransition, TElseTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElsePayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElsePayloadExtensions.cs deleted file mode 100644 index 2eb541ad..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElsePayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class TypedStateBuilderElsePayloadExtensions - { - public static ITypedStateBuilder AddElseDataTransition(this ITypedStateBuilder builder, string targetVertexName, ElseTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseTransition>(targetVertexName, transitionBuildAction); - - public static ITypedStateBuilder AddElseInternalDataTransition(this ITypedStateBuilder builder, ElseInternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddElseInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseTransitionTypedExtensions.cs index 3672943b..e19edfad 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseTransitionTypedExtensions.cs @@ -1,33 +1,67 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class TypedStateBuilderElseTransitionTypedExtensions { + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static ITypedStateBuilder AddElseTransition(this ITypedStateBuilder builder) where TEvent : Event, new() - where TElseTransition : ElseTransition - where TTargetState : BaseState - => AddElseTransition(builder, StateInfo.Name); + where TElseTransition : class, ITransitionEffect + where TTargetState : class, IVertex + => AddElseTransition(builder, State.Name); - public static ITypedStateBuilder AddElseTransition(this ITypedStateBuilder builder, string targetVertexName) + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Transition class; must implement interface + /// Target state name + [DebuggerHidden] + public static ITypedStateBuilder AddElseTransition(this ITypedStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TElseTransition : ElseTransition - { - (builder as IInternal).Services.RegisterElseTransition(); - - return builder.AddElseTransition( - targetVertexName, - t => t.AddElseTransitionEvents() - ); - } + where TElseTransition : class, ITransitionEffect + => (builder as IStateBuilder).AddElseTransition(targetStateName) as ITypedStateBuilder; + /// + /// Adds else alternative for all -triggered transitions coming from current state.

+ /// Transitions are triggered by events sent to State Machine and are changing its state. + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ITypedStateBuilder AddElseTransition(this ITypedStateBuilder builder, ElseTransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddElseTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseTransitionTypedPayloadExtensions.cs deleted file mode 100644 index fbd0053a..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/ElseTransitions/TypedStateBuilderElseTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedStateBuilderElseTransitionTypedPayloadExtensions - { - public static ITypedStateBuilder AddElseDataTransition(this ITypedStateBuilder builder) - where TElseTransition : ElseTransition> - where TTargetState : BaseState - => AddElseDataTransition(builder, StateInfo.Name); - - public static ITypedStateBuilder AddElseDataTransition(this ITypedStateBuilder builder, string targetVertexName) - where TElseTransition : ElseTransition> - { - (builder as IInternal).Services.RegisterElseTransition>(); - - return builder.AddElseTransition>( - targetVertexName, - t => t.AddElseTransitionEvents>() - ); - } - - public static ITypedStateBuilder AddElseDataTransition(this ITypedStateBuilder builder, ElseTransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddElseTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Submachine/TypedStateBuilderDoActivityTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Submachine/TypedStateBuilderDoActivityTypedExtensions.cs new file mode 100644 index 00000000..d84edb48 --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Submachine/TypedStateBuilderDoActivityTypedExtensions.cs @@ -0,0 +1,21 @@ +using System.Diagnostics; +using Stateflows.Activities; +using Stateflows.StateMachines.Registration.Interfaces; + +namespace Stateflows.StateMachines.Typed +{ + public static class TypedStateBuilderDoActivityTypedExtensions + { + /// + /// Embeds Activity in current state.

+ /// Embedded Activity will be initialized on state entry and finalized on state exit. Events can be forwarded from State Machine to embedded Activity using + ///
+ /// Activity class; must implement interface + /// Build action + /// Initialization builder; generates initialization event for embedded State Machine + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddDoActivity(this ITypedStateBuilder builder, EmbeddedBehaviorBuildAction buildAction = null, StateActionInitializationBuilderAsync initializationBuilder = null) + where TActivity : class, IActivity + => builder.AddDoActivity(Activity.Name, buildAction, initializationBuilder); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Submachine/TypedStateBuilderSubmachineTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Submachine/TypedStateBuilderSubmachineTypedExtensions.cs index 2b746029..ef8bfba6 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Submachine/TypedStateBuilderSubmachineTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Submachine/TypedStateBuilderSubmachineTypedExtensions.cs @@ -1,11 +1,20 @@ -using Stateflows.StateMachines.Registration.Interfaces; +using System.Diagnostics; +using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class TypedStateBuilderSubmachineTypedExtensions { - public static IBehaviorTypedStateBuilder AddSubmachine(this ITypedStateBuilder builder, EmbeddedBehaviorBuildAction buildAction, StateActionInitializationBuilder initializationBuilder = null) - where TStateMachine : StateMachine - => builder.AddSubmachine(StateMachineInfo.Name, buildAction, initializationBuilder); + /// + /// Embeds State Machine in current state.

+ /// Embedded Activity will be initialized on state entry and finalized on state exit. Events can be forwarded from State Machine to embedded Activity using + ///
+ /// State Machine class; must implement interface + /// Build action + /// Initialization builder; generates initialization event for embedded State Machine + [DebuggerHidden] + public static IBehaviorTypedStateBuilder AddSubmachine(this ITypedStateBuilder builder, EmbeddedBehaviorBuildAction buildAction = null, StateActionInitializationBuilderAsync initializationBuilder = null) + where TStateMachine : class, IStateMachine + => builder.AddSubmachine(StateMachine.Name, buildAction, initializationBuilder); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderDefaultTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderDefaultTransitionTypedExtensions.cs index 6cac38a5..d704146f 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderDefaultTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderDefaultTransitionTypedExtensions.cs @@ -1,21 +1,100 @@ -using Stateflows.StateMachines.Events; +using System.Diagnostics; using Stateflows.StateMachines.Registration.Interfaces; namespace Stateflows.StateMachines.Typed { public static class TypedStateBuilderDefaultTransitionTypedExtensions { + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static ITypedStateBuilder AddDefaultTransition(this ITypedStateBuilder builder) - where TTransition : Transition - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name); + where TTransition : class, IBaseDefaultTransition + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name); - public static ITypedStateBuilder AddDefaultTransition(this ITypedStateBuilder builder, string targetVertexName) - where TTransition : Transition - => builder.AddTransition(targetVertexName); + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - first type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ITypedStateBuilder AddDefaultTransition(this ITypedStateBuilder builder, string targetStateName) + where TTransition : class, IBaseDefaultTransition + => (builder as IStateBuilder).AddDefaultTransition(targetStateName) as ITypedStateBuilder; + /// + /// Adds default transition coming from current state.
+ /// Default transitions are triggered automatically after every State Machine execution and are changing its state. + /// + /// + /// Target + /// State that transition is coming into - first type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ITypedStateBuilder AddDefaultTransition(this ITypedStateBuilder builder, DefaultTransitionBuildAction transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddDefaultTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddDefaultTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderInternalTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderInternalTransitionTypedExtensions.cs index e59978a8..11e7ddfb 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderInternalTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderInternalTransitionTypedExtensions.cs @@ -1,4 +1,5 @@ -using Stateflows.Common; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.Registration.Interfaces; @@ -6,9 +7,31 @@ namespace Stateflows.StateMachines.Typed { public static class TypedStateBuilderInternalTransitionTypedExtensions { + /// + /// Adds internal transition triggered by coming from current state.
+ /// Internal transitions are triggered by events sent to State Machine and are not changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + [DebuggerHidden] public static ITypedStateBuilder AddInternalTransition(this ITypedStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition + where TTransition : class, IBaseTransition => builder.AddTransition(Constants.DefaultTransitionTarget); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderInternalTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderInternalTransitionTypedPayloadExtensions.cs deleted file mode 100644 index bb42f345..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderInternalTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedStateBuilderInternalTransitionTypedPayloadExtensions - { - public static ITypedStateBuilder AddInternalDataTransition(this ITypedStateBuilder builder) - where TTransition : Transition> - => builder.AddTransition, TTransition>(Constants.DefaultTransitionTarget); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderPayloadExtensions.cs deleted file mode 100644 index ba151a36..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderPayloadExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Registration.Interfaces; - -namespace Stateflows.StateMachines.Data -{ - public static class TypedStateBuilderPayloadExtensions - { - public static ITypedStateBuilder AddDataTransition(this ITypedStateBuilder builder, string targetVertexName, TransitionBuildAction> transitionBuildAction = null) - => builder.AddTransition>(targetVertexName, transitionBuildAction); - - public static ITypedStateBuilder AddInternalDataTransition(this ITypedStateBuilder builder, InternalTransitionBuildAction> transitionBuildAction = null) - => builder.AddInternalTransition>(transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderTransitionTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderTransitionTypedExtensions.cs index 0485570a..70971b7e 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderTransitionTypedExtensions.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderTransitionTypedExtensions.cs @@ -1,33 +1,119 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; +using System.Diagnostics; +using Stateflows.Common; using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; namespace Stateflows.StateMachines.Typed { public static class TypedStateBuilderTransitionTypedExtensions { + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// State that transition is coming into - third type parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DebuggerHidden] public static ITypedStateBuilder AddTransition(this ITypedStateBuilder builder) where TEvent : Event, new() - where TTransition : Transition - where TTargetState : BaseState - => AddTransition(builder, StateInfo.Name); + where TTransition : class, IBaseTransition + where TTargetState : class, IVertex + => AddTransition(builder, State.Name); - public static ITypedStateBuilder AddTransition(this ITypedStateBuilder builder, string targetVertexName) + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Definition + /// Class that defines transition actions (guard and/or effect) - second type parameter. + /// + /// + /// Target + /// Name of the state that transition is coming into - first parameter, + /// + /// + ///
+ /// Event class + /// Transition class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// Target state name + [DebuggerHidden] + public static ITypedStateBuilder AddTransition(this ITypedStateBuilder builder, string targetStateName) where TEvent : Event, new() - where TTransition : Transition - { - (builder as IInternal).Services.RegisterTransition(); - - return builder.AddTransition( - targetVertexName, - t => t.AddTransitionEvents() - ); - } + where TTransition : class, IBaseTransition + => (builder as IStateBuilder).AddTransition(targetStateName) as ITypedStateBuilder; + /// + /// Adds transition triggered by coming from current state.
+ /// Transitions are triggered by events sent to State Machine and are changing its state. + /// + /// + /// Trigger + /// Event that is accepted by transition - first type parameter. + /// + /// + /// Target + /// State that transition is coming into - second type parameter, + /// + /// + /// Guard/Effect + /// Transition actions can be defined using build action - first parameter. + /// + /// + ///
+ /// Event class + /// Target state class; must implement at least one of the following interfaces: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Transition build action + [DebuggerHidden] public static ITypedStateBuilder AddTransition(this ITypedStateBuilder builder, TransitionBuildAction transitionBuildAction = null) where TEvent : Event, new() - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); + where TTargetState : class, IVertex + => builder.AddTransition(State.Name, transitionBuildAction); } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderTransitionTypedPayloadExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderTransitionTypedPayloadExtensions.cs deleted file mode 100644 index 91ba8346..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateBuilder/Transitions/TypedStateBuilderTransitionTypedPayloadExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stateflows.Common; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed.Data -{ - public static class TypedStateBuilderTransitionTypedPayloadExtensions - { - public static ITypedStateBuilder AddDataTransition(this ITypedStateBuilder builder) - where TTransition : Transition> - where TTargetState : BaseState - => AddDataTransition(builder, StateInfo.Name); - - public static ITypedStateBuilder AddDataTransition(this ITypedStateBuilder builder, string targetVertexName) - where TTransition : Transition> - { - (builder as IInternal).Services.RegisterTransition>(); - - return builder.AddTransition>( - targetVertexName, - t => t.AddTransitionEvents>() - ); - } - - public static ITypedStateBuilder AddDataTransition(this ITypedStateBuilder builder, TransitionBuildAction> transitionBuildAction = null) - where TTargetState : BaseState - => builder.AddTransition(StateInfo.Name, transitionBuildAction); - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateMachineBuilder/StateMachine/TypedInitializedStateMachineBuilderTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateMachineBuilder/StateMachine/TypedInitializedStateMachineBuilderTypedExtensions.cs deleted file mode 100644 index 175f864b..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateMachineBuilder/StateMachine/TypedInitializedStateMachineBuilderTypedExtensions.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Diagnostics; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed -{ - public static class TypedInitializedStateMachineBuilderTypedExtensions - { - #region AddFinalState - [DebuggerHidden] - public static ITypedFinalizedStateMachineBuilder AddState(this ITypedInitializedStateMachineBuilder builder, string stateName = FinalState.Name) - where TFinalState : FinalState - => builder.AddFinalState(stateName); - #endregion - - #region AddState - [DebuggerHidden] - public static ITypedInitializedStateMachineBuilder AddState(this ITypedInitializedStateMachineBuilder builder, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - => builder.AddState(StateInfo.Name, stateBuildAction); - - [DebuggerHidden] - public static ITypedInitializedStateMachineBuilder AddState(this ITypedInitializedStateMachineBuilder builder, string stateName, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - { - (builder as IInternal).Services.RegisterState(); - - return builder.AddState( - stateName, - b => - { - b.AddStateEvents(); - - stateBuildAction?.Invoke(b as ITypedStateBuilder); - } - ); - } - #endregion - - #region AddCompositeState - [DebuggerHidden] - public static ITypedInitializedStateMachineBuilder AddCompositeState(this ITypedInitializedStateMachineBuilder builder, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TCompositeState : CompositeState - => builder.AddCompositeState(StateInfo.Name, compositeStateBuildAction); - - [DebuggerHidden] - public static ITypedInitializedStateMachineBuilder AddCompositeState(this ITypedInitializedStateMachineBuilder builder, string stateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TCompositeState : CompositeState - { - (builder as IInternal).Services.RegisterState(); - - return builder.AddCompositeState( - stateName, - b => - { - (b as IInitializedCompositeStateBuilder).AddStateEvents(); - (b as IInitializedCompositeStateBuilder).AddCompositeStateEvents(); - - compositeStateBuildAction?.Invoke(b as ITypedCompositeStateBuilder); - } - ); - } - #endregion - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateMachineBuilder/StateMachine/TypedStateMachineBuilderTypedExtensions.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateMachineBuilder/StateMachine/TypedStateMachineBuilderTypedExtensions.cs deleted file mode 100644 index c294f38b..00000000 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/Extensions/TypedStateMachineBuilder/StateMachine/TypedStateMachineBuilderTypedExtensions.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Diagnostics; -using Stateflows.StateMachines.Extensions; -using Stateflows.StateMachines.Registration.Interfaces; -using Stateflows.StateMachines.Registration.Interfaces.Internal; - -namespace Stateflows.StateMachines.Typed -{ - public static class TypedStateMachineBuilderTypedExtensions - { - #region AddInitialState - [DebuggerHidden] - public static ITypedInitializedStateMachineBuilder AddInitialState(this ITypedStateMachineBuilder builder, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - => builder.AddInitialState(StateInfo.Name, stateBuildAction); - - [DebuggerHidden] - public static ITypedInitializedStateMachineBuilder AddInitialState(this ITypedStateMachineBuilder builder, string stateName, StateTransitionsBuildAction stateBuildAction = null) - where TState : State - { - (builder as IInternal).Services.RegisterState(); - - return builder.AddInitialState( - stateName, - b => - { - b.AddStateEvents(); - - stateBuildAction?.Invoke(b as ITypedStateBuilder); - } - ); - } - #endregion - - #region AddInitialCompositeState - [DebuggerHidden] - public static ITypedInitializedStateMachineBuilder AddInitialCompositeState(this ITypedStateMachineBuilder builder, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TState : State - => builder.AddInitialCompositeState(StateInfo.Name, compositeStateBuildAction); - - [DebuggerHidden] - public static ITypedInitializedStateMachineBuilder AddInitialCompositeState(this ITypedStateMachineBuilder builder, string stateName, CompositeStateTransitionsBuildAction compositeStateBuildAction) - where TState : State - { - (builder as IInternal).Services.RegisterState(); - - return builder.AddInitialCompositeState( - stateName, - b => - { - (b as IInitializedCompositeStateBuilder).AddStateEvents(); - - compositeStateBuildAction?.Invoke(b as ITypedCompositeStateBuilder); - } - ); - } - #endregion - } -} diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/ICompositeStateBuilder.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/ICompositeStateBuilder.cs index 715c4021..623eb094 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/ICompositeStateBuilder.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/ICompositeStateBuilder.cs @@ -8,6 +8,7 @@ public interface IInitializedCompositeStateBuilder : ICompositeStateEvents, IStateTransitions, IStateMachine, + //IStateDoActivity, IStateMachineFinal { } @@ -16,6 +17,7 @@ public interface IFinalizedCompositeStateBuilder : IStateUtils, ICompositeStateEvents, IStateTransitions + //IStateDoActivity { } public interface ICompositeStateBuilder : @@ -23,6 +25,7 @@ public interface ICompositeStateBuilder : IStateUtils, ICompositeStateEvents, IStateTransitions, + //IStateDoActivity, IStateMachineInitial { } @@ -30,17 +33,20 @@ public interface ITypedInitializedCompositeStateBuilder : IStateUtils, IStateTransitions, IStateMachine, + //IStateDoActivity, IStateMachineFinal { } public interface ITypedFinalizedCompositeStateBuilder : IStateUtils, IStateTransitions + //IStateDoActivity { } public interface ITypedCompositeStateBuilder : IStateUtils, IStateTransitions, + //IStateDoActivity, IStateMachineInitial { } } diff --git a/Core/Stateflows/StateMachines/Registration/Interfaces/IStateMachineBuilder.cs b/Core/Stateflows/StateMachines/Registration/Interfaces/IStateMachineBuilder.cs index aaf67bf3..3745c1aa 100644 --- a/Core/Stateflows/StateMachines/Registration/Interfaces/IStateMachineBuilder.cs +++ b/Core/Stateflows/StateMachines/Registration/Interfaces/IStateMachineBuilder.cs @@ -20,18 +20,21 @@ public interface IStateMachineBuilder : IStateMachineEvents { } - public interface ITypedInitializedStateMachineBuilder : - IStateMachine, - IStateMachineFinal, - IStateMachineUtils - { } + //public interface ITypedInitializedStateMachineBuilder : + // IStateMachine, + // IStateMachineFinal, + // IStateMachineUtils, + // IStateMachineEvents + //{ } - public interface ITypedFinalizedStateMachineBuilder : - IStateMachineUtils - { } + //public interface ITypedFinalizedStateMachineBuilder : + // IStateMachineUtils, + // IStateMachineEvents + //{ } - public interface ITypedStateMachineBuilder : - IStateMachineInitial, - IStateMachineUtils - { } + //public interface ITypedStateMachineBuilder : + // IStateMachineInitial, + // IStateMachineUtils, + // IStateMachineEvents + //{ } } diff --git a/Core/Stateflows/StateMachines/Registration/Policies/FinalizationResetPolicy.cs b/Core/Stateflows/StateMachines/Registration/Policies/FinalizationResetPolicy.cs new file mode 100644 index 00000000..07b61efa --- /dev/null +++ b/Core/Stateflows/StateMachines/Registration/Policies/FinalizationResetPolicy.cs @@ -0,0 +1,42 @@ +using System.Threading.Tasks; +using Stateflows.Common; +using Stateflows.StateMachines.Context.Interfaces; + +namespace Stateflows.StateMachines +{ + internal class ResetObserver : IStateMachineObserver + { + private readonly ResetMode resetMode; + + public ResetObserver(ResetMode resetMode) + { + this.resetMode = resetMode; + } + + public Task AfterStateMachineFinalizeAsync(IStateMachineActionContext context) + { + var stateflowsContext = (context as IRootContext).Context.Context; + if (stateflowsContext.Stored) + { + context.StateMachine.Send(new ResetRequest() { Mode = resetMode }); + } + else + { + stateflowsContext.Deleted = true; + } + //var c = (context as IRootContext); + //if (c.Context.Context.Stored) + //{ + // context.StateMachine.Send(new ResetRequest() { Mode = resetMode }); + //} + + return Task.CompletedTask; + } + } + + public static class FinalizationResetPolicy + { + public static IStateMachineBuilder AddFinalizationResetPolicy(this IStateMachineBuilder builder, ResetMode resetMode = ResetMode.Full) + => builder.AddObserver(_ => new ResetObserver(resetMode)); + } +} diff --git a/Core/Stateflows/StateMachines/Registration/StateMachinesRegister.cs b/Core/Stateflows/StateMachines/Registration/StateMachinesRegister.cs index 1187a100..9447b1ea 100644 --- a/Core/Stateflows/StateMachines/Registration/StateMachinesRegister.cs +++ b/Core/Stateflows/StateMachines/Registration/StateMachinesRegister.cs @@ -8,6 +8,7 @@ using Stateflows.StateMachines.Exceptions; using Stateflows.StateMachines.Registration.Builders; using Stateflows.StateMachines.Registration.Interfaces; +using Stateflows.Common.Extensions; namespace Stateflows.StateMachines.Registration { @@ -85,12 +86,11 @@ public void AddStateMachine(string stateMachineName, int version, Type stateMach throw new StateMachineDefinitionException($"State machine '{stateMachineName}' with version '{version}' is already registered", new StateMachineClass(stateMachineName)); } - Services.RegisterStateMachine(stateMachineType); + Services.AddServiceType(stateMachineType); - var sm = FormatterServices.GetUninitializedObject(stateMachineType) as StateMachine; + var sm = FormatterServices.GetUninitializedObject(stateMachineType) as IStateMachine; var builder = new StateMachineBuilder(stateMachineName, version, Services); - builder.AddStateMachineEvents(stateMachineType); builder.Result.StateMachineType = stateMachineType; sm.Build(builder); builder.Result.Build(); @@ -105,7 +105,7 @@ public void AddStateMachine(string stateMachineName, int version, Type stateMach [DebuggerHidden] public void AddStateMachine(string stateMachineName, int version = 1) - where TStateMachine : StateMachine + where TStateMachine : IStateMachine => AddStateMachine(stateMachineName, version, typeof(TStateMachine)); [DebuggerHidden] @@ -116,7 +116,7 @@ public void AddGlobalInterceptor(StateMachineInterceptorFactory interceptorFacto public void AddGlobalInterceptor() where TInterceptor : class, IStateMachineInterceptor { - Services.RegisterInterceptor(); + Services.AddServiceType(); AddGlobalInterceptor(serviceProvider => serviceProvider.GetRequiredService()); } @@ -128,7 +128,7 @@ public void AddGlobalExceptionHandler(StateMachineExceptionHandlerFactory except public void AddGlobalExceptionHandler() where TExceptionHandler : class, IStateMachineExceptionHandler { - Services.RegisterExceptionHandler(); + Services.AddServiceType(); AddGlobalExceptionHandler(serviceProvider => serviceProvider.GetRequiredService()); } @@ -140,7 +140,7 @@ public void AddGlobalObserver(StateMachineObserverFactory observerFactory) public void AddGlobalObserver() where TObserver : class, IStateMachineObserver { - Services.RegisterObserver(); + Services.AddServiceType(); AddGlobalObserver(serviceProvider => serviceProvider.GetRequiredService()); } } diff --git a/Core/Stateflows/StateMachines/StateMachinesDependencyInjection.cs b/Core/Stateflows/StateMachines/StateMachinesDependencyInjection.cs index dd0ce751..82589517 100644 --- a/Core/Stateflows/StateMachines/StateMachinesDependencyInjection.cs +++ b/Core/Stateflows/StateMachines/StateMachinesDependencyInjection.cs @@ -1,9 +1,12 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; using Stateflows.Common.Interfaces; using Stateflows.Common.Initializer; using Stateflows.Common.Registration.Interfaces; +using Stateflows.StateMachines.Context; +using Stateflows.StateMachines.Context.Interfaces; using Stateflows.StateMachines.Engine; using Stateflows.StateMachines.Registration; using Stateflows.StateMachines.EventHandlers; @@ -26,9 +29,10 @@ public static IStateflowsBuilder AddStateMachines(this IStateflowsBuilder statef [DebuggerHidden] public static IStateflowsBuilder AddDefaultInstance(this IStateflowsBuilder stateflowsBuilder, DefaultInstanceInitializationRequestFactoryAsync initializationRequestFactoryAsync = null) - where TStateMachine : StateMachine - => stateflowsBuilder.AddDefaultInstance(new StateMachineClass(StateMachineInfo.Name).BehaviorClass, initializationRequestFactoryAsync); + where TStateMachine : class, IStateMachine + => stateflowsBuilder.AddDefaultInstance(new StateMachineClass(StateMachine.Name).BehaviorClass, initializationRequestFactoryAsync); + [DebuggerHidden] private static StateMachinesRegister EnsureStateMachinesServices(this IStateflowsBuilder stateflowsBuilder) { if (!Registers.TryGetValue(stateflowsBuilder, out var register)) @@ -46,15 +50,31 @@ private static StateMachinesRegister EnsureStateMachinesServices(this IStateflow .AddSingleton(register) .AddSingleton() .AddTransient() - .AddSingleton() .AddSingleton() .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() - ; + .AddTransient(provider => + ContextHolder.StateMachineContext.Value ?? + throw new InvalidOperationException($"No service for type '{typeof(IStateMachineContext).FullName}' is available in this context.") + ) + .AddTransient(provider => + ContextHolder.StateContext.Value ?? + throw new InvalidOperationException($"No service for type '{typeof(IStateContext).FullName}' is available in this context.") + ) + .AddTransient(provider => + ContextHolder.TransitionContext.Value ?? + throw new InvalidOperationException($"No service for type '{typeof(ITransitionContext).FullName}' is available in this context.") + ) + .AddTransient(provider => + ContextHolder.ExecutionContext.Value ?? + throw new InvalidOperationException($"No service for type '{typeof(IExecutionContext).FullName}' is available in this context.") + ) + ; } return register; diff --git a/Core/Stateflows/System/Engine/Processor.cs b/Core/Stateflows/System/Engine/Processor.cs deleted file mode 100644 index 62cdb9d7..00000000 --- a/Core/Stateflows/System/Engine/Processor.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using System.Collections.Generic; -using Stateflows.Common; -using Stateflows.Common.Interfaces; -using Microsoft.Extensions.DependencyInjection; - -namespace Stateflows.System.Engine -{ - internal class Processor : IEventProcessor - { - public string BehaviorType => SystemBehavior.Id.Type; - - private IEnumerable EventHandlers { get; } - - private IServiceProvider ServiceProvider { get; } - - public Processor(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider.CreateScope().ServiceProvider; - EventHandlers = ServiceProvider.GetServices(); - } - - private Task TryHandleEventAsync(TEvent @event) - where TEvent : Event, new() - { - var eventHandler = EventHandlers.FirstOrDefault(h => h.EventType.IsInstanceOfType(@event)); - - return eventHandler != null - ? eventHandler.TryHandleEventAsync(@event) - : Task.FromResult(EventStatus.NotConsumed); - } - - public Task ProcessEventAsync(BehaviorId id, TEvent @event, IServiceProvider serviceProvider) - where TEvent : Event, new() - => TryHandleEventAsync(@event); - } -} diff --git a/Core/Stateflows/System/Engine/Provider.cs b/Core/Stateflows/System/Engine/Provider.cs deleted file mode 100644 index 5c4e5ef2..00000000 --- a/Core/Stateflows/System/Engine/Provider.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; -using Stateflows.Common; -using Stateflows.Common.Classes; -using Stateflows.Common.Utilities; -using Stateflows.Common.Interfaces; - -namespace Stateflows.System.Engine -{ - internal class Provider : IBehaviorProvider - { - public StateflowsEngine Engine { get; private set; } - - public IServiceProvider ServiceProvider { get; private set; } - - public bool IsLocal => true; - - public Provider(StateflowsEngine engine, IServiceProvider serviceProvider) - { - Engine = engine; - ServiceProvider = serviceProvider; - } - - public event ActionAsync BehaviorClassesChanged; - - public bool TryProvideBehavior(BehaviorId id, out IBehavior behavior) - { - behavior = id == SystemBehavior.Id - ? new Behavior(Engine, ServiceProvider, id) - : null; - - return behavior != null; - } - - public IEnumerable BehaviorClasses - => new BehaviorClass[] { new BehaviorClass("System", "Stateflows") }; - } -} diff --git a/Core/Stateflows/System/EventHandlers/AvailableBehaviorClassesHandler.cs b/Core/Stateflows/System/EventHandlers/AvailableBehaviorClassesHandler.cs deleted file mode 100644 index 6a97992b..00000000 --- a/Core/Stateflows/System/EventHandlers/AvailableBehaviorClassesHandler.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Threading.Tasks; -using Stateflows.Common; -using Stateflows.Common.Interfaces; -using Microsoft.Extensions.DependencyInjection; - -namespace Stateflows.System.EventHandlers -{ - internal class AvailableBehaviorClassesHandler : ISystemEventHandler - { - public IBehaviorClassesProvider BehaviorClassesProvider { get; } - - public AvailableBehaviorClassesHandler(IServiceProvider serviceProvider) - { - BehaviorClassesProvider = serviceProvider.GetRequiredService(); - } - - public Type EventType => typeof(AvailableBehaviorClassesRequest); - - public Task TryHandleEventAsync(TEvent @event) - where TEvent : Event, new() - { - if (@event is AvailableBehaviorClassesRequest request) - { - request.Respond(new AvailableBehaviorClassesResponse() { AvailableBehaviorClasses = BehaviorClassesProvider.AllBehaviorClasses }); - - return Task.FromResult(EventStatus.Consumed); - } - - return Task.FromResult(EventStatus.NotConsumed); - } - } -} diff --git a/Core/Stateflows/System/EventHandlers/BehaviorInstancesHandler.cs b/Core/Stateflows/System/EventHandlers/BehaviorInstancesHandler.cs deleted file mode 100644 index f7cecc05..00000000 --- a/Core/Stateflows/System/EventHandlers/BehaviorInstancesHandler.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Stateflows.Common; -using Stateflows.Common.Interfaces; - -namespace Stateflows.System.EventHandlers -{ - internal class BehaviorInstancesHandler : ISystemEventHandler - { - public readonly IBehaviorClassesProvider BehaviorClassesProvider; - public readonly IServiceProvider ServiceProvider; - - public BehaviorInstancesHandler(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - BehaviorClassesProvider = serviceProvider.GetRequiredService(); - } - - public Type EventType => typeof(BehaviorInstancesRequest); - - public async Task TryHandleEventAsync(TEvent @event) - where TEvent : Event, new() - { - if (@event is BehaviorInstancesRequest request) - { - var classes = request.BehaviorClasses; - if (classes == null || !classes.Any()) - { - classes = BehaviorClassesProvider.AllBehaviorClasses; - } - - var storage = ServiceProvider.GetRequiredService(); - - var contexts = await storage.GetContextsAsync(classes); - - request.Respond(new BehaviorInstancesResponse() - { - Behaviors = contexts.Select(c => new BehaviorDescriptor() - { - Id = c.Id, - Status = BehaviorStatus.Initialized - } - ).ToArray() - } - ); - - return EventStatus.Consumed; - } - - return EventStatus.NotConsumed; - } - } -} diff --git a/Core/Stateflows/System/Interfaces/ISystemEventHandler.cs b/Core/Stateflows/System/Interfaces/ISystemEventHandler.cs deleted file mode 100644 index 5985daa7..00000000 --- a/Core/Stateflows/System/Interfaces/ISystemEventHandler.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Threading.Tasks; -using Stateflows.Common; - -namespace Stateflows.System -{ - public interface ISystemEventHandler - { - Type EventType { get; } - - Task TryHandleEventAsync(TEvent @event) - where TEvent : Event, new(); - } -} diff --git a/Core/Stateflows/System/SystemDependencyInjection.cs b/Core/Stateflows/System/SystemDependencyInjection.cs deleted file mode 100644 index 6a39cfcd..00000000 --- a/Core/Stateflows/System/SystemDependencyInjection.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Stateflows.Common.Extensions; -using Stateflows.Common.Interfaces; -using Stateflows.Common.Registration.Interfaces; -using Stateflows.System.Engine; -using Stateflows.System.EventHandlers; - -namespace Stateflows.System -{ - internal static class SystemDependencyInjection - { - public static IStateflowsBuilder EnsureSystemServices(this IStateflowsBuilder stateflowsBuilder) - { - if (!stateflowsBuilder.ServiceCollection.IsServiceRegistered()) - { - stateflowsBuilder - .ServiceCollection - .AddTransient() - .AddTransient() - .AddSingleton() - .AddTransient() - ; - } - - return stateflowsBuilder; - } - } -} diff --git a/Examples/Blazor/Server/Blazor.Server/Blazor.Server.csproj b/Examples/Blazor/Server/Blazor.Server/Blazor.Server.csproj index 12088dec..d62aea54 100644 --- a/Examples/Blazor/Server/Blazor.Server/Blazor.Server.csproj +++ b/Examples/Blazor/Server/Blazor.Server/Blazor.Server.csproj @@ -8,7 +8,6 @@ - diff --git a/Examples/Blazor/Server/Blazor.Server/CustomException.cs b/Examples/Blazor/Server/Blazor.Server/CustomException.cs new file mode 100644 index 00000000..3c3e6c15 --- /dev/null +++ b/Examples/Blazor/Server/Blazor.Server/CustomException.cs @@ -0,0 +1,8 @@ +namespace Blazor.Server +{ + public class CustomException : Exception + { + public CustomException(string? message) : base(message) + { } + } +} diff --git a/Examples/Blazor/Server/Blazor.Server/Pages/Activities.razor b/Examples/Blazor/Server/Blazor.Server/Pages/Activities.razor index f300a112..5cae1cc9 100644 --- a/Examples/Blazor/Server/Blazor.Server/Pages/Activities.razor +++ b/Examples/Blazor/Server/Blazor.Server/Pages/Activities.razor @@ -1,6 +1,5 @@ @page "/" @inject IActivityLocator locator -@inject ISystem system Activities @@ -17,7 +16,6 @@ @* *@ - @* *@ @@ -87,22 +85,16 @@ expectedEvents = null; } - private async Task RefreshAInfo(IActivity activity) + private async Task RefreshAInfo(IActivityBehavior activity) { plantUmlUrl = (await activity.GetPlantUmlAsync()).Response.GetUrl(); } - private async Task SystemRequest() - { - var classes = await system.GetAvailableBehaviorClassesAsync(); - var instances = await system.GetBehaviorInstancesAsync(); - } - private async Task Initialize() { if (locator.TryLocateActivity(GetCurrentId(), out var activity)) { - message = (await activity.InitializeAsync(new X.InitializationRequest1() { Foo = "bar" })).Response?.InitializationSuccessful ?? false + message = (await activity.SendAsync(new X.ClearingRequest() { PersonIds = Enumerable.Range(0, 30).Select(i => new X.PersonId()).ToArray() })).Status == EventStatus.Initialized ? "Activity located and initialized" : "Activity located, it's already initialized"; @@ -139,7 +131,7 @@ { if (locator.TryLocateActivity(GetCurrentId(), out var activity)) { - await activity.InitializeAsync(); + await activity.SendAsync(new Initialize()); await RefreshAInfo(activity); } else diff --git a/Examples/Blazor/Server/Blazor.Server/Pages/StateMachines.razor b/Examples/Blazor/Server/Blazor.Server/Pages/StateMachines.razor index 5d34854f..6906e46c 100644 --- a/Examples/Blazor/Server/Blazor.Server/Pages/StateMachines.razor +++ b/Examples/Blazor/Server/Blazor.Server/Pages/StateMachines.razor @@ -1,7 +1,6 @@ @page "/state-machines" @using Examples.Common @inject IStateMachineLocator locator -@inject ISystem system State Machines @@ -73,9 +72,9 @@ private string message = ""; - private IStateMachine? _stateMachine = null; + private IStateMachineBehavior? _stateMachine = null; - private async Task GetStateMachineAsync() + private async Task GetStateMachineAsync() { var instance = $"{stateMachineInstance}"; if (_stateMachine?.Id == GetCurrentId()) @@ -144,7 +143,7 @@ expectedEvents = null; } - private async Task RefreshSMInfo(IStateMachine stateMachine) + private async Task RefreshSMInfo(IStateMachineBehavior stateMachine) { var result = await stateMachine.GetCurrentStateAsync(); expectedEvents = result.Response?.ExpectedEvents; @@ -164,13 +163,13 @@ var sm = await GetStateMachineAsync(); if (sm != null) { - var result = await sm.InitializeAsync(); + var result = await sm.SendAsync(new Initialize()); - var msg = result.Response?.InitializationSuccessful ?? false + var msg = result.Status == EventStatus.Initialized ? "State Machine located and initialized" : "State Machine located, it's already initialized"; - if (!result.Response?.InitializationSuccessful ?? false) + if (result.Status != EventStatus.Initialized) { await RefreshSMInfo(sm); } @@ -185,6 +184,7 @@ private async Task GetStatus() { + // throw new CustomException("x"); var sm = await GetStateMachineAsync(); if (sm != null) { @@ -220,6 +220,10 @@ { var result = await sm.SendAsync(ev); + message = result.Status == EventStatus.Failed + ? "Processing failed" + : "Processing done"; + if (!(result.Validation?.IsValid ?? true)) { message = "Event invalid"; diff --git a/Examples/Blazor/Server/Blazor.Server/Program.cs b/Examples/Blazor/Server/Blazor.Server/Program.cs index 4b9d1f29..f2e379f1 100644 --- a/Examples/Blazor/Server/Blazor.Server/Program.cs +++ b/Examples/Blazor/Server/Blazor.Server/Program.cs @@ -1,25 +1,26 @@ using System.Diagnostics; using Blazor.Server.Data; using Examples.Common; +using Examples.Storage; using Stateflows; using Stateflows.Utils; using Stateflows.Common; using Stateflows.Common.Data; using Stateflows.StateMachines; using Stateflows.StateMachines.Typed; -using Stateflows.StateMachines.Data; using Stateflows.StateMachines.Sync; using Stateflows.Activities; -using Stateflows.Activities.Data; using Stateflows.Activities.Typed; using Stateflows.Activities.Attributes; using Stateflows.Activities.Registration.Interfaces; using Stateflows.StateMachines.Attributes; -using Examples.Storage; using X; using System.Collections.Generic; using Newtonsoft.Json.Linq; -using MongoDB.Driver; +using Blazor.Server; +using Stateflows.StateMachines.Context.Interfaces; +using Stateflows.Common.Exceptions; +using Stateflows.Common.Utilities; var builder = WebApplication.CreateBuilder(args); @@ -33,17 +34,40 @@ builder.Services.AddStateflows(b => b .AddPlantUml() - //.AddStorage() - - .AddTracing() + .AddStorage() .AddStateMachines(b => b .AddStateMachine("stateMachine1", b => b + //.AddExceptionHandler() + //.AddInterceptor() + //.AddDefaultInitializer(async c => throw new CustomException("test")) .AddInitialState("state1", b => b + .AddOnEntry(async c => + { + //throw new CustomException("test"); + + //var e = new CustomException("test"); + //var x = new Exception("boo", e); + //var z = StateflowsJsonConverter.SerializePolymorphicObject(x, false, Newtonsoft.Json.Formatting.Indented); + //Debug.WriteLine(z); + + //var s = "{\"$type\":\"System.Exception, System.Private.CoreLib\",\"ClassName\":\"System.Exception\",\"Message\":\"boo\",\"Data\":null,\"InnerException\":{\"$type\":\"Blazor.Server.CustomExceptionX, Blazor.Server\",\"Message\":\"test\",\"Data\":{\"$type\":\"System.Collections.ListDictionaryInternal, System.Private.CoreLib\"},\"InnerException\":null,\"HelpLink\":null,\"Source\":null,\"HResult\":-2146233088,\"StackTrace\":null},\"HelpURL\":null,\"StackTraceString\":null,\"RemoteStackTraceString\":null,\"RemoteStackIndex\":0,\"ExceptionMethod\":null,\"HResult\":-2146233088,\"Source\":null,\"WatsonBuckets\":null}\r\n"; + //var x = StateflowsJsonConverter.DeserializeObject(s); + + throw new Exception("test"); + + Debug.WriteLine("x"); + }) .AddTransition("state2") + .AddTransition("state3") .AddInternalTransition(b => b - .AddEffect(c => c.Event.Respond(new ExampleResponse() { ResponseData = "Example response data" })) + .AddEffect(c => + { + c.Event.Respond(new ExampleResponse() { ResponseData = "Example response data" }); + }) + .AddGuard(c => throw new Exception("test")) ) + .AddDoActivity() ) .AddState("state2", b => b .AddOnEntry(async c => @@ -51,26 +75,28 @@ c.StateMachine.Publish(new SomeNotification()); }) .AddTransition("state1") + .AddTransition("state3") ) - ) - - .AddStateMachine("stateMachine2", b => b - .AddInitialState("state1", b => b - .AddOnEntry(async c => - { - await c.StateMachine.SubscribeAsync(new StateMachineId("stateMachine1", "x")); - }) - .AddTransition("state2") + .AddState("state3", b => b + .AddTransition("state1") + .AddTransition() ) - .AddState("state2") + .AddFinalState() ) ) .AddActivities(b => b + .AddActivity("clearing") + .AddActivity("activity1", b => b + .AddAcceptEventAction(b => b + .AddControlFlow>() + ) + .AddAcceptEventAction(async c => Debug.WriteLine("Yuppi!")) + ) .AddActivity("activity2", b => b - .AddOnInitialize(async c => + .AddInitializer(async c => { - Debug.WriteLine(c.InitializationRequest.Foo); + Debug.WriteLine(c.InitializationEvent.Foo); return true; }) @@ -115,9 +141,9 @@ .AddActivity("activity3") .AddActivity("activity4", b => b - .AddOnInitialize(async c => + .AddInitializer(async c => { - Debug.WriteLine(c.InitializationRequest.Foo); + Debug.WriteLine(c.InitializationEvent.Foo); return true; }) @@ -140,8 +166,6 @@ ) ) - .AddAutoInitialization(new StateMachineClass("stateMachine1")) - .SetEnvironment( builder.Environment.IsDevelopment() ? $"{StateflowsEnvironments.Development}.{Environment.MachineName}" @@ -174,15 +198,51 @@ namespace X { - public class InitializationRequest1 : InitializationRequest + public class Structured : IStructuredActivityNodeInitialization + { + public Task OnInitializeAsync() + { + throw new NotImplementedException(); + } + } + + public class InitializationRequest1 : Event { public string Foo { get; set; } } - public class Activity3 : Stateflows.Activities.Activity + public class Handler : IStateMachineExceptionHandler, IStateMachineInterceptor { - public override void Build(ITypedActivityBuilder builder) + public Task OnStateEntryExceptionAsync(IStateActionContext context, Exception exception) + { + return Task.FromResult(true); + } + + public Task AfterProcessEventAsync(IEventActionContext context) + { + Debug.WriteLine($">>>>>>>>>>> after processing {context.Event.Name}"); + + return Task.CompletedTask; + } + + public Task BeforeDehydrateAsync(IStateMachineActionContext context) + { + Debug.WriteLine($">>>>>>>>>>> dehydrate {context.ExecutionTrigger.Name}"); + + return Task.CompletedTask; + } + } + + public class Activity3 : IActivity + { + public void Build(IActivityBuilder builder) => builder + .AddInitializer(async c => + { + Debug.WriteLine(c.InitializationEvent.Foo); + + return true; + }) .AddAcceptEventAction(async c => { }, b => b .AddControlFlow("action1") ) @@ -235,16 +295,9 @@ public override void Build(ITypedActivityBuilder builder) Debug.WriteLine($"counter: {counter}"); } ); - - public override async Task OnInitializeAsync(InitializationRequest1 initializationRequest) - { - Debug.WriteLine(initializationRequest.Foo); - - return true; - } } - public class Action1 : ActionNode + public class Action1 : IActionNode { public readonly Input IntInput; @@ -252,22 +305,108 @@ public class Action1 : ActionNode private readonly StateValue Bar = new("bar"); - public override Task ExecuteAsync() + public Task ExecuteAsync(CancellationToken cancellationToken) { if (!Foo.IsSet) { - Foo.Value = 42; + Foo.Set(42); } return Task.CompletedTask; } } - public class Flow1 : Flow + public class Flow1 : IFlowGuard + { + public async Task GuardAsync(int token) + { + return token > 40; + } + } + + + + + + + + + + public class PersonId { } + + public class ClearingRequest : Event + { + public PersonId[] PersonIds { get; set; } = new PersonId[0]; + } + + + public class ClearingActivity : IActivity { - public override async Task GuardAsync() + public void Build(IActivityBuilder builder) { - return Context.Token > 40; + builder + .AddAcceptEventAction( + async c => c.OutputRange(c.Event.PersonIds), + b => b.AddFlow("clearing-loop") + ) + .AddIterativeActivity( + "clearing-loop", + b => b + .AddInput(b => b + .AddFlow("clear") + ) + //.AddInitial(b => b + // .AddControlFlow>() + //) + //.AddTimeEventAction(b => b + // .AddControlFlow("clear") + //) + .AddAction("clear", async c => Debug.WriteLine($"cleared {c.GetTokensOfType().Count()} dossiers")) + + .AddControlFlow("finish"), + 10 + ) + .AddAction("finish", async c => Debug.WriteLine("finished")) + ; } } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } \ No newline at end of file diff --git a/Examples/Blazor/Server/Blazor.Server/_Imports.razor b/Examples/Blazor/Server/Blazor.Server/_Imports.razor index ac4a5289..cd688673 100644 --- a/Examples/Blazor/Server/Blazor.Server/_Imports.razor +++ b/Examples/Blazor/Server/Blazor.Server/_Imports.razor @@ -10,6 +10,5 @@ @using Blazor.Server.Shared @using Stateflows @using Stateflows.Common -@using Stateflows.System @using Stateflows.Activities @using Stateflows.StateMachines diff --git a/Examples/Blazor/Server/Blazor.Server/appsettings.json b/Examples/Blazor/Server/Blazor.Server/appsettings.json index 10f68b8c..5812d088 100644 --- a/Examples/Blazor/Server/Blazor.Server/appsettings.json +++ b/Examples/Blazor/Server/Blazor.Server/appsettings.json @@ -1,9 +1,9 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, + //"Logging": { + // "LogLevel": { + // "Default": "Information", + // "Microsoft.AspNetCore": "Warning" + // } + //}, "AllowedHosts": "*" } diff --git a/Examples/Examples.Common/SomeEvent.cs b/Examples/Examples.Common/SomeEvent.cs index 9513ccb5..4424e45d 100644 --- a/Examples/Examples.Common/SomeEvent.cs +++ b/Examples/Examples.Common/SomeEvent.cs @@ -6,5 +6,6 @@ public class SomeEvent : Event { public string TheresSomethingHappeningHere { get; set; } = "What it is ain't exactly clear"; public int DelaySize { get; set; } + public bool InitializationSuccessful { get; set; } } } \ No newline at end of file diff --git a/Examples/Examples.SharedBehaviors/StateMachine1.cs b/Examples/Examples.SharedBehaviors/StateMachine1.cs index 46d9e4b5..24f9efe6 100644 --- a/Examples/Examples.SharedBehaviors/StateMachine1.cs +++ b/Examples/Examples.SharedBehaviors/StateMachine1.cs @@ -7,9 +7,9 @@ namespace Examples.SharedBehaviors { [StateMachineBehavior(nameof(StateMachine1))] - public class StateMachine1 : StateMachine + public class StateMachine1 : IStateMachine { - public override void Build(ITypedStateMachineBuilder builder) + public void Build(IStateMachineBuilder builder) { builder .AddInitialState("state1", b => b diff --git a/Examples/Examples.SharedBehaviors/StateMachine2.cs b/Examples/Examples.SharedBehaviors/StateMachine2.cs index 8a2ca233..bcd887c5 100644 --- a/Examples/Examples.SharedBehaviors/StateMachine2.cs +++ b/Examples/Examples.SharedBehaviors/StateMachine2.cs @@ -6,9 +6,9 @@ namespace Examples.SharedBehaviors { [StateMachineBehavior(nameof(StateMachine2))] - public class StateMachine2 : StateMachine + public class StateMachine2 : IStateMachine { - public override void Build(ITypedStateMachineBuilder builder) + public void Build(IStateMachineBuilder builder) { builder .AddInitialState("state1", b => b diff --git a/Examples/Examples.Storage/Migrations/20240723222647_AddTriggerOnStartup.Designer.cs b/Examples/Examples.Storage/Migrations/20240723222647_AddTriggerOnStartup.Designer.cs new file mode 100644 index 00000000..ec2a52e6 --- /dev/null +++ b/Examples/Examples.Storage/Migrations/20240723222647_AddTriggerOnStartup.Designer.cs @@ -0,0 +1,72 @@ +// +using System; +using Examples.Storage; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Examples.Storage.Migrations +{ + [DbContext(typeof(StateflowsDbContext))] + [Migration("20240723222647_AddTriggerOnStartup")] + partial class AddTriggerOnStartup + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.15") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Stateflows.Storage.EntityFrameworkCore.EntityFrameworkCore.Entities.Context_v1", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BehaviorClass") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("BehaviorId") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("Data") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TriggerOnStartup") + .HasColumnType("bit"); + + b.Property("TriggerTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("BehaviorClass"); + + b.HasIndex("BehaviorId") + .IsUnique(); + + b.HasIndex("TriggerOnStartup"); + + b.HasIndex("TriggerTime"); + + b.ToTable("StateflowsContexts_v1"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Examples/Examples.Storage/Migrations/20240723222647_AddTriggerOnStartup.cs b/Examples/Examples.Storage/Migrations/20240723222647_AddTriggerOnStartup.cs new file mode 100644 index 00000000..275eb683 --- /dev/null +++ b/Examples/Examples.Storage/Migrations/20240723222647_AddTriggerOnStartup.cs @@ -0,0 +1,62 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Examples.Storage.Migrations +{ + /// + public partial class AddTriggerOnStartup : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "StateflowsTraces_v1"); + + migrationBuilder.AddColumn( + name: "TriggerOnStartup", + table: "StateflowsContexts_v1", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.CreateIndex( + name: "IX_StateflowsContexts_v1_TriggerOnStartup", + table: "StateflowsContexts_v1", + column: "TriggerOnStartup"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_StateflowsContexts_v1_TriggerOnStartup", + table: "StateflowsContexts_v1"); + + migrationBuilder.DropColumn( + name: "TriggerOnStartup", + table: "StateflowsContexts_v1"); + + migrationBuilder.CreateTable( + name: "StateflowsTraces_v1", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + BehaviorId = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), + Data = table.Column(type: "nvarchar(max)", nullable: false), + ExecutionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_StateflowsTraces_v1", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_StateflowsTraces_v1_BehaviorId", + table: "StateflowsTraces_v1", + column: "BehaviorId"); + } + } +} diff --git a/Examples/Examples.Storage/Migrations/StateflowsDbContextModelSnapshot.cs b/Examples/Examples.Storage/Migrations/StateflowsDbContextModelSnapshot.cs index 17d22c2a..cb8f6003 100644 --- a/Examples/Examples.Storage/Migrations/StateflowsDbContextModelSnapshot.cs +++ b/Examples/Examples.Storage/Migrations/StateflowsDbContextModelSnapshot.cs @@ -44,6 +44,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired() .HasColumnType("nvarchar(max)"); + b.Property("TriggerOnStartup") + .HasColumnType("bit"); + b.Property("TriggerTime") .HasColumnType("datetime2"); @@ -54,37 +57,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("BehaviorId") .IsUnique(); + b.HasIndex("TriggerOnStartup"); + b.HasIndex("TriggerTime"); b.ToTable("StateflowsContexts_v1"); }); - - modelBuilder.Entity("Stateflows.Storage.EntityFrameworkCore.EntityFrameworkCore.Entities.Trace_v1", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("BehaviorId") - .IsRequired() - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("Data") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ExecutionTime") - .HasColumnType("datetime2"); - - b.HasKey("Id"); - - b.HasIndex("BehaviorId"); - - b.ToTable("StateflowsTraces_v1"); - }); #pragma warning restore 612, 618 } } diff --git a/Examples/Examples.Storage/StateflowsDbContext.cs b/Examples/Examples.Storage/StateflowsDbContext.cs index 64897ee7..daa1a725 100644 --- a/Examples/Examples.Storage/StateflowsDbContext.cs +++ b/Examples/Examples.Storage/StateflowsDbContext.cs @@ -8,7 +8,6 @@ namespace Examples.Storage public class StateflowsDbContext : DbContext, IStateflowsDbContext_v1 { public DbSet Contexts_v1 { get; set; } - public DbSet Traces_v1 { get; set; } protected readonly IConfiguration Configuration; diff --git a/Extensions/Stateflows.Extensions.MinimalAPI/StateMachines/StateBuilder/TransitionExtensions.cs b/Extensions/Stateflows.Extensions.MinimalAPI/StateMachines/StateBuilder/TransitionExtensions.cs index 9ca80c91..9609b782 100644 --- a/Extensions/Stateflows.Extensions.MinimalAPI/StateMachines/StateBuilder/TransitionExtensions.cs +++ b/Extensions/Stateflows.Extensions.MinimalAPI/StateMachines/StateBuilder/TransitionExtensions.cs @@ -62,7 +62,7 @@ public static IStateBuilder AddHttpGetInternalTransition(this IStateBuilder buil return builder; } - public static IStateBuilder AddHttpPostTransition(this IStateBuilder builder, string pattern, string targetVertexName, TransitionBuildAction>? transitionbuildAction = null, Action? endpointbuildAction = null) + public static IStateBuilder AddHttpPostTransition(this IStateBuilder builder, string pattern, string targetStateName, TransitionBuildAction>? transitionbuildAction = null, Action? endpointbuildAction = null) { if (builder is IBehaviorBuilder behaviorBuilder) { @@ -82,7 +82,7 @@ public static IStateBuilder AddHttpPostTransition(this IStateBu HttpEvent.UrlOverride = pattern; HttpEvent.MethodOverride = "POST"; - builder.AddTransition>(targetVertexName, transitionbuildAction); + builder.AddTransition>(targetStateName, transitionbuildAction); HttpEvent.UrlOverride = null; HttpEvent.MethodOverride = null; diff --git a/Extensions/Stateflows.Extensions.MinimalAPI/StateMachines/StateBuilder/TransitionTypedExtensions.cs b/Extensions/Stateflows.Extensions.MinimalAPI/StateMachines/StateBuilder/TransitionTypedExtensions.cs index c7e49655..5cc24f04 100644 --- a/Extensions/Stateflows.Extensions.MinimalAPI/StateMachines/StateBuilder/TransitionTypedExtensions.cs +++ b/Extensions/Stateflows.Extensions.MinimalAPI/StateMachines/StateBuilder/TransitionTypedExtensions.cs @@ -13,19 +13,19 @@ public static class TransitionTypedExtensions // => builder.AddHttpGetInternalTransition(pattern, b => b.AddTransitionEvents(), endpointbuildAction); #endregion - #region AddHttpPostTransition - public static IStateBuilder AddHttpPostTransition(this IStateBuilder builder, string pattern, TransitionBuildAction> transitionBuildAction = null, Action endpointBuildAction = null) - where TTargetState : BaseState - => builder.AddHttpPostTransition(pattern, StateInfo.Name, transitionBuildAction, endpointBuildAction); + //#region AddHttpPostTransition + //public static IStateBuilder AddHttpPostTransition(this IStateBuilder builder, string pattern, TransitionBuildAction> transitionBuildAction = null, Action endpointBuildAction = null) + // where TTargetState : IVertex + // => builder.AddHttpPostTransition(pattern, State.Name, transitionBuildAction, endpointBuildAction); - public static IStateBuilder AddHttpPostTransition(this IStateBuilder builder, string pattern, Action endpointbuildAction = null) - where TTransition : Transition> - where TTargetState : BaseState - => builder.AddHttpPostTransition(pattern, StateInfo.Name, b => b.AddTransitionEvents>(), endpointbuildAction); + //public static IStateBuilder AddHttpPostTransition(this IStateBuilder builder, string pattern, Action endpointbuildAction = null) + // where TTransition : Transition> + // where TTargetState : IVertex + // => builder.AddHttpPostTransition(pattern, State.Name, b => b.AddTransitionEvents>(), endpointbuildAction); - public static IStateBuilder AddHttpPostTransition(this IStateBuilder builder, string pattern, string targetVertexName, Action endpointbuildAction = null) - where TTransition : Transition> - => builder.AddHttpPostTransition(pattern, targetVertexName, b => b.AddTransitionEvents>(), endpointbuildAction); - #endregion + //public static IStateBuilder AddHttpPostTransition(this IStateBuilder builder, string pattern, string targetStateName, Action endpointbuildAction = null) + // where TTransition : Transition> + // => builder.AddHttpPostTransition(pattern, targetStateName, b => b.AddTransitionEvents>(), endpointbuildAction); + //#endregion } } \ No newline at end of file diff --git a/Extensions/Stateflows.Extensions.PlantUml/Classes/ActivityPlantUmlGenerator.cs b/Extensions/Stateflows.Extensions.PlantUml/Classes/ActivityPlantUmlGenerator.cs index bb3651bc..e445fb2d 100644 --- a/Extensions/Stateflows.Extensions.PlantUml/Classes/ActivityPlantUmlGenerator.cs +++ b/Extensions/Stateflows.Extensions.PlantUml/Classes/ActivityPlantUmlGenerator.cs @@ -1,10 +1,9 @@ using System.Linq; using System.Text; using System.Collections.Generic; +using Stateflows.Common; using Stateflows.Activities; using Stateflows.Activities.Inspection.Interfaces; -using Stateflows.Common; -using Stateflows.Common.Extensions; namespace Stateflows.Extensions.PlantUml.Classes { @@ -14,6 +13,13 @@ private static string GetNodeName(INodeInspection node, string parentName) { var nodeName = node.Name.Split('.').Last(); + if (node.Type == NodeType.AcceptEventAction || node.Type == NodeType.TimeEventAction) + { + var parts = node.Name.Split('<'); + var eventPart = parts.Last().Split('.').Last(); + nodeName = string.Join("<", parts.First(), eventPart); + } + if (nodeName == "ExceptionHandler") { nodeName = string.Join("<", node.Name.Split('.').Reverse().Take(2)) + ">"; @@ -62,13 +68,16 @@ private static void GetPlantUml(int indentCount, INodeInspection node, StringBui var source = GetNodeName(transition.Source, parentName); var target = GetNodeName(transition.Target, parentName); - if (transition.TokenName == typeof(Control).GetTokenName()) - { - builder.AppendLine($"{indent}{source} --> {target}"); - } - else + if (transition.TokenName != "NodeReferenceToken") { - builder.AppendLine($"{indent}{source} -->[{transition.TokenName}] {target}"); + if (transition.TokenName == typeof(ControlToken).GetTokenName()) + { + builder.AppendLine($"{indent}{source} --> {target}"); + } + else + { + builder.AppendLine($"{indent}{source} -->[{transition.TokenName}] {target}"); + } } } } diff --git a/Extensions/Stateflows.Extensions.PlantUml/Classes/StateMachineInterceptor.cs b/Extensions/Stateflows.Extensions.PlantUml/Classes/StateMachineInterceptor.cs index b2d0ee9c..8732a300 100644 --- a/Extensions/Stateflows.Extensions.PlantUml/Classes/StateMachineInterceptor.cs +++ b/Extensions/Stateflows.Extensions.PlantUml/Classes/StateMachineInterceptor.cs @@ -12,7 +12,7 @@ internal class StateMachineInterceptor : IStateMachineInterceptor public Task AfterHydrateAsync(IStateMachineActionContext context) => Task.CompletedTask; - public Task AfterProcessEventAsync(IEventContext context) + public Task AfterProcessEventAsync(IEventActionContext context) { if ( context is IEventInspectionContext inspectionContext && @@ -33,7 +33,7 @@ context is IEventInspectionContext inspectionContext && public Task BeforeDehydrateAsync(IStateMachineActionContext context) => Task.CompletedTask; - public Task BeforeProcessEventAsync(IEventContext context) + public Task BeforeProcessEventAsync(IEventActionContext context) => Task.FromResult(true); } } diff --git a/Extensions/Stateflows.Extensions.PlantUml/Events/PlantUmlRequest.cs b/Extensions/Stateflows.Extensions.PlantUml/Events/PlantUmlRequest.cs index e1df2bfd..1ca7e996 100644 --- a/Extensions/Stateflows.Extensions.PlantUml/Events/PlantUmlRequest.cs +++ b/Extensions/Stateflows.Extensions.PlantUml/Events/PlantUmlRequest.cs @@ -3,6 +3,7 @@ namespace Stateflows.Extensions.PlantUml.Events { [DoNotTrace] + [NoImplicitInitialization] public sealed class PlantUmlRequest : Request { public override string Name => nameof(PlantUmlRequest); diff --git a/Locks/Stateflows.Locks.DistributedLock/Stateflows.Locks.DistributedLock.csproj b/Locks/Stateflows.Locks.DistributedLock/Stateflows.Locks.DistributedLock.csproj index 1e383126..ab3e9c1b 100644 --- a/Locks/Stateflows.Locks.DistributedLock/Stateflows.Locks.DistributedLock.csproj +++ b/Locks/Stateflows.Locks.DistributedLock/Stateflows.Locks.DistributedLock.csproj @@ -36,4 +36,8 @@ + + + + diff --git a/Storage/Stateflows.Storage.EntityFrameworkCore/DependencyInjection.cs b/Storage/Stateflows.Storage.EntityFrameworkCore/DependencyInjection.cs index e27908e3..e2a39904 100644 --- a/Storage/Stateflows.Storage.EntityFrameworkCore/DependencyInjection.cs +++ b/Storage/Stateflows.Storage.EntityFrameworkCore/DependencyInjection.cs @@ -6,6 +6,7 @@ using Stateflows.Common.Registration.Interfaces; using Stateflows.Storage.EntityFrameworkCore.Stateflows; using Stateflows.Storage.EntityFrameworkCore.EntityFrameworkCore; +using Microsoft.Extensions.Logging.Abstractions; namespace Stateflows { @@ -20,9 +21,8 @@ public static IStateflowsBuilder AddEntityFrameworkCoreStorage(this } builder.ServiceCollection - //.AddScoped() .AddTransient() - .AddTransient() + .AddDbContext() ; return builder; diff --git a/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/Entities/Context_v1.cs b/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/Entities/Context_v1.cs index 71c9926c..95ea30a0 100644 --- a/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/Entities/Context_v1.cs +++ b/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/Entities/Context_v1.cs @@ -8,6 +8,7 @@ namespace Stateflows.Storage.EntityFrameworkCore.EntityFrameworkCore.Entities [Index(nameof(BehaviorClass))] [Index(nameof(BehaviorId), IsUnique = true)] [Index(nameof(TriggerTime))] + [Index(nameof(TriggerOnStartup))] public class Context_v1 { public int Id { get; set; } @@ -20,13 +21,16 @@ public class Context_v1 public DateTime? TriggerTime { get; set; } + public bool TriggerOnStartup { get; set; } + public string Data { get; set; } - public Context_v1(string behaviorClass, string behaviorId, DateTime? triggerTime, string data) + public Context_v1(string behaviorClass, string behaviorId, DateTime? triggerTime, bool triggerOnStartup, string data) { BehaviorClass = behaviorClass; BehaviorId = behaviorId; TriggerTime = triggerTime; + TriggerOnStartup = triggerOnStartup; Data = data; } } diff --git a/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/Entities/Trace_v1.cs b/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/Entities/Trace_v1.cs deleted file mode 100644 index 36a3db5b..00000000 --- a/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/Entities/Trace_v1.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -namespace Stateflows.Storage.EntityFrameworkCore.EntityFrameworkCore.Entities -{ - [Table("StateflowsTraces_v1")] - [Index(nameof(BehaviorId))] -#pragma warning disable S101 // Types should be named in PascalCase - public class Trace_v1 -#pragma warning restore S101 // Types should be named in PascalCase - { - public int Id { get; set; } - - [StringLength(1024)] - public string BehaviorId { get; set; } - - public DateTime? ExecutionTime { get; set; } - - public string Data { get; set; } - - public Trace_v1(string behaviorId, DateTime? executionTime, string data) - { - BehaviorId = behaviorId; - ExecutionTime = executionTime; - Data = data; - } - } -} diff --git a/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/IStateflowsDbContext_v1.cs b/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/IStateflowsDbContext_v1.cs index 8e6413e3..8ac56522 100644 --- a/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/IStateflowsDbContext_v1.cs +++ b/Storage/Stateflows.Storage.EntityFrameworkCore/EntityFrameworkCore/IStateflowsDbContext_v1.cs @@ -8,7 +8,6 @@ public interface IStateflowsDbContext_v1 #pragma warning restore S101 // Types should be named in PascalCase { DbSet Contexts_v1 { get; set; } - DbSet Traces_v1 { get; set; } Task SaveChangesAsync(CancellationToken cancellationToken = default); } } diff --git a/Storage/Stateflows.Storage.EntityFrameworkCore/Stateflows.Storage.EntityFrameworkCore.csproj b/Storage/Stateflows.Storage.EntityFrameworkCore/Stateflows.Storage.EntityFrameworkCore.csproj index 5ad630f5..0e2e2aa9 100644 --- a/Storage/Stateflows.Storage.EntityFrameworkCore/Stateflows.Storage.EntityFrameworkCore.csproj +++ b/Storage/Stateflows.Storage.EntityFrameworkCore/Stateflows.Storage.EntityFrameworkCore.csproj @@ -47,4 +47,8 @@ + + + + diff --git a/Storage/Stateflows.Storage.EntityFrameworkCore/Stateflows/EntityFrameworkCoreStorage.cs b/Storage/Stateflows.Storage.EntityFrameworkCore/Stateflows/EntityFrameworkCoreStorage.cs index 87e0e284..44856ceb 100644 --- a/Storage/Stateflows.Storage.EntityFrameworkCore/Stateflows/EntityFrameworkCoreStorage.cs +++ b/Storage/Stateflows.Storage.EntityFrameworkCore/Stateflows/EntityFrameworkCoreStorage.cs @@ -3,10 +3,8 @@ using Stateflows.Common.Context; using Stateflows.Common.Utilities; using Stateflows.Common.Interfaces; -using Stateflows.Common.Trace.Models; using Stateflows.Storage.EntityFrameworkCore.Utils; using Stateflows.Storage.EntityFrameworkCore.EntityFrameworkCore; -using Stateflows.Storage.EntityFrameworkCore.EntityFrameworkCore.Entities; namespace Stateflows.Storage.EntityFrameworkCore.Stateflows { @@ -28,13 +26,25 @@ public async Task DehydrateAsync(StateflowsContext context) var contextEntity = await DbContext.Contexts_v1.FindOrCreate(context, true); contextEntity.Data = StateflowsJsonConverter.SerializePolymorphicObject(context); contextEntity.TriggerTime = context.TriggerTime; - if (contextEntity.Id == 0) + contextEntity.TriggerOnStartup = context.TriggerOnStartup; + + if (context.Deleted) { - DbContext.Contexts_v1.Add(contextEntity); + if (contextEntity.Id != 0) + { + DbContext.Contexts_v1.Remove(contextEntity); + } } else { - DbContext.Contexts_v1.Update(contextEntity); + if (contextEntity.Id == 0) + { + DbContext.Contexts_v1.Add(contextEntity); + } + else + { + DbContext.Contexts_v1.Update(contextEntity); + } } await DbContext.SaveChangesAsync(); @@ -60,12 +70,12 @@ public async Task HydrateAsync(BehaviorId behaviorId) Logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(EntityFrameworkCoreStorage).FullName, nameof(HydrateAsync), e.GetType().Name, e.Message); } - result ??= new StateflowsContext() { Id = behaviorId }; + result ??= new StateflowsContext(behaviorId); return result; } - public async Task> GetContextsAsync(IEnumerable behaviorClasses) + public async Task> GetAllContextsAsync(IEnumerable behaviorClasses) { StateflowsContext[] result = Array.Empty(); @@ -77,13 +87,13 @@ public async Task> GetContextsAsync(IEnumerable> GetContextsToTimeTriggerAsync(IEnumerable behaviorClasses) + public Task> GetTimeTriggeredContextsAsync(IEnumerable behaviorClasses) { StateflowsContext[] result = Array.Empty(); @@ -95,48 +105,28 @@ public Task> GetContextsToTimeTriggerAsync(IEnume } catch (Exception e) { - Logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(EntityFrameworkCoreStorage).FullName, nameof(GetContextsToTimeTriggerAsync), e.GetType().Name, e.Message); + Logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(EntityFrameworkCoreStorage).FullName, nameof(GetTimeTriggeredContextsAsync), e.GetType().Name, e.Message); } return Task.FromResult(result as IEnumerable); } - public async Task SaveTraceAsync(BehaviorTrace behaviorTrace) + public Task> GetStartupTriggeredContextsAsync(IEnumerable behaviorClasses) { - try - { - var traceEntity = new Trace_v1( - behaviorTrace.BehaviorId.ToString(), - behaviorTrace.ExecutedAt, - StateflowsJsonConverter.SerializePolymorphicObject(behaviorTrace) - ); - - DbContext.Traces_v1.Add(traceEntity); - - await DbContext.SaveChangesAsync(); - } - catch (Exception e) - { - Logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(EntityFrameworkCoreStorage).FullName, nameof(SaveTraceAsync), e.GetType().Name, e.Message); - } - } - - public async Task> GetTracesAsync(BehaviorId behaviorId) - { - BehaviorTrace[] result = Array.Empty(); + StateflowsContext[] result = Array.Empty(); try { - var contexts = await DbContext.Traces_v1.FindByBehaviorIdAsync(behaviorId); + var contexts = DbContext.Contexts_v1.FindByTriggerOnStartup(behaviorClasses); - result = contexts.Select(c => StateflowsJsonConverter.DeserializeObject(c.Data ?? string.Empty)).ToArray(); + result = contexts.Select(c => StateflowsJsonConverter.DeserializeObject(c.Data ?? string.Empty)).ToArray(); } catch (Exception e) { - Logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(EntityFrameworkCoreStorage).FullName, nameof(GetTracesAsync), e.GetType().Name, e.Message); + Logger.LogError(LogTemplates.ExceptionLogTemplate, typeof(EntityFrameworkCoreStorage).FullName, nameof(GetTimeTriggeredContextsAsync), e.GetType().Name, e.Message); } - return result; + return Task.FromResult(result as IEnumerable); } } } diff --git a/Storage/Stateflows.Storage.EntityFrameworkCore/Utils/DbSetExtensions.cs b/Storage/Stateflows.Storage.EntityFrameworkCore/Utils/DbSetExtensions.cs index da0bb13e..cade09e3 100644 --- a/Storage/Stateflows.Storage.EntityFrameworkCore/Utils/DbSetExtensions.cs +++ b/Storage/Stateflows.Storage.EntityFrameworkCore/Utils/DbSetExtensions.cs @@ -17,7 +17,7 @@ public static async Task FindOrCreate(this DbSet dbSet, query = query.AsNoTracking(); } - return await query.FirstOrDefaultAsync() ?? new Context_v1(id.BehaviorClass.ToString(), id.ToString(), null, ""); + return await query.FirstOrDefaultAsync() ?? new Context_v1(id.BehaviorClass.ToString(), id.ToString(), null, false, ""); } public static async Task> FindByClassesAsync(this DbSet dbSet, IEnumerable behaviorClasses) @@ -58,10 +58,16 @@ public static IEnumerable FindByTriggerTime(this DbSet d .ToArray(); } - public static async Task> FindByBehaviorIdAsync(this DbSet dbSet, BehaviorId behaviorId) - => await dbSet - .Where(c => c.BehaviorId == behaviorId.ToString()) + public static IEnumerable FindByTriggerOnStartup(this DbSet dbSet, IEnumerable behaviorClasses) + { + var behaviorClassStrings = behaviorClasses.Select(bc => bc.ToString()); + return dbSet + .Where(c => + behaviorClassStrings.Contains(c.BehaviorClass) && + c.TriggerOnStartup + ) .AsNoTracking() - .ToArrayAsync(); + .ToArray(); + } } } diff --git a/Storage/Stateflows.Storage.MongoDb/MongoDB/Entities/StateflowsContext_v1.cs b/Storage/Stateflows.Storage.MongoDb/MongoDB/Entities/StateflowsContext_v1.cs index a97cc165..e92a87bc 100644 --- a/Storage/Stateflows.Storage.MongoDb/MongoDB/Entities/StateflowsContext_v1.cs +++ b/Storage/Stateflows.Storage.MongoDb/MongoDB/Entities/StateflowsContext_v1.cs @@ -11,6 +11,7 @@ internal class StateflowsContext_v1 public string BehaviorId { get; set; } public string BehaviorClass { get; set; } public DateTime? TriggerTime { get; set; } + public bool TriggerOnStartup { get; set; } public string Data { get; set; } public StateflowsContext_v1(BehaviorId behaviorId) { diff --git a/Storage/Stateflows.Storage.MongoDb/MongoDB/Entities/StateflowsTrace_v1.cs b/Storage/Stateflows.Storage.MongoDb/MongoDB/Entities/StateflowsTrace_v1.cs deleted file mode 100644 index 5911bf0d..00000000 --- a/Storage/Stateflows.Storage.MongoDb/MongoDB/Entities/StateflowsTrace_v1.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; - -namespace Stateflows.Storage.MongoDB.MongoDB.Entities -{ - internal class StateflowsTrace_v1 - { - [BsonId] - public ObjectId Id { get; set; } - public string BehaviorId { get; set; } - public DateTime ExecutionTime { get; set; } - public string Data { get; set; } - public StateflowsTrace_v1(BehaviorId behaviorId, DateTime executionTime, string data) - { - BehaviorId = behaviorId; - ExecutionTime = executionTime; - Data = data; - } - } -} diff --git a/Storage/Stateflows.Storage.MongoDb/Stateflows/MongoDBStorage.cs b/Storage/Stateflows.Storage.MongoDb/Stateflows/MongoDBStorage.cs index 7ef3bb8b..b5eb8a62 100644 --- a/Storage/Stateflows.Storage.MongoDb/Stateflows/MongoDBStorage.cs +++ b/Storage/Stateflows.Storage.MongoDb/Stateflows/MongoDBStorage.cs @@ -5,9 +5,7 @@ using Stateflows.Common.Context; using Stateflows.Common.Utilities; using Stateflows.Common.Interfaces; -using Stateflows.Common.Trace.Models; using Stateflows.Storage.MongoDB.Utils; -using Stateflows.Storage.MongoDB.MongoDB.Entities; namespace Stateflows.Storage.MongoDB.Stateflows { @@ -23,7 +21,7 @@ public async Task HydrateAsync(BehaviorId behaviorId) { var context = await MongoDBSetExtension.FindOrCreateContextAsync(_mongoDatabase, behaviorId); StateflowsContext result = StateflowsJsonConverter.DeserializeObject(context?.Data ?? string.Empty) - ?? new StateflowsContext() { Id = behaviorId }; + ?? new StateflowsContext(behaviorId); return result; } @@ -33,28 +31,20 @@ public async Task DehydrateAsync(StateflowsContext context) var contextEntity = await _mongoDatabase.FindOrCreateContextAsync(context.Id); contextEntity.Data = StateflowsJsonConverter.SerializePolymorphicObject(context); contextEntity.TriggerTime = context.TriggerTime; + contextEntity.TriggerOnStartup = context.TriggerOnStartup; await _mongoDatabase.UpdateOrInsertContextAsync(contextEntity); } - public async Task> GetContextsAsync(IEnumerable behaviorClasses) + public async Task> GetAllContextsAsync(IEnumerable behaviorClasses) => (await _mongoDatabase.FindContextByBehaviorClassAsync(behaviorClasses)) .Select(e => StateflowsJsonConverter.DeserializeObject(e.Data)); - public async Task> GetContextsToTimeTriggerAsync(IEnumerable behaviorClasses) + public async Task> GetTimeTriggeredContextsAsync(IEnumerable behaviorClasses) => (await _mongoDatabase.FindContextByTimeTriggerAsync(behaviorClasses)) .Select(e => StateflowsJsonConverter.DeserializeObject(e.Data)); - public Task SaveTraceAsync(BehaviorTrace behaviorTrace) - => _mongoDatabase.InsertTraceAsync( - new StateflowsTrace_v1( - behaviorTrace.BehaviorId, - behaviorTrace.ExecutedAt, - StateflowsJsonConverter.SerializePolymorphicObject(behaviorTrace) - ) - ); - - public async Task> GetTracesAsync(BehaviorId behaviorId) - => (await _mongoDatabase.FindTracesAsync(behaviorId)) - .Select(e => StateflowsJsonConverter.DeserializeObject(e.Data)); + public async Task> GetStartupTriggeredContextsAsync(IEnumerable behaviorClasses) + => (await _mongoDatabase.FindContextByStartupTriggerAsync(behaviorClasses)) + .Select(e => StateflowsJsonConverter.DeserializeObject(e.Data)); } } diff --git a/Storage/Stateflows.Storage.MongoDb/Utils/MongoDBSetExtension.cs b/Storage/Stateflows.Storage.MongoDb/Utils/MongoDBSetExtension.cs index 83149783..7912c976 100644 --- a/Storage/Stateflows.Storage.MongoDb/Utils/MongoDBSetExtension.cs +++ b/Storage/Stateflows.Storage.MongoDb/Utils/MongoDBSetExtension.cs @@ -12,12 +12,21 @@ internal static class MongoDBSetExtension public static async Task> FindContextByTimeTriggerAsync(this IMongoDatabase mongoDb, IEnumerable behaviorClasses) { var collection = mongoDb.GetCollection(CollectionNames.StateflowsContexts_v1); - var filter = + var filter = Builders.Filter.In(c => c.BehaviorClass, behaviorClasses.Select(c => c.ToString())) & Builders.Filter.Where(c => c.TriggerTime <= DateTime.Now); return await collection.Find(filter).ToListAsync(); } + public static async Task> FindContextByStartupTriggerAsync(this IMongoDatabase mongoDb, IEnumerable behaviorClasses) + { + var collection = mongoDb.GetCollection(CollectionNames.StateflowsContexts_v1); + var filter = + Builders.Filter.In(c => c.BehaviorClass, behaviorClasses.Select(c => c.ToString())) & + Builders.Filter.Where(c => c.TriggerOnStartup); + return await collection.Find(filter).ToListAsync(); + } + public static async Task> FindContextByBehaviorClassAsync(this IMongoDatabase mongoDb, IEnumerable behaviorClasses) { var collection = mongoDb.GetCollection(CollectionNames.StateflowsContexts_v1); @@ -50,13 +59,5 @@ public static async Task UpdateOrInsertContextAsync(this IMongoDatabase mongoDb, await collection.UpdateOneAsync(filter, updateDef); } } - - public static async Task> FindTracesAsync(this IMongoDatabase mongoDb, BehaviorId id) - => await mongoDb.GetCollection(CollectionNames.StateflowsTraces_v1) - .Find(c => c.BehaviorId == id) - .ToListAsync(); - - public static Task InsertTraceAsync(this IMongoDatabase mongoDb, StateflowsTrace_v1 traceEntity) - => mongoDb.GetCollection(CollectionNames.StateflowsTraces_v1).InsertOneAsync(traceEntity); } } diff --git a/Tests/Activity.IntegrationTests/Classes/Actions/AcceptSomeEventAction.cs b/Tests/Activity.IntegrationTests/Classes/Actions/AcceptSomeEventAction.cs new file mode 100644 index 00000000..23cbbf44 --- /dev/null +++ b/Tests/Activity.IntegrationTests/Classes/Actions/AcceptSomeEventAction.cs @@ -0,0 +1,12 @@ + + +namespace Activity.IntegrationTests.Classes.Actions +{ + internal class AcceptSomeEventAction : IAcceptEventActionNode + { + public Task ExecuteAsync(SomeEvent @event, CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + } +} diff --git a/Tests/Activity.IntegrationTests/Classes/Actions/Action1.cs b/Tests/Activity.IntegrationTests/Classes/Actions/Action1.cs new file mode 100644 index 00000000..cc1e96d7 --- /dev/null +++ b/Tests/Activity.IntegrationTests/Classes/Actions/Action1.cs @@ -0,0 +1,11 @@ + +namespace Activity.IntegrationTests.Classes.Actions +{ + internal class Action1 : IActionNode + { + public Task ExecuteAsync(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + } +} diff --git a/Tests/Activity.IntegrationTests/Classes/Activities/EverythingActivity.cs b/Tests/Activity.IntegrationTests/Classes/Activities/EverythingActivity.cs new file mode 100644 index 00000000..d422d23a --- /dev/null +++ b/Tests/Activity.IntegrationTests/Classes/Activities/EverythingActivity.cs @@ -0,0 +1,1932 @@ +using Activity.IntegrationTests.Classes.Actions; +using Activity.IntegrationTests.Classes.Flow; +using Stateflows.Activities.Registration.Interfaces; +using Stateflows.Activities.Typed; +using Stateflows.Common; + +namespace Activity.IntegrationTests.Classes.Activities +{ + internal class EverythingActivity : IActivity + { + public void Build(IActivityBuilder builder) + { + builder + .AddInitial(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + ) + + .AddInput(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + + .AddOutput() + .AddFinal() + + .AddDataStore("dataStore1", b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + + .AddDataStore(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + + .AddFork("fork1", b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + + .AddFork(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow() + ) + + .AddControlDecision("controlDecision1", b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + ) + + .AddControlDecision(b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + ) + + .AddDecision("intDecision1", b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + .AddElseFlow("action1", b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow(b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow("action1") + .AddElseFlow() + ) + + .AddDecision(b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + .AddElseFlow("action1", b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow(b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow("action1") + .AddElseFlow() + ) + + .AddAction( + "action1", + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddAction( + "action1", + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddAction(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddAcceptEventAction( + "someAction", + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddAcceptEventAction( + "someAction", + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddAcceptEventAction(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddSendEventAction( + "send1", + async c => new SomeEvent(), + async c => new BehaviorId("", "", ""), + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + ) + + .AddTimeEventAction( + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddTimeEventAction( + "someAction", + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddTimeEventAction( + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddTimeEventAction( + "someAction", + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + + .AddStructuredActivity(b => b + .AddInitial(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + ) + .AddInput(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddOutput() + .AddFinal() + .AddDataStore("dataStore1", b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddDataStore(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddFork("fork1", b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddFork(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow() + ) + .AddControlDecision("controlDecision1", b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + ) + .AddControlDecision(b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + ) + .AddDecision("intDecision1", b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + .AddElseFlow("action1", b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow(b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow("action1") + .AddElseFlow() + ) + .AddDecision(b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + .AddElseFlow("action1", b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow(b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow("action1") + .AddElseFlow() + ) + .AddAction( + "action1", + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddAction( + "action1", + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddAction(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddAcceptEventAction( + "someAction", + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddAcceptEventAction( + "someAction", + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddAcceptEventAction(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddSendEventAction( + "send1", + async c => new SomeEvent(), + async c => new BehaviorId("", "", ""), + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + ) + .AddTimeEventAction( + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddTimeEventAction( + "someAction", + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddTimeEventAction( + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddTimeEventAction( + "someAction", + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + ) + + .AddIterativeActivity(b => b + .AddInitial(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + ) + .AddInput(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddOutput() + .AddFinal() + .AddDataStore("dataStore1", b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddDataStore(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddFork("fork1", b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddFork(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow() + ) + .AddControlDecision("controlDecision1", b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + ) + .AddControlDecision(b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + ) + .AddDecision("intDecision1", b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + .AddElseFlow("action1", b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow(b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow("action1") + .AddElseFlow() + ) + .AddDecision(b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + .AddElseFlow("action1", b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow(b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow("action1") + .AddElseFlow() + ) + .AddAction( + "action1", + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddAction( + "action1", + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddAction(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddSendEventAction( + "send1", + async c => new SomeEvent(), + async c => new BehaviorId("", "", ""), + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + ) + ) + + .AddParallelActivity(b => b + .AddInitial(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + ) + .AddInput(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddOutput() + .AddFinal() + .AddDataStore("dataStore1", b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddDataStore(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddFork("fork1", b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddFork(b => b + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow("action1") + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin("join1", b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow("action1") + ) + .AddJoin(b => b + .AddFlow() + ) + .AddJoin(b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow("action1") + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge("merge1", b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow("action1") + ) + .AddMerge(b => b + .AddFlow() + ) + .AddMerge(b => b + .AddFlow() + ) + .AddControlDecision("controlDecision1", b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + ) + .AddControlDecision(b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + ) + .AddDecision("intDecision1", b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddFlow(b => b + .AddGuard(async c => true) + ) + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + .AddElseFlow("action1", b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow(b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow("action1") + .AddElseFlow() + ) + .AddDecision(b => b + .AddFlow("action1", b => b + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow() + .AddFlow("action1") + .AddFlow() + + .AddElseFlow("action1", b => b + .SetWeight(1) + ) + .AddElseFlow(b => b + .SetWeight(1) + ) + .AddElseFlow("action1", b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow(b => b + .SetWeight(1) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddElseFlow("action1") + .AddElseFlow() + ) + .AddAction( + "action1", + async c => { }, + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddAction( + "action1", + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddAction(b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + + .AddFlow("action1", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow(b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddFlow("action1") + .AddFlow("action1") + .AddFlow() + .AddFlow() + + .AddFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + .AddTransformation(async c => c.Token.ToString()) + ) + .AddControlFlow("action2", b => b + .SetWeight(1) + .AddGuard(async c => true) + ) + ) + .AddSendEventAction( + "send1", + async c => new SomeEvent(), + async c => new BehaviorId("", "", ""), + b => b + .AddControlFlow("action1", b => b + .AddGuard(async c => true) + ) + .AddControlFlow(b => b + .AddGuard(async c => true) + ) + .AddControlFlow("action1") + .AddControlFlow() + ) + ) + ; + } + } +} diff --git a/Tests/Activity.IntegrationTests/Classes/Flow/ControlFlow.cs b/Tests/Activity.IntegrationTests/Classes/Flow/ControlFlow.cs new file mode 100644 index 00000000..8b7e3415 --- /dev/null +++ b/Tests/Activity.IntegrationTests/Classes/Flow/ControlFlow.cs @@ -0,0 +1,10 @@ +namespace Activity.IntegrationTests.Classes.Flow +{ + internal class ControlFlow : IControlFlowGuard + { + public Task GuardAsync() + { + return Task.FromResult(true); + } + } +} diff --git a/Tests/Activity.IntegrationTests/Classes/Flow/IntFlow.cs b/Tests/Activity.IntegrationTests/Classes/Flow/IntFlow.cs new file mode 100644 index 00000000..49a1b08e --- /dev/null +++ b/Tests/Activity.IntegrationTests/Classes/Flow/IntFlow.cs @@ -0,0 +1,12 @@ +using Activity.IntegrationTests.Classes.Tokens; + +namespace Activity.IntegrationTests.Classes.Flow +{ + internal class IntFlow : IFlowGuard + { + public Task GuardAsync(int token) + { + return Task.FromResult(true); + } + } +} diff --git a/Tests/Activity.IntegrationTests/Classes/Flow/IntStringFlow.cs b/Tests/Activity.IntegrationTests/Classes/Flow/IntStringFlow.cs new file mode 100644 index 00000000..123b910a --- /dev/null +++ b/Tests/Activity.IntegrationTests/Classes/Flow/IntStringFlow.cs @@ -0,0 +1,10 @@ +namespace Activity.IntegrationTests.Classes.Flow +{ + internal class IntStringFlow : IntFlow, IFlowTransformation + { + public Task TransformAsync(int token) + { + return Task.FromResult(token.ToString()); + } + } +} diff --git a/Tests/Activity.IntegrationTests/Tests/AcceptEvent.cs b/Tests/Activity.IntegrationTests/Tests/AcceptEvent.cs index 87d856c8..b3c96c58 100644 --- a/Tests/Activity.IntegrationTests/Tests/AcceptEvent.cs +++ b/Tests/Activity.IntegrationTests/Tests/AcceptEvent.cs @@ -60,7 +60,6 @@ public async Task AcceptSingleEvent() SendResult result = null; if (ActivityLocator.TryLocateActivity(new ActivityId("acceptSingleEvent", "x"), out var a)) { - await a.InitializeAsync(); await a.SendAsync(new SomeEvent()); result = await a.SendAsync(new SomeEvent()); } @@ -75,7 +74,7 @@ public async Task AcceptMultipleEvents() { if (ActivityLocator.TryLocateActivity(new ActivityId("acceptMultipleEvents", "x"), out var a)) { - await a.InitializeAsync(); + //await a.InitializeAsync(); await a.SendAsync(new SomeEvent()); await a.SendAsync(new SomeEvent()); } diff --git a/Tests/Activity.IntegrationTests/Tests/ActionUnit.cs b/Tests/Activity.IntegrationTests/Tests/ActionUnit.cs index 9563d781..0e790e23 100644 --- a/Tests/Activity.IntegrationTests/Tests/ActionUnit.cs +++ b/Tests/Activity.IntegrationTests/Tests/ActionUnit.cs @@ -1,33 +1,39 @@ +using Microsoft.Extensions.DependencyInjection; using Stateflows.Common; -using Stateflows.Activities.Typed; +using Stateflows.Common.Classes; using StateMachine.IntegrationTests.Utils; namespace Activity.IntegrationTests.Tests { - public class TestedAction : ActionNode + public class TestedAction : IActionNode { private readonly GlobalValue Foo = new("foo"); private readonly SingleInput Input; - public override Task ExecuteAsync() + public Task ExecuteAsync(CancellationToken cancellationToken) { Foo.Set(Input.Token); - ActionUnit.Executed = true; + Input.PassOn(); + + Unit.Executed = true; return Task.CompletedTask; } } - public class TestedFlow : Flow + public class TestedFlow : IFlowGuard { - public override Task GuardAsync() + private readonly GlobalValue Foo = new("foo"); + + public Task GuardAsync(int token) { - return Task.FromResult(true); + Foo.Set(token); + return Task.FromResult(Foo.TryGet(out var value) && value == 42); } } [TestClass] - public class ActionUnit : StateflowsTestClass + public class Unit : StateflowsTestClass { public static bool? Executed = null; @@ -41,35 +47,51 @@ public override void Cleanup() protected override void InitializeStateflows(IStateflowsBuilder builder) { - builder.AddActivities(b => b - .AddActivity("unit", b => b - .AddInitial(b => b - .AddControlFlow("generate") - ) - .AddAction( - "generate", - async c => c.Output(42), - b => b.AddFlow() - ) - .AddAction() - ) - ); + // Registering activity also registers all of its node and flow classes; + // yet, tested classes can be registered manually + builder.ServiceCollection + .AddTransient() + .AddTransient() + ; } [TestMethod] public async Task ActionUnitTest() { - var cradle = SetupCradle() - .AddInputToken(42) - .Build(); + // Use InputTokens static class to add tokens to be used by tested action class + InputTokens.Add(42); + + // Use DI to obtain tested action class instance + var action = ServiceProvider.GetRequiredService(); - var results = await cradle.SwingAsync(); + await action.ExecuteAsync(CancellationToken.None); - var isSet = results.TryGetGlobalContextValue("foo", out var value); + // Use ContextValues static class to manage context values before or after running tested code + var isSet = ContextValues.GlobalValues.TryGet("foo", out var value); + + // Use OutputTokens static class to get tokens that are produced by tested action class + var output = OutputTokens.Get().FirstOrDefault(); Assert.IsTrue(isSet); Assert.AreEqual(42, value); + Assert.AreEqual(42, output); Assert.IsTrue(Executed); } + + [TestMethod] + public async Task FlowUnitTest() + { + // Use DI to obtain tested flow class instance + var flow = ServiceProvider.GetRequiredService(); + + var result = await flow.GuardAsync(42); + + // Use ContextValues static class to manage context values before or after running tested code + var isSet = ContextValues.GlobalValues.TryGet("foo", out var value); + + Assert.IsTrue(isSet); + Assert.AreEqual(42, value); + Assert.IsTrue(result); + } } } \ No newline at end of file diff --git a/Tests/Activity.IntegrationTests/Tests/Context.cs b/Tests/Activity.IntegrationTests/Tests/Context.cs index 02efbd63..a3376839 100644 --- a/Tests/Activity.IntegrationTests/Tests/Context.cs +++ b/Tests/Activity.IntegrationTests/Tests/Context.cs @@ -1,4 +1,5 @@ using Stateflows.Activities.Context.Interfaces; +using Stateflows.Common; using StateMachine.IntegrationTests.Utils; namespace Activity.IntegrationTests.Tests @@ -68,7 +69,7 @@ public async Task FlowContext() { if (ActivityLocator.TryLocateActivity(new ActivityId("flow", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsFalse(Activated1); diff --git a/Tests/Activity.IntegrationTests/Tests/DataStore.cs b/Tests/Activity.IntegrationTests/Tests/DataStore.cs index 18fc68ca..f4982982 100644 --- a/Tests/Activity.IntegrationTests/Tests/DataStore.cs +++ b/Tests/Activity.IntegrationTests/Tests/DataStore.cs @@ -51,7 +51,7 @@ public async Task DataStored() { if (ActivityLocator.TryLocateActivity(new ActivityId("dataStore", "x"), out var a)) { - await a.InitializeAsync(); + //await a.InitializeAsync(); await a.SendAsync(new SomeEvent()); await a.SendAsync(new SomeEvent()); await a.SendAsync(new SomeEvent()); diff --git a/Tests/Activity.IntegrationTests/Tests/Decision.cs b/Tests/Activity.IntegrationTests/Tests/Decision.cs index 5bac90e6..b3e7c75c 100644 --- a/Tests/Activity.IntegrationTests/Tests/Decision.cs +++ b/Tests/Activity.IntegrationTests/Tests/Decision.cs @@ -123,7 +123,21 @@ public async Task TokenDecision() { if (ActivityLocator.TryLocateActivity(new ActivityId("tokensDecision", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); + } + + Assert.AreEqual(1, ExecutionCount1); + Assert.AreEqual(5, TokenCount1); + Assert.AreEqual(1, ExecutionCount2); + Assert.AreEqual(5, TokenCount2); + } + + [TestMethod] + public async Task MultipleTokenDecision() + { + if (ActivityLocator.TryLocateActivity(new ActivityId("multipleTokensDecision", "x"), out var a)) + { + await a.ExecuteAsync(); } Assert.AreEqual(1, ExecutionCount1); @@ -151,7 +165,7 @@ public async Task ControlDecision() { if (ActivityLocator.TryLocateActivity(new ActivityId("controlDecision", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Execution1); diff --git a/Tests/Activity.IntegrationTests/Tests/Exceptions.cs b/Tests/Activity.IntegrationTests/Tests/Exceptions.cs index 3f6a89eb..39598934 100644 --- a/Tests/Activity.IntegrationTests/Tests/Exceptions.cs +++ b/Tests/Activity.IntegrationTests/Tests/Exceptions.cs @@ -13,7 +13,7 @@ public class OtherException : Exception public OtherException(string? message) : base(message) { } } - public class Main : StructuredActivityNode + public class Main : IBaseStructuredActivityNode { } @@ -262,7 +262,7 @@ public async Task SpecificExceptionHandled() { if (ActivityLocator.TryLocateActivity(new ActivityId("specific", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed1); @@ -275,7 +275,7 @@ public async Task GenericExceptionHandled() { if (ActivityLocator.TryLocateActivity(new ActivityId("generic", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed1); @@ -288,7 +288,7 @@ public async Task StructuredExceptionHandled() { if (ActivityLocator.TryLocateActivity(new ActivityId("structured", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed1); @@ -302,7 +302,7 @@ public async Task StructuredTypedExceptionHandled() { if (ActivityLocator.TryLocateActivity(new ActivityId("structured-typed", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed1); @@ -316,7 +316,7 @@ public async Task StructuredGuardExceptionHandled() { if (ActivityLocator.TryLocateActivity(new ActivityId("structured-guard", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed1); @@ -331,7 +331,7 @@ public async Task PlainExceptionHandled() { if (ActivityLocator.TryLocateActivity(new ActivityId("plain", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed1); @@ -343,7 +343,7 @@ public async Task PlainSpecificExceptionHandled() { if (ActivityLocator.TryLocateActivity(new ActivityId("plain-specific", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed2); @@ -354,7 +354,7 @@ public async Task PlainGenericExceptionHandled() { if (ActivityLocator.TryLocateActivity(new ActivityId("plain-generic", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed1); @@ -365,7 +365,7 @@ public async Task GuardExceptionHandled() { if (ActivityLocator.TryLocateActivity(new ActivityId("guard", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed1); diff --git a/Tests/Activity.IntegrationTests/Tests/Execution.cs b/Tests/Activity.IntegrationTests/Tests/Execution.cs new file mode 100644 index 00000000..958c6261 --- /dev/null +++ b/Tests/Activity.IntegrationTests/Tests/Execution.cs @@ -0,0 +1,182 @@ +using Stateflows.Common; +using Stateflows.Activities.Typed; +using StateMachine.IntegrationTests.Utils; + +namespace Activity.IntegrationTests.Tests +{ + [TestClass] + public class Execution : StateflowsTestClass + { + public static bool Executed = false; + + [TestInitialize] + public override void Initialize() + => base.Initialize(); + + [TestCleanup] + public override void Cleanup() + => base.Cleanup(); + + protected override void InitializeStateflows(IStateflowsBuilder builder) + { + builder + .AddActivities(b => b + .AddActivity("simple", b => b + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAction( + "main", + async c => Executed = true, + b => b.AddControlFlow() + ) + .AddFinal() + ) + .AddActivity("output", b => b + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAction( + "main", + async c => + { + Executed = true; + c.Output(42); + }, + b => b + .AddFlow() + .AddControlFlow() + ) + .AddOutput() + .AddFinal() + ) + .AddActivity("initialized", b => b + .AddInitializer(async c => true) + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAction( + "main", + async c => Executed = true, + b => b.AddControlFlow() + ) + .AddFinal() + ) + .AddActivity("interactive", b => b + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAcceptEventAction( + async c => { }, + b => b.AddControlFlow("main") + ) + .AddAction( + "main", + async c => Executed = true, + b => b.AddControlFlow() + ) + .AddFinal() + ) + ) + ; + } + + [TestMethod] + public async Task SimpleExecutionOK() + { + var initialized = false; + var finalized = false; + Executed = false; + + if (ActivityLocator.TryLocateActivity(new ActivityId("simple", "x"), out var a)) + { + initialized = (await a.ExecuteAsync()).Status == EventStatus.Initialized; + finalized = (await a.GetStatusAsync()).Response.BehaviorStatus == BehaviorStatus.Finalized; + } + + Assert.IsTrue(initialized); + Assert.IsTrue(finalized); + Assert.IsTrue(Executed); + } + + [TestMethod] + public async Task SimpleExecutionFails() + { + var initialized = false; + var finalized = false; + Executed = false; + + if (ActivityLocator.TryLocateActivity(new ActivityId("simple", "x"), out var a)) + { + await a.SendAsync(new Initialize()); + Executed = false; + initialized = (await a.ExecuteAsync()).Status == EventStatus.Initialized; + finalized = (await a.GetStatusAsync()).Response.BehaviorStatus == BehaviorStatus.Finalized; + } + + Assert.IsFalse(initialized); + Assert.IsTrue(finalized); + Assert.IsFalse(Executed); + } + + [TestMethod] + public async Task OutputExecutionOK() + { + var initialized = false; + var finalized = false; + var outputAvailable = false; + var output = 0; + Executed = false; + + if (ActivityLocator.TryLocateActivity(new ActivityId("output", "x"), out var a)) + { + var result = await a.ExecuteAsync(); + outputAvailable = result.Response.TryGetOutputTokenOfType(out output); + initialized = result.Status == EventStatus.Initialized; + finalized = (await a.GetStatusAsync()).Response.BehaviorStatus == BehaviorStatus.Finalized; + } + + Assert.IsTrue(initialized); + Assert.IsTrue(finalized); + Assert.IsTrue(Executed); + Assert.IsTrue(outputAvailable); + Assert.AreEqual(42, output); + } + + [TestMethod] + public async Task InitializedExecutionOK() + { + var initialized = false; + var finalized = false; + Executed = false; + + if (ActivityLocator.TryLocateActivity(new ActivityId("initialized", "x"), out var a)) + { + initialized = (await a.ExecuteAsync(new SomeEvent())).Status == EventStatus.Initialized; + finalized = (await a.GetStatusAsync()).Response.BehaviorStatus == BehaviorStatus.Finalized; + } + + Assert.IsTrue(initialized); + Assert.IsTrue(finalized); + Assert.IsTrue(Executed); + } + + [TestMethod] + public async Task InteractiveExecutionFailed() + { + var executed = false; + var initialized = false; + Executed = false; + + if (ActivityLocator.TryLocateActivity(new ActivityId("interactive", "x"), out var a)) + { + executed = (await a.ExecuteAsync()).Status == EventStatus.NotInitialized; + initialized = (await a.GetStatusAsync()).Response.BehaviorStatus == BehaviorStatus.Initialized; + } + + Assert.IsFalse(executed); + Assert.IsTrue(initialized); + Assert.IsFalse(Executed); + } + } +} \ No newline at end of file diff --git a/Tests/Activity.IntegrationTests/Tests/Finalization.cs b/Tests/Activity.IntegrationTests/Tests/Finalization.cs new file mode 100644 index 00000000..c0ecf071 --- /dev/null +++ b/Tests/Activity.IntegrationTests/Tests/Finalization.cs @@ -0,0 +1,49 @@ +using Stateflows.Common; +using Stateflows.Activities.Typed; +using StateMachine.IntegrationTests.Utils; + +namespace Activity.IntegrationTests.Tests +{ + + [TestClass] + public class Finalization : StateflowsTestClass + { + [TestInitialize] + public override void Initialize() + => base.Initialize(); + + [TestCleanup] + public override void Cleanup() + => base.Cleanup(); + + protected override void InitializeStateflows(IStateflowsBuilder builder) + { + builder + .AddActivities(b => b + .AddActivity("simple", b => b + .AddInitial(b => b + .AddControlFlow() + ) + .AddFinal() + ) + ) + ; + } + + [TestMethod] + public async Task SimpleFinalization() + { + var initialized = false; + var finalized = false; + + if (ActivityLocator.TryLocateActivity(new ActivityId("simple", "x"), out var a)) + { + initialized = (await a.SendAsync(new Initialize())).Status == EventStatus.Initialized; + finalized = (await a.GetStatusAsync()).Response.BehaviorStatus == BehaviorStatus.Finalized; + } + + Assert.IsTrue(initialized); + Assert.IsTrue(finalized); + } + } +} \ No newline at end of file diff --git a/Tests/Activity.IntegrationTests/Tests/Fork.cs b/Tests/Activity.IntegrationTests/Tests/Fork.cs index 7dff6982..11d105b5 100644 --- a/Tests/Activity.IntegrationTests/Tests/Fork.cs +++ b/Tests/Activity.IntegrationTests/Tests/Fork.cs @@ -46,7 +46,7 @@ public async Task FlowForked() { if (ActivityLocator.TryLocateActivity(new ActivityId("fork", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Execution1); diff --git a/Tests/Activity.IntegrationTests/Tests/Initialization.cs b/Tests/Activity.IntegrationTests/Tests/Initialization.cs index 678abc36..7ac39ec1 100644 --- a/Tests/Activity.IntegrationTests/Tests/Initialization.cs +++ b/Tests/Activity.IntegrationTests/Tests/Initialization.cs @@ -1,9 +1,11 @@ using Stateflows.Common; using StateMachine.IntegrationTests.Utils; +using Stateflows.Activities.Typed; +using Stateflows.Activities.Context.Interfaces; namespace Activity.IntegrationTests.Tests { - public class ValueInitializationRequest : InitializationRequest + public class ValueInitializationRequest : Event { public string Value { get; set; } = String.Empty; } @@ -29,7 +31,7 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) builder .AddActivities(b => b .AddActivity("simple", b => b - .AddOnInitialize(async c => + .AddDefaultInitializer(async c => { Initialized = true; @@ -42,7 +44,7 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) ) .AddActivity("auto", b => b - .AddOnInitialize(async c => + .AddDefaultInitializer(async c => { Initialized = true; @@ -56,9 +58,9 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) ) .AddActivity("value", b => b - .AddOnInitialize(async c => + .AddInitializer(async c => { - c.Activity.Values.Set("foo", c.InitializationRequest.Value); + c.Activity.Values.Set("foo", c.InitializationEvent.Value); return true; }) @@ -74,7 +76,6 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) }) ) ) - .AddAutoInitialization(new ActivityClass("auto")) ; } @@ -85,8 +86,8 @@ public async Task SimpleInitialization() if (ActivityLocator.TryLocateActivity(new ActivityId("simple", "x"), out var a)) { - var result = await a.InitializeAsync(); - initialized = result.Response.InitializationSuccessful; + var result = await a.SendAsync(new Initialize()); + initialized = result.Status == EventStatus.Initialized; } Assert.IsTrue(initialized); @@ -94,38 +95,6 @@ public async Task SimpleInitialization() Assert.IsTrue(Executed); } - [TestMethod] - public async Task AutoInitialization() - { - EventStatus status = EventStatus.NotConsumed; - - if (ActivityLocator.TryLocateActivity(new ActivityId("auto", "x"), out var a)) - { - status = (await a.SendAsync(new SomeEvent())).Status; - } - - Assert.AreEqual(EventStatus.Consumed, status); - Assert.IsTrue(Initialized); - Assert.IsTrue(Executed); - Assert.IsTrue(Accepted); - } - - [TestMethod] - public async Task NoAutoInitialization() - { - EventStatus status = EventStatus.NotConsumed; - - if (ActivityLocator.TryLocateActivity(new ActivityId("simple", "x"), out var a)) - { - status = (await a.SendAsync(new SomeEvent())).Status; - } - - Assert.AreEqual(EventStatus.Rejected, status); - Assert.IsFalse(Initialized); - Assert.IsFalse(Executed); - Assert.IsFalse(Accepted); - } - [TestMethod] public async Task ValueInitialization() { @@ -133,7 +102,7 @@ public async Task ValueInitialization() if (ActivityLocator.TryLocateActivity(new ActivityId("value", "x"), out var a)) { - initialized = (await a.InitializeAsync(new ValueInitializationRequest() { Value = "bar" })).Response.InitializationSuccessful; + initialized = (await a.SendAsync(new ValueInitializationRequest() { Value = "bar" })).Status == EventStatus.Initialized; } Assert.IsTrue(initialized); diff --git a/Tests/Activity.IntegrationTests/Tests/Iterative.cs b/Tests/Activity.IntegrationTests/Tests/Iterative.cs index f6858ba8..531e9220 100644 --- a/Tests/Activity.IntegrationTests/Tests/Iterative.cs +++ b/Tests/Activity.IntegrationTests/Tests/Iterative.cs @@ -51,7 +51,7 @@ public async Task BasicIterativeActivity() { if (ActivityLocator.TryLocateActivity(new ActivityId("iterative", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.AreEqual(20, ExecutionCounter); diff --git a/Tests/Activity.IntegrationTests/Tests/Join.cs b/Tests/Activity.IntegrationTests/Tests/Join.cs index e25482c9..7f136fac 100644 --- a/Tests/Activity.IntegrationTests/Tests/Join.cs +++ b/Tests/Activity.IntegrationTests/Tests/Join.cs @@ -52,7 +52,7 @@ public async Task FlowsJoined() { if (ActivityLocator.TryLocateActivity(new ActivityId("join", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.AreEqual(1, ExecutionCount); diff --git a/Tests/Activity.IntegrationTests/Tests/Merge.cs b/Tests/Activity.IntegrationTests/Tests/Merge.cs index 4d98a02c..eacee751 100644 --- a/Tests/Activity.IntegrationTests/Tests/Merge.cs +++ b/Tests/Activity.IntegrationTests/Tests/Merge.cs @@ -52,7 +52,7 @@ public async Task FlowsMerged() { if (ActivityLocator.TryLocateActivity(new ActivityId("merge", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.AreEqual(2, ExecutionCount); diff --git a/Tests/Activity.IntegrationTests/Tests/Output.cs b/Tests/Activity.IntegrationTests/Tests/Output.cs index 7e759622..9272dcaa 100644 --- a/Tests/Activity.IntegrationTests/Tests/Output.cs +++ b/Tests/Activity.IntegrationTests/Tests/Output.cs @@ -57,7 +57,6 @@ public async Task OutputFromStructuredActivity() { if (ActivityLocator.TryLocateActivity(new ActivityId("structured", "x"), out var a)) { - await a.InitializeAsync(); await a.SendAsync(new SomeEvent()); } diff --git a/Tests/Activity.IntegrationTests/Tests/Parallel.cs b/Tests/Activity.IntegrationTests/Tests/Parallel.cs index 7998c642..880a6ea5 100644 --- a/Tests/Activity.IntegrationTests/Tests/Parallel.cs +++ b/Tests/Activity.IntegrationTests/Tests/Parallel.cs @@ -54,7 +54,7 @@ public async Task BasicParallelActivity() { if (ActivityLocator.TryLocateActivity(new ActivityId("parallel", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.AreEqual(20, ExecutionCounter); diff --git a/Tests/Activity.IntegrationTests/Tests/ServiceScopes.cs b/Tests/Activity.IntegrationTests/Tests/ServiceScopes.cs index 0c197203..6da4864c 100644 --- a/Tests/Activity.IntegrationTests/Tests/ServiceScopes.cs +++ b/Tests/Activity.IntegrationTests/Tests/ServiceScopes.cs @@ -1,9 +1,6 @@ -using Activity.IntegrationTests.Classes.Tokens; using Microsoft.Extensions.DependencyInjection; using Stateflows.Activities.Typed; -using Stateflows.Common; using StateMachine.IntegrationTests.Utils; -using System.Runtime.CompilerServices; namespace Activity.IntegrationTests.Tests { @@ -17,7 +14,7 @@ public Service() public readonly string Value; } - public class ScopeAction1 : ActionNode + public class ScopeAction1 : IActionNode { private readonly Service service; public ScopeAction1(Service service) @@ -25,7 +22,7 @@ public ScopeAction1(Service service) this.service = service; } - public override Task ExecuteAsync() + public Task ExecuteAsync(CancellationToken cancellationToken) { ServiceScopes.Value1 = service.Value; @@ -33,7 +30,7 @@ public override Task ExecuteAsync() } } - public class ScopeAction2 : ActionNode + public class ScopeAction2 : IActionNode { private readonly Service service; public ScopeAction2(Service service) @@ -41,7 +38,7 @@ public ScopeAction2(Service service) this.service = service; } - public override Task ExecuteAsync() + public Task ExecuteAsync(CancellationToken cancellationToken) { ServiceScopes.Value1 = service.Value; @@ -87,7 +84,7 @@ public async Task SeparateScopesOnActions() { if (ActivityLocator.TryLocateActivity(new ActivityId("scopes", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.AreNotEqual(Value1, Value2); diff --git a/Tests/Activity.IntegrationTests/Tests/Structured.cs b/Tests/Activity.IntegrationTests/Tests/Structured.cs index 9ecbbb0b..d2670659 100644 --- a/Tests/Activity.IntegrationTests/Tests/Structured.cs +++ b/Tests/Activity.IntegrationTests/Tests/Structured.cs @@ -101,7 +101,7 @@ public async Task StructuredActivityFinished() { if (ActivityLocator.TryLocateActivity(new ActivityId("structured", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed); @@ -112,7 +112,7 @@ public async Task ParallelActivityFinished() { if (ActivityLocator.TryLocateActivity(new ActivityId("parallel", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed); @@ -124,7 +124,7 @@ public async Task IterativeActivityFinished() { if (ActivityLocator.TryLocateActivity(new ActivityId("iterative", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed); diff --git a/Tests/Activity.IntegrationTests/Tests/TokenIdentity.cs b/Tests/Activity.IntegrationTests/Tests/TokenIdentity.cs index d915eb3e..c2add0eb 100644 --- a/Tests/Activity.IntegrationTests/Tests/TokenIdentity.cs +++ b/Tests/Activity.IntegrationTests/Tests/TokenIdentity.cs @@ -56,7 +56,7 @@ public async Task TokensNotDuplicated() { if (ActivityLocator.TryLocateActivity(new ActivityId("identity", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.AreEqual(10, Count); diff --git a/Tests/Activity.IntegrationTests/Tests/Transformation.cs b/Tests/Activity.IntegrationTests/Tests/Transformation.cs new file mode 100644 index 00000000..79af7271 --- /dev/null +++ b/Tests/Activity.IntegrationTests/Tests/Transformation.cs @@ -0,0 +1,93 @@ +using Stateflows.Activities.Typed; +using StateMachine.IntegrationTests.Utils; + +namespace Activity.IntegrationTests.Tests +{ + public class TransformationFlow : IFlowTransformation, IFlowGuard + { + public Task TransformAsync(int token) + => Task.FromResult(token.ToString()); + + public Task GuardAsync(int token) + => Task.FromResult(token % 2 == 0); + } + + [TestClass] + public class Transformation : StateflowsTestClass + { + private bool Executed = false; + private int Count = 0; + + [TestInitialize] + public override void Initialize() + => base.Initialize(); + + [TestCleanup] + public override void Cleanup() + => base.Cleanup(); + + protected override void InitializeStateflows(IStateflowsBuilder builder) + { + builder + .AddActivities(b => b + .AddActivity("plain", b => b + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAction( + "main", + async c => c.OutputRange(Enumerable.Range(0, 100)), + b => b.AddFlow("check", b => b + .AddTransformation(async c => c.Token.ToString()) + ) + ) + .AddAction("check", async c => + { + Executed = true; + Count = c.GetTokensOfType().Count(); + }) + ) + .AddActivity("typed", b => b + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAction( + "main", + async c => c.OutputRange(Enumerable.Range(0, 100)), + b => b.AddFlow("check") + ) + .AddAction("check", async c => + { + Executed = true; + Count = c.GetTokensOfType().Count(); + }) + ) + ) + ; + } + + [TestMethod] + public async Task PlainTransformation() + { + if (ActivityLocator.TryLocateActivity(new ActivityId("plain", "x"), out var a)) + { + await a.ExecuteAsync(); + } + + Assert.IsTrue(Executed); + Assert.AreEqual(100, Count); + } + + [TestMethod] + public async Task TypedTransformation() + { + if (ActivityLocator.TryLocateActivity(new ActivityId("typed", "x"), out var a)) + { + await a.ExecuteAsync(); + } + + Assert.IsTrue(Executed); + Assert.AreEqual(50, Count); + } + } +} \ No newline at end of file diff --git a/Tests/Activity.IntegrationTests/Tests/Typed.cs b/Tests/Activity.IntegrationTests/Tests/Typed.cs index 7ea12273..ea39fce9 100644 --- a/Tests/Activity.IntegrationTests/Tests/Typed.cs +++ b/Tests/Activity.IntegrationTests/Tests/Typed.cs @@ -5,14 +5,14 @@ namespace Activity.IntegrationTests.Tests { - public class TypedAction : ActionNode + public class TypedAction : IActionNode { public readonly Input someTokens; public readonly Input strings; public readonly GlobalValue value = new("global"); - public override Task ExecuteAsync() + public Task ExecuteAsync(CancellationToken cancellationToken) { Typed.TokenValue = someTokens.First().Foo; @@ -74,7 +74,7 @@ public async Task InputVerification() { if (ActivityLocator.TryLocateActivity(new ActivityId("typed", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed); diff --git a/Tests/Activity.IntegrationTests/Tests/Values.cs b/Tests/Activity.IntegrationTests/Tests/Values.cs index 56a2bcc7..78c95181 100644 --- a/Tests/Activity.IntegrationTests/Tests/Values.cs +++ b/Tests/Activity.IntegrationTests/Tests/Values.cs @@ -4,11 +4,11 @@ namespace Activity.IntegrationTests.Tests { - public class ValueAction : ActionNode + public class ValueAction : IActionNode { internal readonly GlobalValue globalCounter = new("x"); - public override Task ExecuteAsync() + public Task ExecuteAsync(CancellationToken cancellationToken) { globalCounter.Set(42); @@ -54,7 +54,7 @@ public async Task ValuesManagement() { if (ActivityLocator.TryLocateActivity(new ActivityId("values", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed); diff --git a/Tests/Activity.IntegrationTests/Tests/Weight.cs b/Tests/Activity.IntegrationTests/Tests/Weight.cs index 26cb378f..2d1be0d2 100644 --- a/Tests/Activity.IntegrationTests/Tests/Weight.cs +++ b/Tests/Activity.IntegrationTests/Tests/Weight.cs @@ -56,7 +56,7 @@ public async Task OptionalFlow() { if (ActivityLocator.TryLocateActivity(new ActivityId("optional", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsTrue(Executed); @@ -67,7 +67,7 @@ public async Task RequiredFlow() { if (ActivityLocator.TryLocateActivity(new ActivityId("required", "x"), out var a)) { - await a.InitializeAsync(); + await a.ExecuteAsync(); } Assert.IsFalse(Executed); diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/EverythingStateMachine.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/EverythingStateMachine.cs new file mode 100644 index 00000000..4b6d75d0 --- /dev/null +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/EverythingStateMachine.cs @@ -0,0 +1,565 @@ +using Stateflows.StateMachines.Typed; +using Stateflows.StateMachines.Attributes; +using StateMachine.IntegrationTests.Classes.States; +using StateMachine.IntegrationTests.Classes.Transitions; +using Stateflows.StateMachines.Extensions; + +namespace StateMachine.IntegrationTests.Classes.StateMachines +{ + internal class EverythingInitializer : IDefaultInitializer + { + public Task OnInitializeAsync() + { + return Task.FromResult(true); + } + } + internal class SomeInitializer : IInitializer + { + public Task OnInitializeAsync(SomeEvent initializationEvent) + { + return Task.FromResult(true); + } + } + + internal class EverythingFinalizer : IFinalizer + { + public Task OnFinalizeAsync() + { + return Task.CompletedTask; + } + } + + [StateMachineBehavior] + internal class EverythingStateMachine : IStateMachine + { + public void Build(IStateMachineBuilder builder) + { + builder + .AddInitializer() + .AddInitializer(c => true) + .AddInitializer(c => Task.FromResult(true)) + + .AddDefaultInitializer() + .AddDefaultInitializer(c => true) + .AddDefaultInitializer(c => Task.FromResult(true)) + + .AddFinalizer() + .AddFinalizer(c => { }) + .AddFinalizer(c => Task.CompletedTask) + + .AddInitialState(b => b + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + ) + + .AddState("state1", b => b + .AddOnEntry(c => { }) + .AddOnEntry(async c => { }) + + .AddOnExit(c => { }) + .AddOnExit(async c => { }) + + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + + .AddTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInternalTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseInternalTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddDefaultTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseDefaultTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + ) + + .AddState(b => b + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + + .AddTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInternalTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseInternalTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddDefaultTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseDefaultTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + ) + + .AddCompositeState(b => b + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + + .AddTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInternalTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseInternalTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddDefaultTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseDefaultTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInitialState(b => b + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + ) + + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + + .AddTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInternalTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseInternalTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddDefaultTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseDefaultTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddFinalState() + + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + + .AddTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInternalTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseInternalTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddDefaultTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseDefaultTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + ) + + .AddCompositeState("composite", b => b + .AddOnEntry(c => { }) + .AddOnEntry(async c => { }) + + .AddOnExit(c => { }) + .AddOnExit(async c => { }) + + .AddOnInitialize(c => { }) + .AddOnInitialize(async c => { }) + + .AddOnFinalize(c => { }) + .AddOnFinalize(async c => { }) + + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + + .AddTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInternalTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseInternalTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddDefaultTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseDefaultTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInitialState(b => b + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + ) + + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + + .AddTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInternalTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseInternalTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddDefaultTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseDefaultTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddFinalState() + + .AddTransition() + .AddElseTransition() + + .AddInternalTransition() + .AddElseInternalTransition() + + .AddDefaultTransition() + .AddElseDefaultTransition() + + .AddTransition(State.Name) + .AddElseTransition(State.Name) + + .AddDefaultTransition(State.Name) + .AddElseDefaultTransition(State.Name) + + .AddTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddInternalTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseInternalTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddDefaultTransition(b => b + .AddGuard(c => true) + .AddGuard(c => Task.FromResult(true)) + + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + + .AddElseDefaultTransition(b => b + .AddEffect(c => { }) + .AddEffect(c => Task.CompletedTask) + ) + ) + .AddState(); + } + } +} diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/StateMachine1.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/StateMachine1.cs index 8aa7a18d..ac9e1469 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/StateMachine1.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/StateMachine1.cs @@ -5,8 +5,27 @@ namespace StateMachine.IntegrationTests.Classes.StateMachines { + internal class Initializer1 : IDefaultInitializer + { + public Task OnInitializeAsync() + { + StateMachine1.InitializeFired = true; + + return Task.FromResult(true); + } + } + internal class Finalizer1 : IFinalizer + { + public Task OnFinalizeAsync() + { + StateMachine1.FinalizeFired = true; + + return Task.CompletedTask; + } + } + [StateMachineBehavior] - internal class StateMachine1 : Stateflows.StateMachines.StateMachine + internal class StateMachine1 : IStateMachine { public static bool InitializeFired = false; @@ -18,21 +37,11 @@ public static void Reset() FinalizeFired = false; } - public override Task OnInitializeAsync() - { - InitializeFired = true; - return Task.FromResult(true); - } - - public override Task OnFinalizeAsync() - { - FinalizeFired = true; - return Task.CompletedTask; - } - - public override void Build(ITypedStateMachineBuilder builder) + public void Build(IStateMachineBuilder builder) { builder + .AddDefaultInitializer() + .AddFinalizer() .AddInitialState(b => b .AddTransition() ) diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/TypedStateMachine.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/TypedStateMachine.cs new file mode 100644 index 00000000..c953a796 --- /dev/null +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/TypedStateMachine.cs @@ -0,0 +1,108 @@ +using Stateflows.StateMachines.Typed; +using Stateflows.StateMachines.Attributes; +using Stateflows.StateMachines.Context.Interfaces; + +namespace StateMachine.IntegrationTests.Classes.StateMachines +{ + internal class TypedOtherInitializer : IInitializer + { + public Task OnInitializeAsync(OtherEvent initializationEvent) + { + return Task.FromResult(true); + } + } + + internal class TypedDefaultInitializer : IDefaultInitializer + { + public Task OnInitializeAsync() + { + return Task.FromResult(true); + } + } + + internal class TypedFinalizer : IFinalizer + { + public Task OnFinalizeAsync() + { + return Task.CompletedTask; + } + } + + internal class StateA : IStateEntry, IStateExit + { + private readonly IStateContext stateContext; + private readonly IStateMachineContext stateMachineContext; + private readonly IExecutionContext executionContext; + public StateA(IStateContext stateContext, IStateMachineContext stateMachineContext, IExecutionContext executionContext) + { + this.stateContext = stateContext; + this.stateMachineContext = stateMachineContext; + this.executionContext = executionContext; + } + + public Task OnEntryAsync() + { + return Task.CompletedTask; + } + + public Task OnExitAsync() + { + return Task.CompletedTask; + } + } + + internal class StateB : IStateEntry + { + public Task OnEntryAsync() + { + return Task.CompletedTask; + } + } + + internal class SomeTransition : ITransitionGuard, ITransitionEffect + { + private readonly IStateMachineContext stateMachineContext; + private readonly ITransitionContext transitionContext; + private readonly IExecutionContext executionContext; + + public SomeTransition( + IStateMachineContext stateMachineContext, + ITransitionContext transitionContext, + IExecutionContext executionContext + ) + { + this.stateMachineContext = stateMachineContext; + this.transitionContext = transitionContext; + this.executionContext = executionContext; + } + public Task GuardAsync(SomeEvent @event) + { + return Task.FromResult(true); + } + + public Task EffectAsync(SomeEvent @event) + { + return Task.CompletedTask; + } + } + + [StateMachineBehavior] + internal class TypedStateMachine : IStateMachine + { + public void Build(IStateMachineBuilder builder) + { + builder + .AddInitializer() + //.AddDefaultInitializer() + .AddFinalizer() + + .AddInitialState(b => b + .AddTransition() + ) + .AddState(b => b + .AddTransition() + ) + .AddState(); + } + } +} diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/TypedValue.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/TypedValue.cs index b90e85bf..53be1a53 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/TypedValue.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/TypedValue.cs @@ -2,17 +2,16 @@ namespace StateMachine.IntegrationTests.Classes.StateMachines { - public class TypedValue : StateMachine + public class TypedValue : IStateMachine { - public override async Task OnInitializeAsync(ValueInitializationRequest initializationRequest) - { - Context.StateMachine.Values.Set("foo", initializationRequest.Value); - - return true; - } - - public override void Build(ITypedStateMachineBuilder builder) + public void Build(IStateMachineBuilder builder) => builder + .AddInitializer(c => + { + c.StateMachine.Values.Set("foo", c.InitializationEvent.Value); + + return true; + }) .AddInitialState("state1", b => b .AddOnEntry(c => { diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/ValuesStateMachine.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/ValuesStateMachine.cs index 6b1054ba..f67bf571 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/ValuesStateMachine.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/StateMachines/ValuesStateMachine.cs @@ -4,9 +4,9 @@ namespace StateMachine.IntegrationTests.Classes.StateMachines { - public class ValuesStateMachine : Stateflows.StateMachines.StateMachine + public class ValuesStateMachine : IStateMachine { - public override void Build(ITypedStateMachineBuilder builder) + public void Build(IStateMachineBuilder builder) => builder .AddInitialState(b => b .AddDefaultTransition() diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State1.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State1.cs index b6e98bc9..6d9cc490 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State1.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State1.cs @@ -1,26 +1,38 @@ -namespace StateMachine.IntegrationTests.Classes.States +using Stateflows.StateMachines.Context.Interfaces; + +namespace StateMachine.IntegrationTests.Classes.States { - internal class State1 : State + internal class State1 : IStateEntry, IStateExit { public static bool EntryFired = false; public static bool ExitFired = false; + private readonly IStateContext stateContext; + private readonly IStateMachineContext stateMachineContext; + private readonly IExecutionContext executionContext; + public State1(IStateContext stateContext, IStateMachineContext stateMachineContext, IExecutionContext executionContext) + { + this.stateContext = stateContext; + this.stateMachineContext = stateMachineContext; + this.executionContext = executionContext; + } + public static void Reset() { EntryFired = false; ExitFired = false; } - public override Task OnEntryAsync() + public Task OnEntryAsync() { - EntryFired = Context != null && Context.StateMachine.Id.Instance != null; + EntryFired = stateContext != null && stateMachineContext?.Id.Instance != null && executionContext != null; return Task.CompletedTask; } - public override Task OnExitAsync() + public Task OnExitAsync() { - ExitFired = Context != null && Context.StateMachine.Id.Instance != null; + ExitFired = stateContext != null && stateMachineContext?.Id.Instance != null && executionContext != null; return Task.CompletedTask; } } diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State2.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State2.cs index ba46b592..84e04a08 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State2.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State2.cs @@ -1,26 +1,36 @@ -namespace StateMachine.IntegrationTests.Classes.States +using Stateflows.StateMachines.Context.Interfaces; + +namespace StateMachine.IntegrationTests.Classes.States { - internal class State2 : State + internal class State2 : IStateEntry, IStateExit { public static bool EntryFired = false; public static bool ExitFired = false; + private readonly IStateContext stateContext; + private readonly IStateMachineContext stateMachineContext; + public State2(IStateContext stateContext, IStateMachineContext stateMachineContext) + { + this.stateContext = stateContext; + this.stateMachineContext = stateMachineContext; + } + public static void Reset() { EntryFired = false; ExitFired = false; } - public override Task OnEntryAsync() + public Task OnEntryAsync() { - EntryFired = Context != null && Context.StateMachine.Id.Instance != null; + EntryFired = stateContext != null && stateMachineContext?.Id.Instance != null; return Task.CompletedTask; } - public override Task OnExitAsync() + public Task OnExitAsync() { - ExitFired = Context != null && Context.StateMachine.Id.Instance != null; + ExitFired = stateContext != null && stateMachineContext?.Id.Instance != null; return Task.CompletedTask; } } diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State3.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State3.cs new file mode 100644 index 00000000..59c7dd54 --- /dev/null +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/State3.cs @@ -0,0 +1,20 @@ +namespace StateMachine.IntegrationTests.Classes.States +{ + internal class State3 : ICompositeStateInitialization, IStateEntry, IStateExit + { + public Task OnEntryAsync() + { + return Task.CompletedTask; + } + + public Task OnExitAsync() + { + return Task.CompletedTask; + } + + public Task OnInitializeAsync() + { + return Task.CompletedTask; + } + } +} diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/ValueState1.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/ValueState1.cs index 5264c688..8e19b609 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/ValueState1.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/ValueState1.cs @@ -2,11 +2,11 @@ namespace StateMachine.IntegrationTests.Classes.States { - internal class ValueState1 : State + internal class ValueState1 : IStateEntry { private readonly StateValue counter = new("counter"); - public override Task OnEntryAsync() + public Task OnEntryAsync() { if (counter.TryGet(out var c)) { diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/ValueState2.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/ValueState2.cs index b436da1b..2c66571f 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/ValueState2.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/States/ValueState2.cs @@ -1,8 +1,8 @@ namespace StateMachine.IntegrationTests.Classes.States { - internal class ValueState2 : State + internal class ValueState2 : IStateEntry { - public override Task OnEntryAsync() + public Task OnEntryAsync() { return Task.CompletedTask; } diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/GuardedTransition.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/GuardedTransition.cs index 921a8d51..522b7915 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/GuardedTransition.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/GuardedTransition.cs @@ -1,16 +1,23 @@ using Stateflows.Common; -using Stateflows.StateMachines.Events; namespace StateMachine.IntegrationTests.Classes.Transitions { - internal class GuardedTransition : Transition + internal class GuardedTransition : IDefaultTransitionGuard { private readonly GlobalValue counter = new("counter"); - public override Task GuardAsync() + public Task GuardAsync() { var result = counter.TryGet(out var c) && c == 1; return Task.FromResult(result); } } + + internal class EffectedTransition : IDefaultTransitionEffect + { + public Task EffectAsync() + { + return Task.CompletedTask; + } + } } diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/InternalTransition.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/InternalTransition.cs index a37fa70c..a921badd 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/InternalTransition.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/InternalTransition.cs @@ -2,11 +2,11 @@ namespace StateMachine.IntegrationTests.Classes.Transitions { - internal class InternalTransition : Transition + internal class InternalTransition : ITransitionEffect { private readonly GlobalValue counter = new("counter"); - public override Task EffectAsync() + public Task EffectAsync(SomeEvent @event) { if (!counter.TryGet(out var c)) { diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/SomeEventTransition.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/SomeEventTransition.cs index f435802e..b9d0b2e4 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/SomeEventTransition.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/SomeEventTransition.cs @@ -1,26 +1,50 @@ -namespace StateMachine.IntegrationTests.Classes.Transitions +using Stateflows.StateMachines.Context.Interfaces; + +namespace StateMachine.IntegrationTests.Classes.Transitions { - internal class SomeEventTransition : Transition + internal class SomeEventTransition : ITransitionGuard, ITransitionEffect { public static bool GuardFired = false; public static bool EffectFired = false; + private readonly IStateMachineContext stateMachineContext; + private readonly ITransitionContext transitionContext; + private readonly IExecutionContext executionContext; + public SomeEventTransition( + IStateMachineContext stateMachineContext, + ITransitionContext transitionContext, + IExecutionContext executionContext + ) + { + this.stateMachineContext = stateMachineContext; + this.transitionContext = transitionContext; + this.executionContext = executionContext; + } + public static void Reset() { GuardFired = false; EffectFired = false; } - public override Task GuardAsync() + public Task GuardAsync(SomeEvent @event) { - GuardFired = Context != null && Context.StateMachine.Id.Instance != null; + GuardFired = + stateMachineContext != null && + transitionContext != null && + executionContext != null && stateMachineContext.Id.Instance != null; + return Task.FromResult(true); } - public override Task EffectAsync() + public Task EffectAsync(SomeEvent @event) { - EffectFired = Context != null && Context.StateMachine.Id.Instance != null; + EffectFired = + stateMachineContext != null && + transitionContext != null && + executionContext != null && stateMachineContext.Id.Instance != null; + return Task.CompletedTask; } } diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/ValueTransition.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/ValueTransition.cs index 8ebb5028..421d9d11 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/ValueTransition.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Classes/Transitions/ValueTransition.cs @@ -1,12 +1,10 @@ -using Stateflows.StateMachines.Events; - -namespace StateMachine.IntegrationTests.Classes.Transitions +namespace StateMachine.IntegrationTests.Classes.Transitions { - internal class ValueTransition : Transition + internal class ValueTransition : IBaseDefaultTransition { private readonly SourceStateValue counter = new("counter"); - public override Task GuardAsync() + public Task GuardAsync() { var result = counter.TryGet(out var c) && c == 1; return Task.FromResult(result); diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Activities.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Activities.cs new file mode 100644 index 00000000..b3e248cc --- /dev/null +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Activities.cs @@ -0,0 +1,164 @@ +using Stateflows.Activities; +using StateMachine.IntegrationTests.Utils; +using Stateflows.Activities.Typed; +using Stateflows.Common; + +namespace StateMachine.IntegrationTests.Tests +{ + public class BoolInit : Event + { + public bool Value { get; set; } + } + + [TestClass] + public class Activities : StateflowsTestClass + { + public bool GuardRun = false; + public bool EffectRun = false; + public bool EntryRun = false; + public bool ExitRun = false; + + [TestInitialize] + public override void Initialize() + => base.Initialize(); + + [TestCleanup] + public override void Cleanup() + => base.Cleanup(); + + protected override void InitializeStateflows(IStateflowsBuilder builder) + { + builder + .AddPlantUml() + .AddStateMachines(b => b + .AddStateMachine("extended", b => b + .AddExecutionSequenceObserver() + .AddInitializer(async c => + { + c.StateMachine.Values.Set("value", c.InitializationEvent.Value); + return true; + }) + .AddInitialState("stateA", b => b + .AddTransition("stateB", b => b + .AddGuardActivity("guard", c => new BoolInit() { Value = c.StateMachine.Values.TryGet("value", out var value) && value }) + .AddEffectActivity("effect") + ) + ) + .AddState("stateB", b => b + .AddOnEntryActivity("entry") + .AddOnExitActivity("exit") + ) + ) + ) + .AddActivities(b => b + .AddActivity("guard", b => b + .AddInitializer(async c => + { + c.Activity.Values.Set("value", c.InitializationEvent.Value); + return true; + }) + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAction( + "main", + async c => + { + GuardRun = true; + if (c.Activity.Values.TryGet("value", out var value)) + { + c.Output(value); + } + }, + b => b.AddFlow() + ) + .AddOutput() + ) + .AddActivity("effect", b => b + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAction("main", async c => + { + EffectRun = true; + }) + ) + .AddActivity("entry", b => b + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAction("main", async c => + { + EntryRun = true; + }) + ) + .AddActivity("exit", b => b + .AddInitial(b => b + .AddControlFlow("main") + ) + .AddAction("main", async c => + { + ExitRun = true; + }) + ) + ) + ; + } + + [TestMethod] + public async Task ActivityActions() + { + string currentState1 = ""; + + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("extended", "x"), out var sm)) + { + await sm.SendAsync(new BoolInit() { Value = true }); + + await sm.SendAsync(new SomeEvent()); + + var currentState = (await sm.GetCurrentStateAsync()).Response; + + currentState1 = currentState.StatesStack.First(); + } + + ExecutionSequence.Verify(b => b + .StateEntry("stateA") + .StateExit("stateA") + .StateEntry("stateB") + ); + + Assert.AreEqual("stateB", currentState1); + Assert.AreEqual(true, GuardRun); + Assert.AreEqual(true, EffectRun); + Assert.AreEqual(true, EntryRun); + Assert.AreEqual(false, ExitRun); + } + + [TestMethod] + public async Task ActivityGuard() + { + string currentState1 = ""; + + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("extended", "x"), out var sm)) + { + await sm.SendAsync(new BoolInit() { Value = false }); + + await sm.SendAsync(new SomeEvent()); + + var currentState = (await sm.GetCurrentStateAsync()).Response; + + currentState1 = currentState.StatesStack.First(); + } + + ExecutionSequence.Verify(b => b + .StateEntry("stateA") + ); + + Assert.AreEqual("stateA", currentState1); + Assert.AreEqual(true, GuardRun); + Assert.AreEqual(false, EffectRun); + Assert.AreEqual(false, EntryRun); + Assert.AreEqual(false, ExitRun); + } + } +} \ No newline at end of file diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Behaviors.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Behaviors.cs index 178bf7fc..cca6a762 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Behaviors.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Behaviors.cs @@ -1,6 +1,5 @@ using Stateflows.Common; using Stateflows.Activities; -using Stateflows.StateMachines.Sync; using StateMachine.IntegrationTests.Utils; namespace StateMachine.IntegrationTests.Tests @@ -78,7 +77,7 @@ public async Task SimpleSubmachine() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("submachine", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + initialized = (await sm.SendAsync(new Initialize())).Status == EventStatus.Initialized; someStatus1 = (await sm.SendAsync(new SomeEvent())).Status; @@ -99,7 +98,7 @@ public async Task SimpleSubmachine() .StateMachineFinalize() ); Assert.IsTrue(initialized); - Assert.AreEqual(EventStatus.Consumed, someStatus1); + Assert.AreEqual(EventStatus.Forwarded, someStatus1); Assert.AreEqual("state2", currentState1); } @@ -112,7 +111,7 @@ public async Task SimpleDoActivity() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("doActivity", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + initialized = (await sm.SendAsync(new Initialize())).Status == EventStatus.Initialized; someStatus1 = (await sm.SendAsync(new SomeEvent())).Status; @@ -121,12 +120,12 @@ public async Task SimpleDoActivity() currentState1 = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); } - ExecutionSequence.Verify(b => b + ExecutionSequence.Verify(b => b .StateEntry("state1") .StateEntry("state2") ); Assert.IsTrue(initialized); - Assert.AreEqual(EventStatus.Consumed, someStatus1); + Assert.AreEqual(EventStatus.Forwarded, someStatus1); Assert.AreEqual(true, eventConsumed); Assert.AreEqual("state2", currentState1); } diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Composite.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Composite.cs index 58e2316b..0c148a74 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Composite.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Composite.cs @@ -1,10 +1,23 @@ using Stateflows.Common; -using Stateflows.StateMachines.Sync; +using Stateflows.StateMachines.Typed; using Stateflows.StateMachines.Events; using StateMachine.IntegrationTests.Utils; +using System.Diagnostics; +using Stateflows.StateMachines.Context.Interfaces; namespace StateMachine.IntegrationTests.Tests { + public class StateA : IBaseState + { + public StateA(IStateMachineContext smContext, ITransitionContext tContext) + { + Debug.WriteLine(smContext.Id.Instance); + } + } + + public class StateB : IBaseState + { } + [TestClass] public class Composite : StateflowsTestClass { @@ -24,6 +37,18 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) { builder .AddStateMachines(b => b + + .AddStateMachine("berlin", b => b + .AddDefaultInitializer(async c => true) + + .AddInitialState(b => b + .AddTransition(State.Name, b => b + .AddGuard(async c => true) + ) + ) + .AddState() + ) + .AddStateMachine("composite", b => b .AddExecutionSequenceObserver() .AddInitialCompositeState("state1", b => b @@ -55,7 +80,7 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) .AddStateMachine("exits", b => b .AddExecutionSequenceObserver() - .AddOnInitialize(c => + .AddDefaultInitializer(c => { ParentStateExited = null; ChildStateExited = null; @@ -89,6 +114,22 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) ; } + + + [TestMethod] + public async Task Berlin() + { + var status = EventStatus.Rejected; + string currentState = ""; + + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("berlin", "x"), out var sm)) + { + status = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 42 })).Status; + + currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); + } + } + [TestMethod] public async Task SelfTransition() { @@ -98,8 +139,6 @@ public async Task SelfTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("composite", "x"), out var sm)) { - await sm.InitializeAsync(); - status = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 42 })).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); @@ -128,8 +167,6 @@ public async Task DefaultTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("default", "x"), out var sm)) { - _ = await sm.InitializeAsync(); - status = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 42 })).Status; currentState = (await sm.GetCurrentStateAsync()).Response; @@ -169,8 +206,6 @@ public async Task LocalExits() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("exits", "x"), out var sm)) { - await sm.InitializeAsync(); - status = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 42 })).Status; currentState = (await sm.GetCurrentStateAsync()).Response; @@ -202,8 +237,6 @@ public async Task SingleInitialization() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("single", "x"), out var sm)) { - await sm.InitializeAsync(); - status = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 42 })).Status; currentState = (await sm.GetCurrentStateAsync()).Response; diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Compound.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Compound.cs index 68bfdb88..5521b8a2 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Compound.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Compound.cs @@ -40,7 +40,7 @@ public async Task CompoundRequestOK() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) { - await sm.InitializeAsync(); + //await sm.InitializeAsync(); var request = new CompoundRequest() { @@ -68,7 +68,7 @@ public async Task CompoundRequestNOK() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) { - await sm.InitializeAsync(); + //await sm.InitializeAsync(); var request = new CompoundRequest() { @@ -97,7 +97,7 @@ public async Task CompoundRequestInvalid() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) { - await sm.InitializeAsync(); + //await sm.InitializeAsync(); var request = new CompoundRequest() { diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Concurrency.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Concurrency.cs index e2637717..99b551f8 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Concurrency.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Concurrency.cs @@ -65,8 +65,8 @@ public async Task TwoConcurrentBehaviors() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("a", "x"), out var a) && StateMachineLocator.TryLocateStateMachine(new StateMachineId("b", "x"), out var b)) { - _ = await a.InitializeAsync(); - _ = await b.InitializeAsync(); + _ = await a.SendAsync(new Initialize()); + _ = await b.SendAsync(new Initialize()); await Task.WhenAll( a.SendAsync(new SomeEvent()), b.SendAsync(new SomeEvent()) @@ -91,8 +91,8 @@ public async Task TwoConcurrentInstances() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("instance", "a"), out var a) && StateMachineLocator.TryLocateStateMachine(new StateMachineId("instance", "b"), out var b)) { - _ = await a.InitializeAsync(); - _ = await b.InitializeAsync(); + _ = await a.SendAsync(new Initialize()); + _ = await b.SendAsync(new Initialize()); await Task.WhenAll( a.SendAsync(new SomeEvent() { DelaySize = 100 }), b.SendAsync(new SomeEvent() { DelaySize = 0 }) diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Context.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Context.cs index 136de62e..03a60219 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Context.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Context.cs @@ -1,3 +1,4 @@ +using Stateflows.Common; using StateMachine.IntegrationTests.Utils; namespace StateMachine.IntegrationTests.Tests @@ -57,7 +58,7 @@ public async Task EnumSerialization() { if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("context", "x"), out var stateMachine)) { - await stateMachine.InitializeAsync(); + await stateMachine.SendAsync(new Initialize()); } Assert.IsTrue(EnumGet); diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Deferral.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Deferral.cs index 0e54cc63..a51f765d 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Deferral.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Deferral.cs @@ -84,7 +84,7 @@ public async Task SimpleDeferral() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("defer", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + initialized = (await sm.SendAsync(new Initialize())).Status == EventStatus.Initialized; otherStatus = (await sm.SendAsync(new OtherEvent())).Status; @@ -110,7 +110,7 @@ public async Task SequenceDeferral() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("sequence", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + initialized = (await sm.SendAsync(new Initialize())).Status == EventStatus.Initialized; otherStatus1 = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 42 })).Status; @@ -139,7 +139,7 @@ public async Task NestedDeferral() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("nested", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + initialized = (await sm.SendAsync(new Initialize())).Status == EventStatus.Initialized; otherStatus1 = (await sm.SendAsync(new OtherEvent())).Status; diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ElseTransitions.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ElseTransitions.cs index 135da25f..64470122 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ElseTransitions.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ElseTransitions.cs @@ -57,7 +57,7 @@ public async Task ElseFromOneTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("single", "x"), out var sm)) { - await sm.InitializeAsync(); + //await sm.InitializeAsync(); status = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 43 })).Status; @@ -76,7 +76,7 @@ public async Task ElseFromTwoTransitions() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("multiple", "x"), out var sm)) { - await sm.InitializeAsync(); + //await sm.InitializeAsync(); status = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 43 })).Status; diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Exceptions.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Exceptions.cs new file mode 100644 index 00000000..ffac330a --- /dev/null +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Exceptions.cs @@ -0,0 +1,54 @@ +using Stateflows.Common; +using Stateflows.Activities; +using StateMachine.IntegrationTests.Utils; + +namespace StateMachine.IntegrationTests.Tests +{ + [TestClass] + public class Exceptions : StateflowsTestClass + { + public bool eventConsumed = false; + + [TestInitialize] + public override void Initialize() + => base.Initialize(); + + [TestCleanup] + public override void Cleanup() + => base.Cleanup(); + + protected override void InitializeStateflows(IStateflowsBuilder builder) + { + builder + .AddPlantUml() + .AddStateMachines(b => b + .AddStateMachine("uncatched", b => b + .AddInitialState("state1", b => b + .AddOnEntry(c => throw new Exception("example")) + .AddTransition("state2") + ) + .AddState("state2") + ) + ) + ; + } + + [TestMethod] + public async Task Uncatched() + { + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("uncatched", "x"), out var sm)) + { + try + { + await sm.SendAsync(new Initialize()); + } + catch (Exception) + { + throw; + } + } + + Assert.IsTrue(true); + } + } +} \ No newline at end of file diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ExternalTransitions.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ExternalTransitions.cs index ce6a6cc0..995eb20e 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ExternalTransitions.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ExternalTransitions.cs @@ -95,7 +95,7 @@ public async Task NestedToRootTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("nested-to-root", "x"), out var sm)) { - status = (await sm.InitializeAsync()).Status; + status = (await sm.SendAsync(new Initialize())).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); } @@ -116,7 +116,7 @@ public async Task NestedToRootTransition() .StateEntry("state2") ); - Assert.AreEqual(EventStatus.Consumed, status); + Assert.AreEqual(EventStatus.Initialized, status); Assert.AreEqual("state2", currentState); } @@ -128,7 +128,7 @@ public async Task RootToNestedTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("root-to-nested", "x"), out var sm)) { - status = (await sm.InitializeAsync()).Status; + status = (await sm.SendAsync(new Initialize())).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.Last(); } @@ -144,7 +144,7 @@ public async Task RootToNestedTransition() .StateEntry("state2.1.2") ); - Assert.AreEqual(EventStatus.Consumed, status); + Assert.AreEqual(EventStatus.Initialized, status); Assert.AreEqual("state2.1.2", currentState); } @@ -156,7 +156,7 @@ public async Task NestedToNestedTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("nested-to-nested", "x"), out var sm)) { - status = (await sm.InitializeAsync()).Status; + status = (await sm.SendAsync(new Initialize())).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.Last(); } @@ -179,7 +179,7 @@ public async Task NestedToNestedTransition() .StateEntry("state2.1.2") ); - Assert.AreEqual(EventStatus.Consumed, status); + Assert.AreEqual(EventStatus.Initialized, status); Assert.AreEqual("state2.1.2", currentState); } @@ -191,7 +191,7 @@ public async Task NestedToParentTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("nested-to-parent", "x"), out var sm)) { - await sm.InitializeAsync(); + //await sm.InitializeAsync(); status = (await sm.SendAsync(new SomeEvent())).Status; diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Finalization.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Finalization.cs index 6e9dfe6a..9a645008 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Finalization.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Finalization.cs @@ -41,22 +41,22 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) ; } - [TestMethod] - public async Task NoFinalization() - { - var status = EventStatus.Consumed; - string? currentState = ""; + //[TestMethod] + //public async Task NoFinalization() + //{ + // var status = EventStatus.Consumed; + // string? currentState = ""; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) - { - status = (await sm.SendAsync(new SomeEvent())).Status; + // if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) + // { + // status = (await sm.SendAsync(new SomeEvent())).Status; - currentState = (await sm.GetCurrentStateAsync()).Response?.StatesStack.FirstOrDefault(); - } + // currentState = (await sm.GetCurrentStateAsync()).Response?.StatesStack.FirstOrDefault(); + // } - Assert.AreEqual(EventStatus.Rejected, status); - Assert.AreNotEqual(FinalState.Name, currentState); - } + // Assert.AreEqual(EventStatus.NotConsumed, status); + // Assert.AreNotEqual(FinalState.Name, currentState); + //} [TestMethod] public async Task SimpleFinalization() @@ -67,7 +67,7 @@ public async Task SimpleFinalization() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + initialized = (await sm.SendAsync(new Initialize())).Status == EventStatus.Initialized; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); @@ -79,7 +79,7 @@ public async Task SimpleFinalization() ); Assert.IsTrue(initialized); Assert.IsTrue(finalized); - Assert.AreEqual(StateInfo.Name, currentState); + Assert.AreEqual(State.Name, currentState); } [TestMethod] @@ -90,7 +90,7 @@ public async Task CascadeFinalization() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("cascade", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + initialized = (await sm.SendAsync(new Initialize())).Status == EventStatus.Initialized; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.Skip(1).First() ?? string.Empty; } diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Initialization.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Initialization.cs index cdbfe7f8..d3a3d33b 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Initialization.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Initialization.cs @@ -1,14 +1,11 @@ using Stateflows.Common; -using Stateflows.Common.Data; -using Stateflows.StateMachines.Data; -using Stateflows.StateMachines.Sync.Data; using StateMachine.IntegrationTests.Utils; -using Newtonsoft.Json.Linq; using StateMachine.IntegrationTests.Classes.StateMachines; +using Stateflows.StateMachines.Typed; namespace StateMachine.IntegrationTests.Tests { - public class ValueInitializationRequest : InitializationRequest + public class ValueInitializationRequest : Event { public string Value { get; set; } = String.Empty; } @@ -17,6 +14,8 @@ public class ValueInitializationRequest : InitializationRequest public class Initialization : StateflowsTestClass { private bool? StateEntered = null; + private bool? InitializerCalled = null; + private bool InitializationSuccessful = true; public static string Value = "boo"; [TestInitialize] @@ -31,49 +30,48 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) { builder .AddStateMachines(b => b - .AddStateMachine("simple", b => b + + .AddStateMachine("implicit", b => b .AddInitialState("state1", b => b .AddOnEntry(c => StateEntered = true) ) ) - .AddStateMachine("auto", b => b + .AddStateMachine("explicit", b => b + .AddInitializer(c => + { + InitializerCalled = true; + return c.InitializationEvent.InitializationSuccessful; + }) .AddInitialState("state1", b => b .AddOnEntry(c => StateEntered = true) ) ) - .AddStateMachine("value", b => b - .AddOnInitialize(c => + .AddStateMachine("default", b => b + .AddDefaultInitializer(c => { - c.StateMachine.Values.Set("foo", c.InitializationRequest.Value); - - return true; + InitializerCalled = true; + return InitializationSuccessful; }) .AddInitialState("state1", b => b - .AddOnEntry(c => - { - if (c.StateMachine.Values.TryGet("foo", out var v)) - { - Value = v; - } - }) + .AddOnEntry(c => StateEntered = true) ) ) - .AddStateMachine("invalid", b => b - .AddOnInitialize(c => c.InitializationRequest.Value != null) - .AddInitialState("state1") - ) - - .AddStateMachine("payload", b => b - .AddOnInitialize(c => c.InitializationRequest.Payload != null) - .AddInitialState("state1") + .AddStateMachine("consumption", b => b + .AddInitializer(c => true) + .AddInitialState("state1", b => b + .AddTransition("state2") + ) + .AddState("state2") ) - .AddStateMachine("failed", b => b - .AddOnInitialize(c => throw new Exception("Initialization failed")) - .AddInitialState("state1") + .AddStateMachine("initialize-consumption", b => b + .AddInitialState("state1", b => b + .AddTransition("state2") + ) + .AddState("state2") ) .AddStateMachine("completion", b => b @@ -94,172 +92,186 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) .AddStateMachine() ) - - .AddAutoInitialization(new StateMachineClass("auto")) ; } [TestMethod] - public async Task NoInitialization() + public async Task ImplicitInitialization() { - var status = EventStatus.Rejected; - string? currentState = ""; + string currentState = string.Empty; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("implicit", "x"), out var sm)) { - status = (await sm.SendAsync(new SomeEvent())).Status; - - currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.FirstOrDefault(); + currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.FirstOrDefault() ?? string.Empty; } - Assert.AreEqual(EventStatus.Rejected, status); - Assert.IsNull(StateEntered); - Assert.AreNotEqual("state1", currentState); + Assert.IsTrue(StateEntered); + Assert.AreEqual("state1", currentState); } [TestMethod] - public async Task SimpleInitialization() + public async Task ExplicitInitializationWithInitialize() { - var initialized = false; - string currentState = string.Empty; + EventStatus status = EventStatus.Undelivered; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("implicit", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + status = (await sm.SendAsync(new Initialize())).Status; + } - currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.FirstOrDefault() ?? string.Empty; + Assert.IsTrue(StateEntered); + Assert.AreEqual(EventStatus.Initialized, status); + } + + [TestMethod] + public async Task ExplicitDefaultInitializationWithInitialize() + { + EventStatus status = EventStatus.Undelivered; + + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("default", "x"), out var sm)) + { + status = (await sm.SendAsync(new Initialize())).Status; } - Assert.IsTrue(initialized); Assert.IsTrue(StateEntered); - Assert.AreEqual("state1", currentState); + Assert.AreEqual(EventStatus.Initialized, status); } [TestMethod] - public async Task AutoInitialization() + public async Task ExplicitInitializationOK() { + var status = EventStatus.Rejected; string currentState = string.Empty; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("auto", "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("explicit", "x"), out var sm)) { + status = (await sm.SendAsync(new SomeEvent() { InitializationSuccessful = true })).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.FirstOrDefault() ?? string.Empty; } + Assert.IsTrue(InitializerCalled); + Assert.AreEqual(EventStatus.Initialized, status); Assert.IsTrue(StateEntered); Assert.AreEqual("state1", currentState); } [TestMethod] - public async Task NoAutoInitialization() + public async Task ExplicitInitializationFailed() { + var status = EventStatus.Rejected; string currentState = string.Empty; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("explicit", "x"), out var sm)) { + status = (await sm.SendAsync(new SomeEvent() { InitializationSuccessful = false })).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.FirstOrDefault() ?? string.Empty; } - Assert.IsNull(StateEntered); - Assert.AreNotEqual("state1", currentState); + Assert.IsTrue(InitializerCalled); + Assert.AreEqual(EventStatus.NotInitialized, status); + Assert.AreEqual(string.Empty, currentState); } [TestMethod] - public async Task DoubleInitialization() + public async Task ConsumptionInitializeOnly() { - var initialized = false; + var status = EventStatus.Rejected; string currentState = string.Empty; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("consumption", "x"), out var sm)) { - await sm.InitializeAsync(); - - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; - - currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First() ?? string.Empty; + status = (await sm.SendAsync(new SomeEvent() { InitializationSuccessful = true })).Status; + currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.FirstOrDefault() ?? string.Empty; } - Assert.IsFalse(initialized); - Assert.IsTrue(StateEntered); + Assert.AreEqual(EventStatus.Initialized, status); Assert.AreEqual("state1", currentState); } [TestMethod] - public async Task ValueInitialization() + public async Task ConsumptionTransition() { - var initialized = false; + var status1 = EventStatus.Rejected; + var status2 = EventStatus.Rejected; string currentState = string.Empty; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("value", "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("consumption", "x"), out var sm)) { - initialized = (await sm.InitializeAsync(new ValueInitializationRequest() { Value = "bar" })).Response.InitializationSuccessful; - - currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First() ?? string.Empty; + status1 = (await sm.SendAsync(new SomeEvent() { InitializationSuccessful = true })).Status; + status2 = (await sm.SendAsync(new SomeEvent() { InitializationSuccessful = true })).Status; + currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.FirstOrDefault() ?? string.Empty; } - Assert.IsTrue(initialized); - Assert.AreEqual("bar", Value); - Assert.AreEqual("state1", currentState); + Assert.AreEqual(EventStatus.Initialized, status1); + Assert.AreEqual(EventStatus.Consumed, status2); + Assert.AreEqual("state2", currentState); } [TestMethod] - public async Task TypedValueInitialization() + public async Task InitializeConsumptionInitializeOnly() { - var initialized = false; + var status = EventStatus.Rejected; string currentState = string.Empty; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId(StateMachineInfo.Name, "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("initialize-consumption", "x"), out var sm)) { - initialized = (await sm.InitializeAsync(new ValueInitializationRequest() { Value = "bar" })).Response.InitializationSuccessful; - - currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First() ?? string.Empty; + status = (await sm.SendAsync(new Initialize())).Status; + currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.FirstOrDefault() ?? string.Empty; } - Assert.IsTrue(initialized); - Assert.AreEqual("bar", Value); + Assert.AreEqual(EventStatus.Initialized, status); Assert.AreEqual("state1", currentState); } [TestMethod] - public async Task PayloadInitialization() + public async Task InitializeConsumptionTransition() { - var initialized = false; + var status1 = EventStatus.Rejected; + var status2 = EventStatus.Rejected; string currentState = string.Empty; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("payload", "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("initialize-consumption", "x"), out var sm)) { - initialized = (await sm.InitializeAsync("bar")).Response.InitializationSuccessful; - - currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First() ?? string.Empty; + status1 = (await sm.SendAsync(new Initialize())).Status; + status2 = (await sm.SendAsync(new Initialize())).Status; + currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.FirstOrDefault() ?? string.Empty; } - Assert.IsTrue(initialized); + Assert.AreEqual(EventStatus.Initialized, status1); + Assert.AreEqual(EventStatus.NotInitialized, status2); Assert.AreEqual("state1", currentState); } [TestMethod] - public async Task InvalidInitialization() + public async Task ImplicitDefaultInitializationOK() { - var initialized = false; + string currentState = string.Empty; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("invalid", "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("default", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + var result = await sm.GetCurrentStateAsync(); + currentState = (result).Response.StatesStack.FirstOrDefault() ?? string.Empty; } - Assert.IsFalse(initialized); + Assert.IsTrue(InitializerCalled); + Assert.IsTrue(StateEntered); + Assert.AreEqual("state1", currentState); } [TestMethod] - public async Task FailedInitialization() + public async Task DefaultInitializationFailed() { - var initialized = false; + string currentState = string.Empty; + InitializationSuccessful = false; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("failed", "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("default", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + var result = await sm.GetCurrentStateAsync(); + currentState = (result).Response.StatesStack.FirstOrDefault() ?? string.Empty; } - Assert.IsFalse(initialized); + Assert.IsTrue(InitializerCalled); + Assert.AreEqual(string.Empty, currentState); } [TestMethod] @@ -270,7 +282,7 @@ public async Task InitializationWithCompletion() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("completion", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + initialized = (await sm.SendAsync(new Initialize())).Status == EventStatus.Initialized; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First() ?? string.Empty; } @@ -287,7 +299,7 @@ public async Task InitializationWithNestedCompletion() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("nested-completion", "x"), out var sm)) { - initialized = (await sm.InitializeAsync()).Response.InitializationSuccessful; + initialized = (await sm.SendAsync(new Initialize())).Status == EventStatus.Initialized; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.Skip(1).First() ?? string.Empty; } diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Reset.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Reset.cs index 385083ce..2c814f37 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Reset.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Reset.cs @@ -23,6 +23,7 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) builder .AddStateMachines(b => b .AddStateMachine("reset", b => b + .AddInitializer(async c => true) .AddInitialState("state1", b => b .AddOnEntry(c => StateEntered = true) ) @@ -40,7 +41,7 @@ public async Task ResettingInitialized() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("reset", "x"), out var sm)) { - await sm.InitializeAsync(); + await sm.SendAsync(new SomeEvent()); currentState1 = (await sm.GetCurrentStateAsync()).Response; diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Scale.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Scale.cs index 82878179..fa886930 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Scale.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Scale.cs @@ -1,3 +1,4 @@ +using Stateflows.Common; using StateMachine.IntegrationTests.Utils; namespace StateMachine.IntegrationTests.Tests @@ -51,10 +52,10 @@ public async Task ProcessingInScale() : null ) .Where(stateMachine => stateMachine is not null) - .Select(stateMachine => stateMachine.InitializeAsync()) + .Select(stateMachine => stateMachine.SendAsync(new Initialize())) .ToArray(); - var badResults = (await Task.WhenAll(sequence)).Count(r => !r.Response.InitializationSuccessful); + var badResults = (await Task.WhenAll(sequence)).Count(r => r.Status != EventStatus.Initialized); Assert.AreEqual(0, badResults); } diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ServiceScopes.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ServiceScopes.cs index a6669853..55d84a35 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ServiceScopes.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/ServiceScopes.cs @@ -17,7 +17,7 @@ public Service() public readonly string Value; } - public class ScopeState : State + public class ScopeState : IStateEntry, IStateExit { private readonly Service service; public ScopeState(Service service) @@ -25,14 +25,14 @@ public ScopeState(Service service) this.service = service; } - public override Task OnEntryAsync() + public Task OnEntryAsync() { ServiceScopes.EntryValue = service.Value; return Task.CompletedTask; } - public override Task OnExitAsync() + public Task OnExitAsync() { ServiceScopes.ExitValue = service.Value; @@ -40,7 +40,7 @@ public override Task OnExitAsync() } } - public class Some : Transition + public class Some : ITransitionEffect { private readonly Service service; public Some(Service service) @@ -48,7 +48,7 @@ public Some(Service service) this.service = service; } - public override Task EffectAsync() + public Task EffectAsync(SomeEvent @event) { ServiceScopes.SomeValue = service.Value; @@ -56,7 +56,7 @@ public override Task EffectAsync() } } - public class Other : Transition + public class Other : ITransitionEffect { private readonly Service service; public Other(Service service) @@ -64,7 +64,7 @@ public Other(Service service) this.service = service; } - public override Task EffectAsync() + public Task EffectAsync(OtherEvent @event) { ServiceScopes.OtherValue = service.Value; @@ -116,7 +116,6 @@ public async Task SeparateScopesOnCompoundEvents() { if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("compound", "x"), out var sm)) { - await sm.InitializeAsync(); await sm.SendAsync(new CompoundRequest() { Events = new List() @@ -135,7 +134,7 @@ public async Task SeparateScopesOnStateEvents() { if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("state", "x"), out var sm)) { - await sm.InitializeAsync(); + await sm.SendAsync(new Initialize()); } Assert.AreNotEqual(ServiceScopes.SomeValue, ServiceScopes.OtherValue); diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Subscription.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Subscription.cs index 800fd447..2bb3191e 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Subscription.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Subscription.cs @@ -1,6 +1,5 @@ -using StateMachine.IntegrationTests.Utils; using Stateflows.Common; -using Stateflows.StateMachines.Sync; +using StateMachine.IntegrationTests.Utils; namespace StateMachine.IntegrationTests.Tests { @@ -56,9 +55,9 @@ public async Task SubscribingSuccessful() StateMachineLocator.TryLocateStateMachine(new StateMachineId("subscribee", "x"), out var subscribee) ) { - await subscriber.InitializeAsync(); + //await subscriber.SendAsync(new Initialize()); - await subscribee.InitializeAsync(); + //await subscribee.SendAsync(new Initialize()); await subscribee.SendAsync(new OtherEvent()); @@ -87,7 +86,7 @@ public async Task WatchSuccessful() } }); - await subscribee.InitializeAsync(); + //await subscribee.InitializeAsync(); await subscribee.SendAsync(new OtherEvent()); @@ -112,9 +111,9 @@ public async Task WatchStandardNotifications() _ = subscribee.WatchStatusAsync(n => currentStatus = n.BehaviorStatus); - await subscribee.InitializeAsync(); + await subscribee.SendAsync(new Initialize()); - await subscribee.GetCurrentStateAsync(); + await Task.Delay(10); } Assert.AreEqual("state1", currentState); diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Transitions.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Transitions.cs index 5ac9c7d5..213dbc4b 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Transitions.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Transitions.cs @@ -88,8 +88,6 @@ public async Task SimpleTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("simple", "x"), out var sm)) { - await sm.InitializeAsync(); - status = (await sm.SendAsync(new SomeEvent())).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); @@ -110,8 +108,6 @@ public async Task GuardedTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("guarded", "x"), out var sm)) { - await sm.InitializeAsync(); - status = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 43 })).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); @@ -123,6 +119,25 @@ public async Task GuardedTransition() Assert.AreNotEqual("state2", currentState); } + [TestMethod] + public async Task GuardedTransitionInvalid() + { + var status = EventStatus.Rejected; + string currentState = "state1"; + + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("guarded", "x"), out var sm)) + { + status = (await sm.SendAsync(new OtherEvent() { AnswerToLifeUniverseAndEverything = 42, RequiredParameter = string.Empty })).Status; + + currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); + } + + Assert.AreEqual(EventStatus.Invalid, status); + Assert.IsNull(StateExited); + Assert.IsNull(StateEntered); + Assert.AreNotEqual("state2", currentState); + } + [TestMethod] public async Task DefaultTransition() { @@ -131,8 +146,6 @@ public async Task DefaultTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("default", "x"), out var sm)) { - await sm.InitializeAsync(); - status = (await sm.SendAsync(new SomeEvent())).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); @@ -150,8 +163,6 @@ public async Task InternalTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("internal", "x"), out var sm)) { - await sm.InitializeAsync(); - status = (await sm.SendAsync(new SomeEvent())).Status; var stack = (await sm.GetCurrentStateAsync()).Response.StatesStack; @@ -176,8 +187,6 @@ public async Task SelfTransition() if (StateMachineLocator.TryLocateStateMachine(new StateMachineId("self", "x"), out var sm)) { - await sm.InitializeAsync(); - status = (await sm.SendAsync(new SomeEvent())).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Typed.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Typed.cs index cf1ca606..7d017eca 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Typed.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Typed.cs @@ -1,10 +1,8 @@ using Stateflows.Common; -using Stateflows.StateMachines.Sync; -using Stateflows.StateMachines.Typed; -using StateMachine.IntegrationTests.Classes.StateMachines; +using StateMachine.IntegrationTests.Utils; using StateMachine.IntegrationTests.Classes.States; using StateMachine.IntegrationTests.Classes.Transitions; -using StateMachine.IntegrationTests.Utils; +using StateMachine.IntegrationTests.Classes.StateMachines; namespace StateMachine.IntegrationTests.Tests { @@ -33,17 +31,15 @@ public async Task TypedStateMachine() { var status1 = EventStatus.Rejected; var status2 = EventStatus.Rejected; - string currentState = StateInfo.Name; + string currentState = State.Name; StateMachine1.Reset(); State1.Reset(); State2.Reset(); SomeEventTransition.Reset(); - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId(StateMachineInfo.Name, "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId(StateMachine.Name, "x"), out var sm)) { - await sm.InitializeAsync(); - status1 = (await sm.SendAsync(new SomeEvent())).Status; currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); @@ -57,7 +53,7 @@ public async Task TypedStateMachine() Assert.IsTrue(SomeEventTransition.GuardFired); Assert.IsTrue(SomeEventTransition.EffectFired); Assert.IsTrue(State2.EntryFired); - Assert.AreEqual(StateInfo.Name, currentState); + Assert.AreEqual(State.Name, currentState); Assert.AreEqual(EventStatus.Consumed, status2); Assert.IsTrue(State2.ExitFired); Assert.IsTrue(StateMachine1.FinalizeFired); diff --git a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Values.cs b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Values.cs index 5679babc..d288b84a 100644 --- a/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Values.cs +++ b/Tests/StateMachine/StateMachine.IntegrationTests/Tests/Values.cs @@ -27,17 +27,17 @@ protected override void InitializeStateflows(IStateflowsBuilder builder) [TestMethod] public async Task TypedStateMachine() { - string currentState = StateInfo.Name; + string currentState = State.Name; - if (StateMachineLocator.TryLocateStateMachine(new StateMachineId(StateMachineInfo.Name, "x"), out var sm)) + if (StateMachineLocator.TryLocateStateMachine(new StateMachineId(StateMachine.Name, "x"), out var sm)) { - await sm.InitializeAsync(); + //await sm.InitializeAsync(); await sm.SendAsync(new SomeEvent()); currentState = (await sm.GetCurrentStateAsync()).Response.StatesStack.First(); } - Assert.AreEqual(StateInfo.Name, currentState); + Assert.AreEqual(State.Name, currentState); } } } \ No newline at end of file diff --git a/Transport/@stateflows/common/src/behaviors/behavior.ts b/Transport/@stateflows/common/src/behaviors/behavior.ts index 35df8ed8..93c9ee1b 100644 --- a/Transport/@stateflows/common/src/behaviors/behavior.ts +++ b/Transport/@stateflows/common/src/behaviors/behavior.ts @@ -2,13 +2,11 @@ import { Request } from "../events/request"; import { IBehavior } from "../interfaces/behavior"; import { SendResult } from "../classes/send-result"; import { RequestResult } from "../classes/request-result"; -import { InitializationResponse } from "../events/initialization.response"; import { BehaviorStatusResponse } from "../events/behavior-status.response"; import { BehaviorId } from "../ids/behavior.id"; import { Response } from "../events/response"; import { CompoundRequest } from "../events/compound.request"; import { CompoundResponse } from "../events/compound.response"; -import { InitializationRequest } from "../events/initialization.request"; import { Event } from "../events/event"; import { BehaviorStatusRequest } from "../events/behavior-status.request"; import { IStateflowsClientTransport } from "../interfaces/stateflows-client-transport"; @@ -20,6 +18,7 @@ import { BehaviorStatusNotification } from "../events/behavior-status.notificati import { Notification } from "../events/notification"; import { IWatcher } from "../interfaces/watcher"; import { NotificationHandler } from "../utils/notification-handler"; +import { ResetMode } from "../enums/reset-mode"; export class Behavior implements IBehavior, IWatcher { #transportPromise: Promise; @@ -48,40 +47,12 @@ export class Behavior implements IBehavior, IWatcher { return result; } - initialize(initializationRequest?: InitializationRequest): Promise> { - if (typeof initializationRequest === "undefined") { - initializationRequest = new InitializationRequest(); - } - - return this.request(initializationRequest); - } - finalize(): Promise> { return this.request(new FinalizationRequest()); } - reset(keepVersion?: boolean): Promise> { - return this.request(new ResetRequest(keepVersion ?? false)); - } - - async reinitialize(initializationRequest?: InitializationRequest, keepVersion: boolean = true): Promise> { - if (typeof initializationRequest === "undefined") { - initializationRequest = new InitializationRequest(); - } - - let result = await this.sendCompound( - new ResetRequest(keepVersion ?? true), - initializationRequest - ); - - let initializationResult = result.response.results.slice(-1)[0]; - - return new RequestResult( - initializationResult.response as InitializationResponse, - initializationRequest, - initializationResult.status, - initializationResult.validation - ); + reset(resetMode?: ResetMode): Promise> { + return this.request(new ResetRequest(resetMode ?? ResetMode.Full)); } notify(notification: Notification): void { diff --git a/Transport/@stateflows/common/src/behaviors/state-machine.ts b/Transport/@stateflows/common/src/behaviors/state-machine.ts index 29e399bb..96603422 100644 --- a/Transport/@stateflows/common/src/behaviors/state-machine.ts +++ b/Transport/@stateflows/common/src/behaviors/state-machine.ts @@ -1,5 +1,7 @@ +import { RequestResult } from "../classes/request-result"; import { CurrentStateNotification } from "../events/current-state.notification"; import { CurrentStateRequest } from "../events/current-state.request"; +import { CurrentStateResponse } from "../events/current-state.response"; import { IStateMachine } from "../interfaces/state-machine"; import { NotificationHandler } from "../utils/notification-handler"; import { Behavior } from "./behavior"; @@ -9,7 +11,7 @@ export class StateMachine extends Behavior implements IStateMachine { super(behavior, behavior.id); } - getCurrentState(): Promise { + getCurrentState(): Promise> { return this.request(new CurrentStateRequest()); } diff --git a/Transport/@stateflows/common/src/behaviors/system.ts b/Transport/@stateflows/common/src/behaviors/system.ts deleted file mode 100644 index b70bba48..00000000 --- a/Transport/@stateflows/common/src/behaviors/system.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ISystem } from "../interfaces/system"; -import { IBehavior } from "../interfaces/behavior"; -import { RequestResult } from "../classes/request-result"; -import { AvailableBehaviorClassesRequest } from "../events/available-behavior-classes.request"; -import { AvailableBehaviorClassesResponse } from "../events/available-behavior-classes.response"; -import { BehaviorInstancesRequest } from "../events/behavior-instances.request"; -import { BehaviorInstancesResponse } from "../events/behavior-instances.response"; - -export class System implements ISystem { - constructor(private behavior: IBehavior) {} - - getAvailableBehaviorClasses(): Promise> { - return this.behavior.request(new AvailableBehaviorClassesRequest()); - } - - getBehaviorInstances(): Promise> { - return this.behavior.request(new BehaviorInstancesRequest()); - } -} \ No newline at end of file diff --git a/Transport/@stateflows/common/src/classes/stateflows-client.ts b/Transport/@stateflows/common/src/classes/stateflows-client.ts index 08b9efe1..d0778557 100644 --- a/Transport/@stateflows/common/src/classes/stateflows-client.ts +++ b/Transport/@stateflows/common/src/classes/stateflows-client.ts @@ -2,10 +2,8 @@ import { IBehaviorLocator } from "../interfaces/behavior.locator"; import { IStateMachineLocator } from "../interfaces/state-machine.locator"; import { BehaviorLocator } from "../locators/behavior.locator"; import { StateMachineLocator } from "../locators/state-machine.locator"; -import { ISystem } from "../interfaces/system"; import { BehaviorId } from "../ids/behavior.id"; import { BehaviorClass } from "../ids/behavior.class"; -import { System } from "../behaviors/system"; import { IActivityLocator } from "../interfaces/activity.locator"; import { ActivityLocator } from "../locators/activity.locator"; import { IStateflowsClientTransportFactory } from "../interfaces/stateflows-client-transport-factory"; @@ -30,14 +28,4 @@ export class StateflowsClient { public get activityLocator(): IActivityLocator { return this.#activityLocator ??= new ActivityLocator(this.behaviorLocator); } - - #systemPromise: Promise | null = null; - - public get system(): Promise { - return this.#systemPromise ??= new Promise((resolve, reject) => { - this.behaviorLocator.locateBehavior(new BehaviorId(new BehaviorClass("System", "Stateflows"), "")) - .then(behavior => resolve(new System(behavior))) - .catch(reason => reject(reason)); - }) - } } \ No newline at end of file diff --git a/Transport/@stateflows/common/src/enums/event-status.ts b/Transport/@stateflows/common/src/enums/event-status.ts index 38ac00fd..76685c03 100644 --- a/Transport/@stateflows/common/src/enums/event-status.ts +++ b/Transport/@stateflows/common/src/enums/event-status.ts @@ -1,8 +1,13 @@ export enum EventStatus { - Undelivered = 0, - Rejected = 1, - Invalid = 2, - NotConsumed = 3, - Deferred = 4, - Consumed = 5 + Initialized = 0, + NotInitialized = 1, + Undelivered = 2, + Rejected = 3, + Invalid = 4, + Deferred = 5, + Consumed = 6, + NotConsumed = 7, + Omitted = 8, + Failed = 9, + Forwarded = 10 } \ No newline at end of file diff --git a/Transport/@stateflows/common/src/enums/reset-mode.ts b/Transport/@stateflows/common/src/enums/reset-mode.ts new file mode 100644 index 00000000..79986d1d --- /dev/null +++ b/Transport/@stateflows/common/src/enums/reset-mode.ts @@ -0,0 +1,5 @@ +export enum ResetMode { + KeepVersionAndSubscriptions = 0, + KeepSubscriptions = 1, + Full = 2 +} \ No newline at end of file diff --git a/Transport/@stateflows/common/src/events/initialization.request.ts b/Transport/@stateflows/common/src/events/initialization.request.ts deleted file mode 100644 index e42a4460..00000000 --- a/Transport/@stateflows/common/src/events/initialization.request.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Request } from "./request"; -import { InitializationResponse } from "./initialization.response"; - -export class InitializationRequest extends Request { - public $type = "Stateflows.Common.InitializationRequest, Stateflows.Common"; - public name = "Stateflows.Common.InitializationRequest"; -} \ No newline at end of file diff --git a/Transport/@stateflows/common/src/events/initialization.response.ts b/Transport/@stateflows/common/src/events/initialization.response.ts deleted file mode 100644 index 2e817636..00000000 --- a/Transport/@stateflows/common/src/events/initialization.response.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Response } from "./response"; - -export class InitializationResponse extends Response { - constructor( - public initializationSuccessful: boolean, - ) { - super(); - } -} \ No newline at end of file diff --git a/Transport/@stateflows/common/src/events/initialize.ts b/Transport/@stateflows/common/src/events/initialize.ts new file mode 100644 index 00000000..793ae176 --- /dev/null +++ b/Transport/@stateflows/common/src/events/initialize.ts @@ -0,0 +1,4 @@ +export class Initialize extends Event { + public $type = "Stateflows.Common.Initialize, Stateflows.Common"; + public name = "Stateflows.Common.Initialize"; +} \ No newline at end of file diff --git a/Transport/@stateflows/common/src/events/reset.request.ts b/Transport/@stateflows/common/src/events/reset.request.ts index 92068784..c94a021a 100644 --- a/Transport/@stateflows/common/src/events/reset.request.ts +++ b/Transport/@stateflows/common/src/events/reset.request.ts @@ -1,12 +1,13 @@ import { Request } from "./request"; import { ResetResponse } from "./reset.response"; +import { ResetMode } from "../enums/reset-mode"; export class ResetRequest extends Request { public $type = "Stateflows.Common.ResetRequest, Stateflows.Common"; public name = "Stateflows.Common.ResetRequest"; constructor( - public keepVersion: boolean = false, + public mode: ResetMode = ResetMode.Full, ) { super(); } diff --git a/Transport/@stateflows/common/src/index.ts b/Transport/@stateflows/common/src/index.ts index f3538d10..d53d88b7 100644 --- a/Transport/@stateflows/common/src/index.ts +++ b/Transport/@stateflows/common/src/index.ts @@ -10,8 +10,6 @@ export { Request } from "./events/request"; export { Notification } from "./events/notification"; export { CompoundRequest } from "./events/compound.request"; export { CompoundResponse } from "./events/compound.response"; -export { InitializationRequest } from "./events/initialization.request"; -export { InitializationResponse } from "./events/initialization.response"; export { FinalizationRequest } from "./events/finalization.request"; export { FinalizationResponse } from "./events/finalization.response"; export { ResetRequest } from "./events/reset.request"; @@ -29,7 +27,6 @@ export { CurrentStateNotification } from "./events/current-state.notification"; export { IBehaviorLocator } from "./interfaces/behavior.locator"; export { IWatcher } from "./interfaces/watcher"; export { IBehavior } from "./interfaces/behavior"; -export { ISystem } from "./interfaces/system"; export { IStateMachineLocator } from "./interfaces/state-machine.locator"; export { IActivityLocator } from "./interfaces/activity.locator"; export { IStateMachine } from "./interfaces/state-machine"; diff --git a/Transport/@stateflows/common/src/interfaces/behavior.ts b/Transport/@stateflows/common/src/interfaces/behavior.ts index 106ceb85..a11c0803 100644 --- a/Transport/@stateflows/common/src/interfaces/behavior.ts +++ b/Transport/@stateflows/common/src/interfaces/behavior.ts @@ -2,7 +2,6 @@ import { RequestResult } from "../classes/request-result"; import { SendResult } from "../classes/send-result"; import { BehaviorStatusResponse } from "../events/behavior-status.response"; import { BehaviorStatusNotification } from "../events/behavior-status.notification"; -import { InitializationResponse } from "../events/initialization.response"; import { FinalizationResponse } from "../events/finalization.response"; import { ResetResponse } from "../events/reset.response"; import { CompoundResponse } from "../events/compound.response"; @@ -10,9 +9,9 @@ import { Event } from "../events/event"; import { Request } from "../events/request"; import { Response } from "../events/response"; import { Notification } from "../events/notification"; -import { InitializationRequest } from "../events/initialization.request"; import { NotificationHandler } from "../utils/notification-handler"; import { BehaviorId } from "../ids/behavior.id"; +import { ResetMode } from "../enums/reset-mode"; export interface IBehavior { id: BehaviorId; @@ -21,10 +20,8 @@ export interface IBehavior { sendCompound(...events: Event[]): Promise>; request(request: Request): Promise>; - initialize(initializationRequest?: InitializationRequest): Promise>; finalize(): Promise>; - reset(keepVersion?: boolean): Promise>; - reinitialize(initializationRequest?: InitializationRequest): Promise>; + reset(resetMode?: ResetMode): Promise>; watch(notificationName: string, handler: NotificationHandler): Promise; unwatch(notificationName: string): Promise; diff --git a/Transport/@stateflows/common/src/interfaces/system.ts b/Transport/@stateflows/common/src/interfaces/system.ts deleted file mode 100644 index 965766d7..00000000 --- a/Transport/@stateflows/common/src/interfaces/system.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { RequestResult } from "../classes/request-result"; -import { AvailableBehaviorClassesResponse } from "../events/available-behavior-classes.response"; -import { BehaviorInstancesResponse } from "../events/behavior-instances.response"; - -export interface ISystem { - getAvailableBehaviorClasses(): Promise>; - getBehaviorInstances(): Promise>; -} \ No newline at end of file diff --git a/Transport/@stateflows/http-client/src/classes/http-transport.ts b/Transport/@stateflows/http-client/src/classes/http-transport.ts index 8f82e874..814f8ef0 100644 --- a/Transport/@stateflows/http-client/src/classes/http-transport.ts +++ b/Transport/@stateflows/http-client/src/classes/http-transport.ts @@ -20,27 +20,6 @@ export class HttpTransport implements IStateflowsClientTransport { this.#targets.forEach(async target => { await this.send(target.behaviorId, new NotificationsRequest()); }); - - // let body = JsonUtils.stringify({ - // $type: "Stateflows.Common.Transport.Classes.StateflowsNotificationRequest, Stateflows.Common.Transport", - // targets: this.getTargets() - // }); - - // let result = await fetch( - // `${this.url}stateflows/getNotifications`, - // { - // method: "POST", - // headers: { - // 'Accept': 'application/json', - // 'Content-Type': 'application/json' - // }, - // body: body - // } - // ); - - // let stateflowsNotificationResponse = await result.json(); - - // this.handleNotifications(stateflowsNotificationResponse.notifications, stateflowsNotificationResponse.responseTime); }, 10 * 1000); } @@ -77,43 +56,6 @@ export class HttpTransport implements IStateflowsClientTransport { this.#notificationIds = notifications.map(notification => notification.id); } - // private getTargets(): Array { - // let targets: any[] = []; - - // this.#targets.forEach((target, behaviorId) => { - // let targetIndex = targets.findIndex(t => JsonUtils.stringify(t.id) === JsonUtils.stringify(behaviorId)); - // if (targetIndex !== -1) { - // target.watches.forEach(watch => { - // let watchIndex = targets[targetIndex].watches.findIndex((w: any) => w.notificationName === watch.notificationName); - // if (watchIndex === -1) { - // targets[targetIndex].watches.push({ - // notificationName: watch.notificationName, - // lastNotificationCheck: watch.lastNotificationCheck, - // milisecondsSinceLastNotificationCheck: watch.milisecondsSinceLastNotificationCheck !== null - // ? Date.now() - watch.milisecondsSinceLastNotificationCheck - // : null, - // }); - // } - // }); - // } else { - // targets.push({ - // id: target.behaviorId, - // watches: target.watches.map(watch => { - // return { - // notificationName: watch.notificationName, - // lastNotificationCheck: watch.lastNotificationCheck, - // milisecondsSinceLastNotificationCheck: watch.milisecondsSinceLastNotificationCheck !== null - // ? Date.now() - watch.milisecondsSinceLastNotificationCheck - // : null, - // }; - // }) - // }); - // } - // }); - - // return targets; - // } - private getWatches(behaviorId: BehaviorId) { if (this.#targets.has(JsonUtils.stringify(behaviorId))) { let target = this.#targets.get(JsonUtils.stringify(behaviorId)); diff --git a/Transport/Stateflows.Transport.Http/Stateflows.Transport.Http.csproj b/Transport/Stateflows.Transport.Http/Stateflows.Transport.Http.csproj index 88f37d81..2165dc4b 100644 --- a/Transport/Stateflows.Transport.Http/Stateflows.Transport.Http.csproj +++ b/Transport/Stateflows.Transport.Http/Stateflows.Transport.Http.csproj @@ -36,4 +36,9 @@ \ + + + + +