シンプルステートマシン遷移グラフDGMLファイルジェネレーター

WPF / MVVMプロジェクトがあるとします。このプロジェクトでは、配置されている状態に応じてオブジェクト(この場合はViewModel)の動作を制御できるState Machineテンプレートを実装する必要があります。 この場合、状態クラス、遷移ロジックと遷移テーブルを実装するクラスを含むWindows Workflow Foundationを使用せずに、このテンプレートの簡単な実装を取得する必要があります。 このテンプレートの実装の問題とともに、タスクは、遷移表に基づいて状態図を構築するプロセスを自動化するツールを実装することです。 この場合、このツールを使用して構築されたグラフは、次の要件を満たしている必要があります。





したがって、WPF / MVVMプロジェクトのコンテキストでのステートマシンパターンの実装について十分な資料がある場合、2番目のタスク(遷移グラフジェネレーターの実装)に対する明確な解決策はありませんでした。 しかし、このトピックに関する資料を分析するときに、この記事に出くわしました。 そのため、この記事では、作成者はVisual Studioツール、つまりDGMLファイル(Direct Graph Markup Language)のビジュアルエディターを使用して状態グラフを手動で作成し、受け取ったグラフに基づいて、プログラムで状態マシン遷移テーブルを作成します。



DGMLファイル(指向グラフファイル)にはXML表現があり、その構造はMSDNで詳しく説明されています。 そのため、XML表現をプログラムで編集して、グラフの視覚的表現を変更できます。 したがって、グラフの視覚化ツールが選択され、既存の遷移テーブルに基づいてDGMLファイルのXML表現を形成するジェネレーターを実装します。



そのため、プロジェクトソリューションにDGMLファイルを追加し、テストメソッドでグラフジェネレーターを実装することが決定されました。



[TestMethod] public void ClientStateMachineTest() { //    ClientStateMachine var clientStateMachine = new ClientStateMachine(); var xmlDoc = new XmlDocument(); //    DGML-,     const string fileDgml = @"..\..\SM\Test\ClientStateMachineGraph.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(@"..\..\SM\States\{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); }
      
      





メソッドの開始時に、プロジェクトDGMLファイルへの相対パスに基づいて、リンクグラフの指向リンクを含むリンクXMLノードと、ノードグラフのノードを含むノードXMLノードが抽出されるXMLドキュメントがロードされます。



さらに、clientStateMachine.StatesCollection状態コレクションに基づいて、グラフの頂点が形成され、状態ファイルと背景色へのリンクが確立されます。



次に、初期InitialState状態と最終FinalState状態を持つclientStateMachine.Transitions遷移テーブルからの各遷移に基づいて、対応するSource属性とTarget属性をLink XML要素に追加することにより、有向グラフエッジが形成されます。



この試験方法の結果を下図に示します。



画像



結論として、私はそれに注意したい:





したがって、テストメソッドでの有向グラフジェネレーターのシンプルで効果的な実装が提示され、その実装により、状態図の現在のバージョンを取得できます。



All Articles