Quick Start: The Traffic Light

Quick Start: The Traffic Light

This quick start walks you through creating a simple Traffic Light state machine and generating code for Java, JavaScript, and C.

note

For a more comprehensive tutorial with interactive demos, realistic European-style traffic lights, and emergency modes, see the Traffic Light Tutorial.

1. The State Machine

Create a file named traffic.scxml. We use the null datamodel for maximum portability (it works identically on all targets).

xml
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0"
       initial="red" datamodel="null">

    <!-- Red Light -->
    <state id="red">
        <onentry>
            <log label="Light" expr="'RED'"/>
        </onentry>
        <transition event="timer" target="green"/>
    </state>

    <!-- Green Light -->
    <state id="green">
        <onentry>
            <log label="Light" expr="'GREEN'"/>
        </onentry>
        <transition event="timer" target="yellow"/>
    </state>

    <!-- Yellow Light -->
    <state id="yellow">
        <onentry>
            <log label="Light" expr="'YELLOW'"/>
        </onentry>
        <transition event="timer" target="red"/>
    </state>

</scxml>

2. Java Implementation

Generate:

bash
scxml-gen traffic.scxml -o src/main/java/com/example/TrafficLight.java --package com.example

Run:

java
package com.example;
import com.scxmlgen.runtime.executor.ContinuousStateMachineExecutor;

public class App {
    public static void main(String[] args) throws Exception {
        TrafficLight sm = new TrafficLight();
        ContinuousStateMachineExecutor executor = new ContinuousStateMachineExecutor(sm);
        executor.start();

        System.out.println("Started. Current state: " + sm.getActiveStateIds());

        // Cycle through lights
        sm.send("timer");
        Thread.sleep(100);
        sm.send("timer");
        Thread.sleep(100);
        sm.send("timer");

        executor.close();
    }
}

3. JavaScript Implementation

Generate:

bash
scxml-gen traffic.scxml -t js -o traffic.js

Run (Node.js):

javascript
import { TrafficLight } from './traffic.js';

const sm = new TrafficLight();
sm.setLogger((msg) => console.log("[LOG]", msg));

sm.start();

// Cycle
sm.send('timer');
sm.send('timer');
sm.send('timer');

4. C Implementation

Generate:

bash
scxml-gen traffic.scxml -t c --amalgamate -o traffic.c

Run (main.c):

c
#include "traffic.h"
#include <stdio.h>
#include <unistd.h> // for sleep

int main() {
    TrafficLight sm;
    TrafficLight_init(&sm);
    TrafficLight_start(&sm);

    // Send events using generated constants
    TrafficLight_send(&sm, EVT_TIMER, NULL);
    printf("State: %d\n", TrafficLight_is_in(&sm, S_GREEN));

    TrafficLight_send(&sm, EVT_TIMER, NULL);
    TrafficLight_send(&sm, EVT_TIMER, NULL);

    return 0;
}

Compile (Linux/Mac):

bash
gcc -DSCXML_PLATFORM_POSIX traffic.c main.c -o traffic
./traffic

Advanced Tutorials

For more in-depth examples, check out these guides: