State machine family: initial, state and final nodes

Overview

Base Control: StateMachineControl : MaterialControl
Namespace: Beep.Skia.StateMachine

The StateMachineControl is the root control for this diagram family. It inherits MaterialControl and provides shared port management, styling, and template methods for all nodes in the family.

This family contains 3 node types.

Node Types

Node ClassShapeDescription
InitialStateNodeFilled circle (black)Initial pseudo-state. Where the state machine begins.
StateNodeRounded rectangleNamed state with optional entry/exit/do actions and internal transitions.
FinalStateNodeCircle with inner filled circle (bullseye)Final termination state.

InitialStateNode

Initial pseudo-state. Where the state machine begins.

ShapeFilled circle (black)
Input Ports0
Output Ports1

StateNode

Named state with optional entry/exit/do actions and internal transitions.

ShapeRounded rectangle
Input Ports1+
Output Ports1+

FinalStateNode

Final termination state.

ShapeCircle with inner filled circle (bullseye)
Input Ports1+
Output Ports0

Connection Points

Every node in this family exposes connection points (ports) for linking to other nodes. Port positions are computed lazily by LayoutPorts(), which runs when MarkPortsDirty() flags the layout as stale after a move or resize.

Node ClassInput PortsOutput PortsExtra
InitialStateNode01—
StateNode1+1+—
FinalStateNode1+0—

Connection Conventions

When building diagrams with this family, follow these conventions:

  • Initial state has no inputs, one output transition
  • State transitions are labeled with trigger[guard]/action
  • Final state has inputs but no outputs
  • States may contain do/entry/exit activity compartments

Usage Example

Complete example showing creation, node placement, and connection:

C# Example

var sm = new StateMachineControl
{
    X = 50, Y = 50,
    Width = 600, Height = 400
};
drawingManager.AddComponent(sm);

var init = new InitialStateNode { X = 100, Y = 200 };
var idle = new StateNode { X = 250, Y = 200, StateName = "Idle" };
var active = new StateNode { X = 400, Y = 100, StateName = "Active" };
var final = new FinalStateNode { X = 400, Y = 300 };

drawingManager.AddComponent(init);
drawingManager.AddComponent(idle);
drawingManager.AddComponent(active);
drawingManager.AddComponent(final);

drawingManager.ConnectComponents(init.OutPoints[0], idle.InPoints[0]);
drawingManager.ConnectComponents(idle.OutPoints[0], active.InPoints[0]);
drawingManager.ConnectComponents(active.OutPoints[0], final.InPoints[0]);

States and Transitions

A state machine is a StateNode graph where the transition semantics live on the connection lines. States carry their behaviour; lines carry the trigger, guard and action:

MemberOnDescription
TitleStateNodeState name shown in the shape.
EntryActionStateNodeBehaviour executed when the state is entered.
ExitActionStateNodeBehaviour executed when the state is left.
DoActivityStateNodeActivity performed while in the state.
TriggerEventConnectionLineEvent that fires the transition.
GuardConditionConnectionLinePredicate that must hold (for example [balance >= amount]).
TransitionActionConnectionLineBehaviour executed during the transition.

The three line properties also appear on the line's labels, so a transition can be read directly on the canvas: trigger [guard] / action. They are persisted with the diagram and validated by the diagram validator when transitions are unreachable.

drawingManager.ConnectComponents(idle, processing);

var transition = drawingManager.GetLines().Last();
transition.TriggerEvent = "order.received";
transition.GuardCondition = "order.items > 0";
transition.TransitionAction = "reserveInventory()";
transition.Label1 = "order.received [items > 0] / reserveInventory()";