Skip to content

Commit

Permalink
added state machine implementation to OOCSI
Browse files Browse the repository at this point in the history
  • Loading branch information
matsfunk committed Apr 10, 2016
1 parent 7cdad75 commit 2d2c9d5
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/nl/tue/id/oocsi/OOCSI.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,15 @@ public String getChannels(String channelName) {
return oocsi.isConnected() ? oocsi.channels(channelName) : "";
}

/**
* retrieve the internal OOCSICommunicator
*
* @return
*/
OOCSICommunicator getCommunicator() {
return oocsi;
}

/**
* start OOCSI with a connection and handlers
*
Expand Down
103 changes: 103 additions & 0 deletions src/nl/tue/id/oocsi/StateMachine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package nl.tue.id.oocsi;

import nl.tue.id.oocsi.client.protocol.EventHandler;
import nl.tue.id.oocsi.client.protocol.Handler;

public class StateMachine {

private nl.tue.id.oocsi.client.behavior.state.OOCSIStateMachine sm;

private OOCSICommunicator oocsi;

public StateMachine(OOCSI oocsi) {
this.oocsi = oocsi.getCommunicator();
sm = new nl.tue.id.oocsi.client.behavior.state.OOCSIStateMachine();
}

public State addState(String name, String enterAction, String executeAction, String exitAction) {
Handler enter = oocsi.createSimpleCallerHandler(enterAction);
Handler execute = oocsi.createSimpleCallerHandler(executeAction);
Handler exit = oocsi.createSimpleCallerHandler(exitAction);

sm.addState(name, enter, execute, exit);
return new State(name);
}

public State addState(String name) {
sm.addState(name, null, null, null);
return new State(name);
}

public void execute() {
sm.execute();
}

public boolean isInState(String state) {
return sm.isInState(state);
}

public String get() {
return sm.get();
}

public void set(String newState) {
sm.set(newState);
}

public class State {

private String name;

public State(String name) {
this.name = name;
}

public State enter(String enterAction) {
sm.get(name).setEnter(oocsi.createSimpleCallerHandler(enterAction));
return this;
}

public State execute(String executeAction) {
sm.get(name).setExecute(oocsi.createSimpleCallerHandler(executeAction));
return this;
}

public State exit(String exitAction) {
sm.get(name).setExit(oocsi.createSimpleCallerHandler(exitAction));
return this;
}

public void connect(String channelName, final String key) {
oocsi.subscribe(channelName, new EventHandler() {
@Override
public void receive(OOCSIEvent event) {
if (event.has(key)) {
sm.set(name);
}
}
});
}

public void connect(String channelName, final String key, final Number value) {
oocsi.subscribe(channelName, new EventHandler() {
@Override
public void receive(OOCSIEvent event) {
if (event.has(key) && event.getDouble(key, Double.MAX_VALUE) == value.doubleValue()) {
sm.set(name);
}
}
});
}

public void connect(String channelName, final String key, final String value) {
oocsi.subscribe(channelName, new EventHandler() {
@Override
public void receive(OOCSIEvent event) {
if (event.has(key) && event.getString(key, "").equals(value)) {
sm.set(name);
}
}
});
}
}
}
113 changes: 113 additions & 0 deletions test/state/TestState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package state;

import nl.tue.id.oocsi.OOCSI;
import nl.tue.id.oocsi.StateMachine;
import processing.core.PApplet;

/**
* example application - proposes a leader to be elected and waits for votes from other clients in the same channel
* "electionChannel" via OOCSI
*
* @author matsfunk
*/
@SuppressWarnings("serial")
public class TestState extends PApplet {

OOCSI oocsi;
StateMachine sm;

int brightness = 255;

public void setup() {
size(200, 200);
noStroke();
background(0);
frameRate(30);

// open connection to local OOCSI
// (for more information how to run an OOCSI server refer to: https://iddi.github.io/oocsi/)
oocsi = new OOCSI(this, ("state_" + Math.random()).toString().substring(0, 20), "localhost");

// create state machine
sm = new StateMachine(oocsi);

// add different states

// add state normal constructor version
sm.addState("rect", "blueBackground", "drawRect", "lightFill").connect("state_channel", "cornered");
sm.addState("triangle", "redBackground", "drawTriangle", "darkFill").connect("state_channel", "pointy");

// add state, telescope version
sm.addState("ellipse").enter("redBackground").execute("drawEllipse").connect("state_channel", "round");

// set starting state to "ellipse" state
sm.set("ellipse");
}

public void draw() {
// fade
fill(0, 10);
rect(0, 0, width, height);

// move to center and rotate
translate(width / 2f, height / 2f);
rotate(radians(frameCount));
fill(brightness, 70);

// call update of state machine
sm.execute();
}

public void redBackground() {
background(255, 10, 10);
}

public void blueBackground() {
background(10, 10, 250);
}

public void lightFill() {
brightness = 255;
}

public void darkFill() {
brightness = 110;
}

public void drawEllipse() {
ellipse(15, 0, 30, 30);
}

public void drawRect() {
rect(0, 0, 30, 30);
}

public void drawTriangle() {
triangle(0, 0, 30, 30, 0, 30);
}

// allow for mouse presses to forget all roles for this client
public void mousePressed() {
if (frameCount % 3 == 0) {
oocsi.channel("state_channel").data("cornered", "").send();
sm.set("rect");
} else if (frameCount % 3 == 1) {
oocsi.channel("state_channel").data("round", "").send();
sm.set("ellipse");
} else {
oocsi.channel("state_channel").data("pointy", "").send();
sm.set("triangle");
}
}

public static void main(String[] args) {
PApplet.main(new String[] { "--location=200,100", "state.TestState" });
PApplet.main(new String[] { "--location=200,320", "state.TestState" });
PApplet.main(new String[] { "--location=400,100", "state.TestState" });
PApplet.main(new String[] { "--location=400,320", "state.TestState" });
PApplet.main(new String[] { "--location=600,100", "state.TestState" });
PApplet.main(new String[] { "--location=600,320", "state.TestState" });
PApplet.main(new String[] { "--location=800,100", "state.TestState" });
PApplet.main(new String[] { "--location=800,320", "state.TestState" });
}
}

0 comments on commit 2d2c9d5

Please sign in to comment.