JSFiddle - React, Tailwind, and code Playground

by ifandelse

HTML

<script src="https://rawgit.com/lodash/lodash/2.4.1/dist/lodash.js"></script>
<script src="https://rawgit.com/ifandelse/machina.js/christmas/lib/machina.js"></script>
<div id="east-west" class="traffic-light stop"></div>
<div id="north-south" class="traffic-light stop"></div>

CSS

.traffic-light {
    border-radius: 50%;
    width: 150px;
    height: 150px;
    border: 1pt solid black;
    margin: 5px;
}

.stop {
    background-color: red;
}

.go {
    background-color: green;
}

.caution {
    background-color: yellow;
}

JavaScript

var trafficLightFsm = window.trafficLightFsm = new machina.BehavioralFsm({

	initialState: "disabled",
	
	states: {
	
		disabled: {
			activate: function(client, isStopped) {
				this.transition(client, isStopped ? "stop" : "go");
			}
		},
	
		stop: {
			advance : function(client) {
				this.emit("TimeToGo", { foo: "bar", client: client });
				this.transition(client, "go");
			}
		},
		
		go: {
			advance : "caution"
		},
		
		caution: {
			_onEnter: function(client) {
				this.timeout = setTimeout(function() {
					this.handle(client, "advance");
				}.bind(this), 5000);
			},
			
			advance: "stop",
			
			_onExit: function() {
				clearTimeout(this.timeout);
			}
		}
	},
	
	advance: function(client) {
		this.handle(client, "advance");
	},
	
	activateInStop: function (client) {
		this.handle(client, "activate", true);
	},
	
	activateInGo: function(client) {
		this.handle(client, "activate", false);
	}
});

// Now we can have multiple 'instances' of traffic lights that all share the same FSM:
var light1 = window.light1 = { location: "Dijsktra Ave & Hunt Blvd", direction: "north-south" };
var light2 = window.light2 = { location: "Dijsktra Ave & Hunt Blvd", direction: "east-west" };

// to use the behavioral fsm, we pass the "client" in as the first arg to API calls:
trafficLightFsm.activateInStop(light1);