Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/tokens reworked #27

Merged
merged 11 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[*.cs]

# S3358: Ternary operators should not be nested
dotnet_diagnostic.S3358.severity = none

# S2094: Classes should not be empty
dotnet_diagnostic.S2094.severity = none
dotnet_diagnostic.S2326.severity = none
dotnet_diagnostic.S1121.severity = none
dotnet_diagnostic.CS0067.severity = none
4 changes: 2 additions & 2 deletions Core/Stateflows.Common/Activities/Classes/ActivityWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ public ActivityWrapper(IBehavior consumer)
Behavior = consumer;
}

public Task<RequestResult<ExecutionResponse>> ExecuteAsync(InitializationRequest initializationRequest = null, IEnumerable<Token> inputTokens = null)
public Task<RequestResult<ExecutionResponse>> ExecuteAsync(InitializationRequest initializationRequest = null, IEnumerable<object> inputTokens = null)
{
var executionRequest = new ExecutionRequest(initializationRequest ?? new InitializationRequest(), inputTokens ?? new Token[0]);
var executionRequest = new ExecutionRequest(initializationRequest ?? new InitializationRequest(), inputTokens ?? new object[0]);
if (initializationRequest != null)
{
executionRequest.Headers.AddRange(initializationRequest.Headers);
Expand Down
4 changes: 2 additions & 2 deletions Core/Stateflows.Common/Activities/Events/ExecutionRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Stateflows.Activities.Events
{
public sealed class ExecutionRequest : Request<ExecutionResponse>
{
public ExecutionRequest(InitializationRequest initializationRequest, IEnumerable<Token> inputTokens)
public ExecutionRequest(InitializationRequest initializationRequest, IEnumerable<object> inputTokens)
{
InitializationRequest = initializationRequest;
InputTokens = inputTokens;
Expand All @@ -15,6 +15,6 @@ public ExecutionRequest(InitializationRequest initializationRequest, IEnumerable
public InitializationRequest InitializationRequest { get; set; }

[JsonProperty(TypeNameHandling = TypeNameHandling.None)]
public IEnumerable<Token> InputTokens { get; set; }
public IEnumerable<object> InputTokens { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public sealed class ExecutionResponse : Response
public bool ExecutionSuccessful { get; set; }

[JsonProperty(TypeNameHandling = TypeNameHandling.None)]
public IEnumerable<Token> OutputTokens { get; set; } = new List<Token>();
public IEnumerable<object> OutputTokens { get; set; } = new List<object>();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using Stateflows.Common;
using Stateflows.Activities.Events;

namespace Stateflows.Activities
Expand All @@ -9,7 +8,7 @@ public static class ExecutionResponseExtensions
{
public static IEnumerable<T> GetOutputValues<T>(this ExecutionResponse response)
=> response != null
? response.OutputTokens.OfType<Token<T>>().Select(t => t.Payload).ToArray()
? response.OutputTokens.OfType<T>().ToArray()
: new T[0];

public static T GetOutputValueOrDefault<T>(this ExecutionResponse response, T defaultValue = default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ namespace Stateflows.Activities
public static class IBehaviorLocatorActivityExtensions
{
public static bool TryLocateActivity(this IBehaviorLocator locator, ActivityId id, out IActivity activity)
#pragma warning disable S1121 // Assignments should not be made from within sub-expressions
=> (
activity = locator.TryLocateBehavior(id.BehaviorId, out var behavior)
? new ActivityWrapper(behavior)
: null
) != null;
#pragma warning restore S1121 // Assignments should not be made from within sub-expressions
}
}

This file was deleted.

2 changes: 1 addition & 1 deletion Core/Stateflows.Common/Activities/Interfaces/IActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ namespace Stateflows.Activities
{
public interface IActivity : IBehavior
{
Task<RequestResult<ExecutionResponse>> ExecuteAsync(InitializationRequest initializationRequest = null, IEnumerable<Token> inputTokens = null);
Task<RequestResult<ExecutionResponse>> ExecuteAsync(InitializationRequest initializationRequest = null, IEnumerable<object> inputTokens = null);
}
}
6 changes: 5 additions & 1 deletion Core/Stateflows.Common/Events/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@

namespace Stateflows.Common
{
public class Event : Token
public class Event
{
public Guid Id { get; set; } = Guid.NewGuid();

[JsonProperty(TypeNameHandling = TypeNameHandling.None)]
public List<EventHeader> Headers { get; set; } = new List<EventHeader>();

public DateTime SentAt { get; set; }

public virtual string Name => GetType().GetEventName();
}

public class Event<TPayload> : Event
Expand Down
2 changes: 0 additions & 2 deletions Core/Stateflows.Common/Events/TimeEvents/RecurringEvent.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
namespace Stateflows.Common
{
#pragma warning disable S2094 // Classes should not be empty
public abstract class RecurringEvent : TimeEvent
#pragma warning restore S2094 // Classes should not be empty
{ }
}
5 changes: 3 additions & 2 deletions Core/Stateflows.Common/Extensions/EventInfoExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Stateflows.Common.Extensions;
using System;

namespace Stateflows.Common
{
Expand All @@ -11,7 +12,7 @@ public static string GetEventName(this Type @type)
throw new ArgumentException("Given type is not subclass of Event class");
}

return @type.GetTokenName();
return @type.GetReadableName();
}
}
}
23 changes: 7 additions & 16 deletions Core/Stateflows.Common/Extensions/PayloadObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
using System.Linq;
using System.Collections.Generic;

namespace Stateflows.Common.Data
namespace Stateflows.Common.Data
{
public static class PayloadObjectExtensions
{
public static Event<T> ToEvent<T>(this T obj)
=> new Event<T>() { Payload = obj };

public static Request<TRequestPayload, TResponsePayload> ToRequest<TRequestPayload, TResponsePayload>(this TRequestPayload obj)
=> new Request<TRequestPayload, TResponsePayload>() { Payload = obj };

public static InitializationRequest<T> ToInitializationRequest<T>(this T obj)
=> new InitializationRequest<T>() { Payload = obj };
public static Event<T> ToEvent<T>(this T payload)
=> new Event<T>() { Payload = payload };

public static Token<T> ToToken<T>(this T obj)
=> new Token<T>() { Payload = obj };
public static Request<TRequestPayload, TPayload> ToRequest<TRequestPayload, TPayload>(this TRequestPayload payload)
=> new Request<TRequestPayload, TPayload>() { Payload = payload };

public static IEnumerable<Token<T>> ToTokens<T>(this IEnumerable<T> objs)
=> objs.Select(obj => obj.ToToken()).ToArray();
public static InitializationRequest<TPayload> ToInitializationRequest<TPayload>(this TPayload payload)
=> new InitializationRequest<TPayload>() { Payload = payload };
}
}
10 changes: 1 addition & 9 deletions Core/Stateflows.Common/Extensions/TokenInfoExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@ namespace Stateflows.Common
public static class TokenInfoExtensions
{
public static string GetTokenName(this Type @type)
{
if ([email protected](typeof(Token)))
{
throw new ArgumentException("Given type is not subclass of Token class");
}

var token = @type.GetUninitializedInstance() as Token;
return token.Name;
}
=> @type.GetReadableName();
}
}
2 changes: 1 addition & 1 deletion Core/Stateflows.Common/Extensions/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public static string GetReadableName(this Type type)
var standardPrefix = "Stateflows.Activities.";
if (result.StartsWith(standardPrefix))
{
result = result.Substring(standardPrefix.Length);
result = result[standardPrefix.Length..];
}

return result;
Expand Down
7 changes: 3 additions & 4 deletions Core/Stateflows.Common/Interfaces/IBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Stateflows.Common.Data;
using Stateflows.Common.Interfaces;

namespace Stateflows.Common
{
/// <summary>
/// Behavior handle
/// </summary>
public interface IBehavior : IWatches, IDisposable
{
BehaviorId Id { get; }
Expand Down Expand Up @@ -41,9 +43,6 @@ async Task<RequestResult<InitializationResponse>> ReinitializeAsync(Initializati
return new RequestResult<InitializationResponse>(initializationRequest, result.Status, result.Validation);
}

Task<RequestResult<InitializationResponse>> ReinitializeAsync<TInitializationPayload>(TInitializationPayload payload, bool keepVersion = true)
=> ReinitializeAsync(payload.ToInitializationRequest(), keepVersion);

Task<RequestResult<BehaviorStatusResponse>> GetStatusAsync()
=> RequestAsync(new BehaviorStatusRequest());

Expand Down
6 changes: 6 additions & 0 deletions Core/Stateflows.Common/Interfaces/IBehaviorLocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ namespace Stateflows.Common
{
public interface IBehaviorLocator
{
/// <summary>
/// Locates handle of behavior with given identifier.
/// </summary>
/// <param name="id">Identifier of behavior</param>
/// <param name="behavior">out parameter providing behavior handle</param>
/// <returns>True if behavior handle is available; false otherwise</returns>
bool TryLocateBehavior(BehaviorId id, out IBehavior behavior);
}
}
13 changes: 13 additions & 0 deletions Core/Stateflows.Common/Interfaces/ISubscriptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,22 @@ namespace Stateflows.Common
{
public interface ISubscriptions
{
/// <summary>
/// Subscribes for notifications from given behavior (by sending <see cref="SubscriptionRequest"/> to it).<br/>
/// Subscription is durable over time; the only way to end it is by calling <see cref="UnsubscribeAsync"/>.
/// </summary>
/// <typeparam name="TNotification">Subscribed notification type</typeparam>
/// <param name="behaviorId">Identifier of a behavior being subscribed to</param>
/// <returns>Task providing <see cref="SubscriptionResponse"/></returns>
Task<RequestResult<SubscriptionResponse>> SubscribeAsync<TNotification>(BehaviorId behaviorId)
where TNotification : Notification, new();

/// <summary>
/// Unsubscribes for notifications from given behavior (by sending <see cref="UnsubscriptionRequest"/> to it).
/// </summary>
/// <typeparam name="TNotification">Unsubscribed notification type</typeparam>
/// <param name="behaviorId">Identifier of a behavior being unsubscribed to</param>
/// <returns>Task providing <see cref="UnsubscriptionResponse"/></returns>
Task<RequestResult<UnsubscriptionResponse>> UnsubscribeAsync<TNotification>(BehaviorId behaviorId)
where TNotification : Notification, new();
}
Expand Down
12 changes: 12 additions & 0 deletions Core/Stateflows.Common/Interfaces/IWatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,21 @@ namespace Stateflows.Common.Interfaces
{
public interface IWatches
{
/// <summary>
/// Watches for notifications from behavior.<br/>
/// Watch is not durable; it lasts as long as behavior handle does.
/// </summary>
/// <typeparam name="TNotification">Notification type</typeparam>
/// <param name="handler">Notification handler</param>
/// <returns>Task of watch operation</returns>
Task WatchAsync<TNotification>(Action<TNotification> handler)
where TNotification : Notification, new();

/// <summary>
/// Unwatches for notifications from behavior.
/// </summary>
/// <typeparam name="TNotification">Notification type</typeparam>
/// <returns>Task of unwatch operation</returns>
Task UnwatchAsync<TNotification>()
where TNotification : Notification, new();
}
Expand Down
16 changes: 0 additions & 16 deletions Core/Stateflows.Common/Tokens/GroupToken.cs

This file was deleted.

52 changes: 0 additions & 52 deletions Core/Stateflows.Common/Tokens/Token.cs

This file was deleted.

Loading
Loading