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}\"];";
+ }
}
}