Home .NET Simple generator of DGML file of state machine transitions graph

Simple generator of DGML file of state machine transitions graph

by admin

Suppose there is a WPF/MVVM project that needs to implement a State Machine pattern that allows you to control the behavior of an object (in this case, a ViewModel) depending on the state it is in. At the same time, we need to get a simple implementation of this pattern without using Windows Workflow Foundation, which would include state classes, a class that implements the logic of transitions and a table of transitions. And along with the questions of realization of this template there is a task of realization of a tool automating the process of building the state diagram on the basis of the transition table. Thus the graph constructed with the help of this tool should meet the following requirements :

  • the graph should have a clear and orderly visual structure (manual ordering of graph vertices and links should be kept to a minimum);
  • the graph file should be included in the project and, consequently, in the version control system;
  • vertex of the graph must have a clickable link to the file in which the state is implemented;
  • it must be possible to specify styles to the vertices of the graph.

So, if there is enough material on implementation of the pattern of state machine in the context of WPF/MVVM project, for the second problem – the implementation of the generator of transitions graph – no obvious solution was found. But while analyzing the material on this topic I came across this article which is what got me started on the solution. In this article the author manually generates a graph of states with the help of Visual Studio, namely the visual editor of DGML-files (Direct Graph Markup Language), and then, based on the resulting graph, programmatically forms a table of state machine transitions.
A DGML file (oriented graph file) has an XML representation, the structure of which is perfectly described in MSDN. So, by editing the XML representation programmatically it is possible to change the visual representation of a graph. Thus, a graph visualization tool has been chosen, all that remains is to implement a generator that would generate an XML representation of the DGML file based on the existing transition table.
So it was decided to add the DGML file to the project solution and implement the graph generator in the test method :

[TestMethod]public void ClientStateMachineTest(){// ClientStateMachine State Machine Instancevar clientStateMachine = new ClientStateMachine();var xmlDoc = new XmlDocument();// Relative path to the DGML file included in the project solutionconst string fileDgml = @....SMTestClientStateMachineGraph.dgml;;xmlDoc.Load(fileDgml);var nodeLinks = xmlDoc.SelectSingleNode("/*[local-name()='DirectedGraph']/*[local-name()='Links']");var nodes = xmlDoc.SelectSingleNode("/*[local-name()='DirectedGraph']/*[local-name()='Nodes']");if (nodes != null){nodes.RemoveAll();foreach (var state in clientStateMachine.StatesCollection){var newNode = xmlDoc.CreateNode(XmlNodeType.Element, "Node", "http://schemas.microsoft.com/vs/2009/dgml");var id = xmlDoc.CreateAttribute("Id");id.Value = state.GetType().Name;var reference = xmlDoc.CreateAttribute("Reference");reference.Value = string.Format(@"....SMStates{0}.cs", state.GetType().Name);var background = xmlDoc.CreateAttribute("Background");background.Value = state.Background.Name;if (newNode.Attributes != null){newNode.Attributes.Append(id);newNode.Attributes.Append(background);newNode.Attributes.Append(reference);}nodes.AppendChild(newNode);}}if (nodeLinks != null){nodeLinks.RemoveAll();foreach (var tr in clientStateMachine.Transitions){var newLink = xmlDoc.CreateNode(XmlNodeType.Element, "Link", "http://schemas.microsoft.com/vs/2009/dgml");var source = xmlDoc.CreateAttribute("Source");source.Value = (tr.Value.InitialState).GetType().Name;var target = xmlDoc.CreateAttribute("Target");target.Value = tr.Value.FinalState.GetType().Name;if (newLink.Attributes != null){newLink.Attributes.Append(source);newLink.Attributes.Append(target);}nodeLinks.AppendChild(newLink);}}xmlDoc.Save(fileDgml);}

At the beginning of the method, based on the relative path to the DGML file of the project, an XML document is loaded, from which the XML node Links, containing the oriented links of the Link graph, and the XML node Nodes, containing the nodes of the Node graph, are extracted.
Next, based on the clientStateMachine.StatesCollection, the vertices of the graph are formed, which have links to the state files and the background color.
Then, based on each transition from the clientStateMachine.Transitions table that has an InitialState and a FinalState, a directed graph edge is formed by adding the appropriate Source and Target attributes to the Link XML element.
The result of this test method is shown in the figure below.
Simple generator of DGML file of state machine transitions graph
In conclusion, I would like to point out that :

  • clear graph structure, with no overlapping or intersecting vertices or links, was obtained automatically using the graph layout builder, which is an excellent advantage of this Visual Studio tool;
  • you can follow the link to the state file from the context menu of the graph node;
  • the presented generator can be easily adapted to any state machine that has a transition table.

Thus, a simple but effective implementation of the oriented graph generator in the test method is presented, the execution of which allows to get an up-to-date version of the state diagram.

You may also like