Skip to content

Commit

Permalink
graph: deduplicate similar lines
Browse files Browse the repository at this point in the history
  • Loading branch information
qmuntal committed Aug 23, 2024
1 parent ad13c0f commit 689d323
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 10 deletions.
Empty file added go.sum
Empty file.
41 changes: 35 additions & 6 deletions graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,35 @@ func (g *graph) formatAllStateTransitions(sm *StateMachine, sr *stateRepresentat
return fmt.Sprint(ti) < fmt.Sprint(tj)
})

type line struct {
source State
destination State
}

lines := make(map[line][]string, len(triggerList))
order := make([]line, 0, len(triggerList))
for _, trigger := range triggerList {
switch t := trigger.(type) {
case *ignoredTriggerBehaviour:
sb.WriteString(g.formatOneTransition(sm, sr.State, sr.State, t.Trigger, nil, t.Guard))
ln := line{sr.State, sr.State}
if _, ok := lines[ln]; !ok {
order = append(order, ln)
}
lines[ln] = append(lines[ln], g.formatOneTransition(t.Trigger, nil, t.Guard))
case *reentryTriggerBehaviour:
actions := g.getEntryActions(sr.EntryActions, t.Trigger)
sb.WriteString(g.formatOneTransition(sm, sr.State, t.Destination, t.Trigger, actions, t.Guard))
ln := line{sr.State, t.Destination}
if _, ok := lines[ln]; !ok {
order = append(order, ln)
}
lines[ln] = append(lines[ln], g.formatOneTransition(t.Trigger, actions, t.Guard))
case *internalTriggerBehaviour:
actions := g.getEntryActions(sr.EntryActions, t.Trigger)
sb.WriteString(g.formatOneTransition(sm, sr.State, sr.State, t.Trigger, actions, t.Guard))
ln := line{sr.State, sr.State}
if _, ok := lines[ln]; !ok {
order = append(order, ln)
}
lines[ln] = append(lines[ln], g.formatOneTransition(t.Trigger, actions, t.Guard))
case *transitioningTriggerBehaviour:
src := sm.stateConfig[sr.State]
if src == nil {
Expand All @@ -149,15 +168,25 @@ func (g *graph) formatAllStateTransitions(sm *StateMachine, sr *stateRepresentat
} else {
destState = dest.State
}
sb.WriteString(g.formatOneTransition(sm, src.State, destState, t.Trigger, actions, t.Guard))
ln := line{sr.State, destState}
if _, ok := lines[ln]; !ok {
order = append(order, ln)
}
lines[ln] = append(lines[ln], g.formatOneTransition(t.Trigger, actions, t.Guard))
case *dynamicTriggerBehaviour:
// TODO: not supported yet
}
}

for _, ln := range order {
content := lines[ln]
sb.WriteString(g.formatOneLine(str(ln.source, true), str(ln.destination, true), strings.Join(content, "\\n")))
}

return sb.String()
}

func (g *graph) formatOneTransition(sm *StateMachine, source, destination State, trigger Trigger, actions []string, guards transitionGuard) string {
func (g *graph) formatOneTransition(trigger Trigger, actions []string, guards transitionGuard) string {
var sb strings.Builder
sb.WriteString(str(trigger, false))
if len(actions) > 0 {
Expand All @@ -170,7 +199,7 @@ func (g *graph) formatOneTransition(sm *StateMachine, source, destination State,
}
sb.WriteString(fmt.Sprintf("[%s]", esc(info.Description.String(), false)))
}
return g.formatOneLine(str(source, true), str(destination, true), sb.String())
return sb.String()
}

func (g *graph) formatOneLine(fromNodeName, toNodeName, label string) string {
Expand Down
4 changes: 4 additions & 0 deletions graph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func TestStateMachine_ToGraph(t *testing.T) {
got := fn().ToGraph()
name := "testdata/golden/" + name + ".dot"
want, err := os.ReadFile(name)
want = bytes.ReplaceAll(want, []byte("\r\n"), []byte("\n"))
if *update {
if !bytes.Equal([]byte(got), want) {
os.WriteFile(name, []byte(got), 0666)
Expand All @@ -147,6 +148,9 @@ func TestStateMachine_ToGraph(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !bytes.Equal([]byte(got), want) {
t.Fatalf("got:\n%swant:\n%s", got, want)
}
}
})
}
Expand Down
6 changes: 2 additions & 4 deletions testdata/golden/phoneCall.dot
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ digraph {
subgraph cluster_Connected {
label="Substates of\nConnected";
style="dashed";
OnHold [label="OnHold"];
OnHold [label="OnHold|exit / func6"];
}
OffHook [label="OffHook"];
Ringing [label="Ringing"];
Connected -> OffHook [label="LeftMessage"];
Connected -> Connected [label="MuteMicrophone"];
Connected -> Connected [label="MuteMicrophone\nSetVolume\nUnmuteMicrophone"];
Connected -> OnHold [label="PlacedOnHold"];
Connected -> Connected [label="SetVolume"];
Connected -> Connected [label="UnmuteMicrophone"];
OffHook -> Ringing [label="CallDialed / func1"];
OnHold -> PhoneDestroyed [label="PhoneHurledAgainstWall"];
OnHold -> Connected [label="TakenOffHold"];
Expand Down

0 comments on commit 689d323

Please sign in to comment.