diff --git a/CHANGELOG.md b/CHANGELOG.md index ee89471e..5050bf62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## TODO: vNext - date +### Changed + - Updated net6.0 build target to net8.0 [#551] + - New abstract method, `GetInitialTransition`, added to `GraphStyleBase` to remove DOT graph implementation from `StateGraph` [#557] + - Classes that are derived from `GraphStyleBase` and are being migrated from an earlier release of Stateless will need to implement this method. +### Added + - Added license information and README file to NuGet package [#539, #553] + ## 5.14.0 - 2023.11.14 ### Added - Enable Source Link & Deterministic Builds [#501] diff --git a/src/Stateless/Graph/GraphStyleBase.cs b/src/Stateless/Graph/GraphStyleBase.cs index ffa4e644..f7139c6a 100644 --- a/src/Stateless/Graph/GraphStyleBase.cs +++ b/src/Stateless/Graph/GraphStyleBase.cs @@ -15,13 +15,14 @@ public abstract class GraphStyleBase /// For example, for DOT files the prefix text would be /// digraph { /// - /// Prefix text + /// Prefix text. public abstract string GetPrefix(); /// - /// Get initial transition if present + /// Get initial transition if present. /// - /// + /// The initial state. + /// Description of the initial transition, if present. public abstract string GetInitialTransition(Reflection.StateInfo initialState); /// @@ -30,28 +31,28 @@ public abstract class GraphStyleBase /// nodename [label="statename"]; /// Usually the information on exit and entry actions would also be included here. /// - /// The state to generate text for - /// Description of the state in the desired format + /// The state to generate text for. + /// Description of the state in the desired format. public abstract string FormatOneState(State state); /// /// Returns the formatted text for a single superstate and its substates. /// For example, for DOT files this would be a subgraph containing nodes for all the substates. /// - /// The superstate to generate text for - /// Description of the superstate, and all its substates, in the desired format + /// The superstate to generate text for. + /// Description of the superstate, and all its substates, in the desired format. public abstract string FormatOneCluster(SuperState stateInfo); /// /// Returns the formatted text for a single decision node. - /// A decision node is created each time there is a PermitDynamic() transition. There will be a transition + /// A decision node is created each time there is a PermitDynamic() transition. There will be a transition /// from the state that has the dynamic transition to the decision node, and transitions from the decision - /// node to each of the destination nodes. If the caller did not specify the possible destination states, + /// node to each of the destination nodes. If the caller did not specify the possible destination states, /// there will be no transitions leaving the decision node. /// - /// Name of the node - /// Label for the node - /// + /// Name of the node. + /// Label for the node. + /// Description of the decision node for a dynamic transition, in the desired format. public abstract string FormatOneDecisionNode(string nodeName, string label); /// @@ -59,8 +60,8 @@ public abstract class GraphStyleBase /// This form, which can be overridden, determines the type of each transition and passes the appropriate /// parameters to the virtual FormatOneTransition() function. /// - /// List of all transitions in the state graph - /// Description of all transitions, in the desired format + /// List of all transitions in the state graph. + /// Description of all transitions, in the desired format. public virtual List FormatAllTransitions(List transitions) { List lines = new List(); @@ -117,15 +118,15 @@ public virtual List FormatAllTransitions(List transitions) } /// - /// Returns the formatted text for a single transition. Only required if the default version of + /// Returns the formatted text for a single transition. Only required if the default version of /// FormatAllTransitions() is used. /// - /// Node name of the source state node - /// Name of the trigger - /// List of entry and exit actions (if any) - /// - /// List of guards (if any) - /// + /// Node name of the source state node. + /// Name of the trigger. + /// List of entry and exit actions (if any). + /// Name of the destination state node. + /// List of guards (if any). + /// Description of the initial state transition, in the desired format. public virtual string FormatOneTransition(string sourceNodeName, string trigger, IEnumerable actions, string destinationNodeName, IEnumerable guards) { throw new InvalidOperationException("If you use IGraphStyle.FormatAllTransitions() you must implement an override of FormatOneTransition()"); diff --git a/src/Stateless/Graph/UmlDotGraphStyle.cs b/src/Stateless/Graph/UmlDotGraphStyle.cs index 9a053747..7d2f5bd0 100644 --- a/src/Stateless/Graph/UmlDotGraphStyle.cs +++ b/src/Stateless/Graph/UmlDotGraphStyle.cs @@ -7,12 +7,12 @@ namespace Stateless.Graph { /// - /// Generate DOT graphs in basic UML style + /// Generate DOT graphs in basic UML style. /// public class UmlDotGraphStyle : GraphStyleBase { - /// Get the text that starts a new graph - /// + /// Get the text that starts a new graph. + /// The prefix for the DOT graph document. public override string GetPrefix() { return "digraph {\n" @@ -23,10 +23,9 @@ public override string GetPrefix() /// /// Returns the formatted text for a single superstate and its substates. - /// For example, for DOT files this would be a subgraph containing nodes for all the substates. /// - /// The superstate to generate text for - /// Description of the superstate, and all its substates, in the desired format + /// A DOT graph representation of the superstate and all its substates. + /// public override string FormatOneCluster(SuperState stateInfo) { string stateRepresentationString = ""; @@ -57,10 +56,10 @@ public override string FormatOneCluster(SuperState stateInfo) } /// - /// Generate the text for a single state + /// Generate the text for a single state. /// - /// The state to generate text for - /// + /// A DOT graph representation of the state. + /// public override string FormatOneState(State state) { if (state.EntryActions.Count == 0 && state.ExitActions.Count == 0) @@ -80,14 +79,10 @@ public override string FormatOneState(State state) } /// - /// Generate text for a single transition + /// Generate text for a single transition. /// - /// - /// - /// - /// - /// - /// + /// A DOT graph representation of a state transition. + /// public override string FormatOneTransition(string sourceNodeName, string trigger, IEnumerable actions, string destinationNodeName, IEnumerable guards) { string label = trigger ?? ""; @@ -109,26 +104,20 @@ public override string FormatOneTransition(string sourceNodeName, string trigger } /// - /// Generate the text for a single decision node + /// Generate the text for a single decision node. /// - /// Name of the node - /// Label for the node - /// + /// A DOT graph representation of the decision node for a dynamic transition. + /// public override string FormatOneDecisionNode(string nodeName, string label) { return $"\"{nodeName}\" [shape = \"diamond\", label = \"{label}\"];\n"; } - internal string FormatOneLine(string fromNodeName, string toNodeName, string label) - { - return $"\"{fromNodeName}\" -> \"{toNodeName}\" [style=\"solid\", label=\"{label}\"];"; - } - /// - /// + /// Get initial transition if present. /// - /// - /// + /// A DOT graph representation of the initial state transition. + /// public override string GetInitialTransition(StateInfo initialState) { var initialStateName = initialState.UnderlyingState.ToString(); @@ -139,5 +128,10 @@ public override string GetInitialTransition(StateInfo initialState) return dirgraphText; } + + internal string FormatOneLine(string fromNodeName, string toNodeName, string label) + { + return $"\"{fromNodeName}\" -> \"{toNodeName}\" [style=\"solid\", label=\"{label}\"];"; + } } }