Skip to content

Commit

Permalink
Merge pull request dotnet-state-machine#560 from mclift/557
Browse files Browse the repository at this point in the history
Update xmdoc.
  • Loading branch information
mclift authored Dec 29, 2023
2 parents 3a97ffe + 57081a9 commit a9d5a35
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 49 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
43 changes: 22 additions & 21 deletions src/Stateless/Graph/GraphStyleBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ public abstract class GraphStyleBase
/// For example, for DOT files the prefix text would be
/// digraph {
/// </summary>
/// <returns>Prefix text</returns>
/// <returns>Prefix text.</returns>
public abstract string GetPrefix();

/// <summary>
/// Get initial transition if present
/// Get initial transition if present.
/// </summary>
/// <returns></returns>
/// <param name="initialState">The initial state.</param>
/// <returns>Description of the initial transition, if present.</returns>
public abstract string GetInitialTransition(Reflection.StateInfo initialState);

/// <summary>
Expand All @@ -30,37 +31,37 @@ public abstract class GraphStyleBase
/// nodename [label="statename"];
/// Usually the information on exit and entry actions would also be included here.
/// </summary>
/// <param name="state">The state to generate text for</param>
/// <returns>Description of the state in the desired format</returns>
/// <param name="state">The state to generate text for.</param>
/// <returns>Description of the state in the desired format.</returns>
public abstract string FormatOneState(State state);

/// <summary>
/// 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.
/// </summary>
/// <param name="stateInfo">The superstate to generate text for</param>
/// <returns>Description of the superstate, and all its substates, in the desired format</returns>
/// <param name="stateInfo">The superstate to generate text for.</param>
/// <returns>Description of the superstate, and all its substates, in the desired format.</returns>
public abstract string FormatOneCluster(SuperState stateInfo);

/// <summary>
/// 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.
/// </summary>
/// <param name="nodeName">Name of the node</param>
/// <param name="label">Label for the node</param>
/// <returns></returns>
/// <param name="nodeName">Name of the node.</param>
/// <param name="label">Label for the node.</param>
/// <returns>Description of the decision node for a dynamic transition, in the desired format.</returns>
public abstract string FormatOneDecisionNode(string nodeName, string label);

/// <summary>
/// Returns the formatted text for all the transitions found in the state graph.
/// This form, which can be overridden, determines the type of each transition and passes the appropriate
/// parameters to the virtual FormatOneTransition() function.
/// </summary>
/// <param name="transitions">List of all transitions in the state graph</param>
/// <returns>Description of all transitions, in the desired format</returns>
/// <param name="transitions">List of all transitions in the state graph.</param>
/// <returns>Description of all transitions, in the desired format.</returns>
public virtual List<string> FormatAllTransitions(List<Transition> transitions)
{
List<string> lines = new List<string>();
Expand Down Expand Up @@ -117,15 +118,15 @@ public virtual List<string> FormatAllTransitions(List<Transition> transitions)
}

/// <summary>
/// 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.
/// </summary>
/// <param name="sourceNodeName">Node name of the source state node</param>
/// <param name="trigger">Name of the trigger</param>
/// <param name="actions">List of entry and exit actions (if any)</param>
/// <param name="destinationNodeName"></param>
/// <param name="guards">List of guards (if any)</param>
/// <returns></returns>
/// <param name="sourceNodeName">Node name of the source state node.</param>
/// <param name="trigger">Name of the trigger.</param>
/// <param name="actions">List of entry and exit actions (if any).</param>
/// <param name="destinationNodeName">Name of the destination state node.</param>
/// <param name="guards">List of guards (if any).</param>
/// <returns>Description of the initial state transition, in the desired format.</returns>
public virtual string FormatOneTransition(string sourceNodeName, string trigger, IEnumerable<string> actions, string destinationNodeName, IEnumerable<string> guards)
{
throw new InvalidOperationException("If you use IGraphStyle.FormatAllTransitions() you must implement an override of FormatOneTransition()");
Expand Down
50 changes: 22 additions & 28 deletions src/Stateless/Graph/UmlDotGraphStyle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
namespace Stateless.Graph
{
/// <summary>
/// Generate DOT graphs in basic UML style
/// Generate DOT graphs in basic UML style.
/// </summary>
public class UmlDotGraphStyle : GraphStyleBase
{
/// <summary>Get the text that starts a new graph</summary>
/// <returns></returns>
/// <summary>Get the text that starts a new graph.</summary>
/// <returns>The prefix for the DOT graph document.</returns>
public override string GetPrefix()
{
return "digraph {\n"
Expand All @@ -23,10 +23,9 @@ public override string GetPrefix()

/// <summary>
/// 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.
/// </summary>
/// <param name="stateInfo">The superstate to generate text for</param>
/// <returns>Description of the superstate, and all its substates, in the desired format</returns>
/// <returns>A DOT graph representation of the superstate and all its substates.</returns>
/// <inheritdoc/>
public override string FormatOneCluster(SuperState stateInfo)
{
string stateRepresentationString = "";
Expand Down Expand Up @@ -57,10 +56,10 @@ public override string FormatOneCluster(SuperState stateInfo)
}

/// <summary>
/// Generate the text for a single state
/// Generate the text for a single state.
/// </summary>
/// <param name="state">The state to generate text for</param>
/// <returns></returns>
/// <returns>A DOT graph representation of the state.</returns>
/// <inheritdoc/>
public override string FormatOneState(State state)
{
if (state.EntryActions.Count == 0 && state.ExitActions.Count == 0)
Expand All @@ -80,14 +79,10 @@ public override string FormatOneState(State state)
}

/// <summary>
/// Generate text for a single transition
/// Generate text for a single transition.
/// </summary>
/// <param name="sourceNodeName"></param>
/// <param name="trigger"></param>
/// <param name="actions"></param>
/// <param name="destinationNodeName"></param>
/// <param name="guards"></param>
/// <returns></returns>
/// <returns>A DOT graph representation of a state transition.</returns>
/// <inheritdoc/>
public override string FormatOneTransition(string sourceNodeName, string trigger, IEnumerable<string> actions, string destinationNodeName, IEnumerable<string> guards)
{
string label = trigger ?? "";
Expand All @@ -109,26 +104,20 @@ public override string FormatOneTransition(string sourceNodeName, string trigger
}

/// <summary>
/// Generate the text for a single decision node
/// Generate the text for a single decision node.
/// </summary>
/// <param name="nodeName">Name of the node</param>
/// <param name="label">Label for the node</param>
/// <returns></returns>
/// <returns>A DOT graph representation of the decision node for a dynamic transition.</returns>
/// <inheritdoc/>
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}\"];";
}

/// <summary>
///
/// Get initial transition if present.
/// </summary>
/// <param name="initialState"></param>
/// <returns></returns>
/// <returns>A DOT graph representation of the initial state transition.</returns>
/// <inheritdoc/>
public override string GetInitialTransition(StateInfo initialState)
{
var initialStateName = initialState.UnderlyingState.ToString();
Expand All @@ -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}\"];";
}
}
}

0 comments on commit a9d5a35

Please sign in to comment.