Browse Source

rolled back usage of CompletableFuture in favour of callbacks

lookup-tables
Stephan Richter 5 years ago
parent
commit
ad25dd8166
  1. 90
      src/main/java/de/srsoftware/web4rail/Command.java
  2. 123
      src/main/java/de/srsoftware/web4rail/ControlUnit.java
  3. 5
      src/main/java/de/srsoftware/web4rail/Plan.java
  4. 67
      src/main/java/de/srsoftware/web4rail/Route.java
  5. 25
      src/main/java/de/srsoftware/web4rail/moving/Locomotive.java
  6. 29
      src/main/java/de/srsoftware/web4rail/moving/Train.java
  7. 4
      src/main/java/de/srsoftware/web4rail/tiles/Signal.java
  8. 64
      src/main/java/de/srsoftware/web4rail/tiles/Turnout.java
  9. 16
      src/main/java/de/srsoftware/web4rail/tiles/Turnout3E.java
  10. 48
      src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java
  11. 39
      src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java

90
src/main/java/de/srsoftware/web4rail/Command.java

@ -1,21 +1,103 @@ @@ -1,21 +1,103 @@
package de.srsoftware.web4rail;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.Date;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Command extends CompletableFuture<ControlUnit.Reply> {
public class Command {
private static final Logger LOG = LoggerFactory.getLogger(Command.class);
private String command;
private Reply reply = null;
public static class Reply{
private long secs;
private int milis;
private int code;
private String message;
public Reply(Scanner scanner) {
String word = scanner.next();
secs = Long.parseLong(word.substring(0, word.length()-4));
milis = Integer.parseInt(word.substring(word.length()-3));
code = scanner.nextInt();
message = scanner.nextLine().trim();
LOG.info("recv {}.{} {} {}.",secs,milis,code,message);
}
public Reply(int code, String message) {
secs = new Date().getTime();
milis = (int) (secs % 1000);
secs /= 1000;
this.code = code;
this.message = message;
}
public boolean is(int code) {
return code == this.code;
}
public boolean succeeded() {
return (code > 199 && code < 300);
}
public String message() {
return message;
}
@Override
public String toString() {
return "Reply("+secs+"."+milis+" / "+code+" / "+message+")";
}
}
public Command(String command) {
this.command = command;
this.orTimeout(500, TimeUnit.MILLISECONDS);
LOG.debug("Created new Command({}).",command);
}
protected void onFailure(Reply reply) {
LOG.warn("onFailure({})",command);
}
public void onResponse(Reply reply) {
this.reply = reply;
if (reply.succeeded()) {
onSuccess();
} else onFailure(reply);
}
public void onSuccess(){
LOG.debug("onSuccess({})",command);
}
public void readReplyFrom(Scanner scanner) {
onResponse(new Reply(scanner));
}
public Reply reply() throws TimeoutException {
return reply(100);
}
public Reply reply(int timeout) throws TimeoutException {
int counter = 0;
while (reply == null) try {
if (counter++ > timeout) timeout();
Thread.sleep(10);
} catch (InterruptedException e) {
LOG.warn("wait() interrupted!",e);
}
return reply;
}
private void timeout() throws TimeoutException {
String msg = command;
command = null;
throw new TimeoutException("\""+msg+"\" timed out!");
}
@Override
public String toString() {

123
src/main/java/de/srsoftware/web4rail/ControlUnit.java

@ -10,6 +10,7 @@ import java.nio.charset.StandardCharsets; @@ -10,6 +10,7 @@ import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;
import org.json.JSONObject;
import org.slf4j.Logger;
@ -26,44 +27,10 @@ public class ControlUnit extends Thread implements Constants{ @@ -26,44 +27,10 @@ public class ControlUnit extends Thread implements Constants{
private static final Logger LOG = LoggerFactory.getLogger(ControlUnit.class);
private static final String DEFAULT_HOST = "localhost";
private static final int DEFAULT_PORT = 4303;
private static final int OK_PROTO = 201;
private static final int OK_MODE = 202;
private static final int OK = 200;
private static final String HOST = "host";
private static final String PORT = "port";
private static final String BUS = "bus";
public class Reply{
private long secs;
private int milis;
private int code;
private String message;
public Reply(Scanner scanner) {
String word = scanner.next();
secs = Long.parseLong(word.substring(0, word.length()-4));
milis = Integer.parseInt(word.substring(word.length()-3));
code = scanner.nextInt();
message = scanner.nextLine().trim();
LOG.info("recv {}.{} {} {}.",secs,milis,code,message);
}
public String message() {
return message;
}
@Override
public String toString() {
return "Reply("+secs+"."+milis+" / "+code+" / "+message+")";
}
public boolean is(int code) {
return code == this.code;
}
}
private String host = DEFAULT_HOST;
private int port = DEFAULT_PORT;
private int bus = 0;
@ -72,6 +39,11 @@ public class ControlUnit extends Thread implements Constants{ @@ -72,6 +39,11 @@ public class ControlUnit extends Thread implements Constants{
private Socket socket;
private Scanner scanner;
private boolean power = false;
private Plan plan;
public ControlUnit(Plan plan) {
this.plan = plan;
}
/**
* @return stops the loop at the next interval
@ -81,7 +53,7 @@ public class ControlUnit extends Thread implements Constants{ @@ -81,7 +53,7 @@ public class ControlUnit extends Thread implements Constants{
return this;
}
private void handshake() throws IOException {
private void handshake() throws TimeoutException, IOException {
String proto = null;
if (scanner.hasNext()) {
String line = scanner.nextLine();
@ -92,18 +64,19 @@ public class ControlUnit extends Thread implements Constants{ @@ -92,18 +64,19 @@ public class ControlUnit extends Thread implements Constants{
}
if (proto == null) throw new IOException("Handshake failed: "+line);
if (!proto.startsWith("0.8.")) throw new IOException("Unsupported protocol: "+proto);
writeln("SET PROTOCOL SRCP "+proto);
} else throw new IOException("Handshake expected.");
Command command = new Command("SET PROTOCOL SRCP "+proto);
send(command);
if (!command.reply().succeeded()) throw new IOException("Handshake failed: "+command.reply());
Reply reply = new Reply(scanner);
if (reply.code != OK_PROTO) throw new IOException("Handshake failed: "+reply);
command = new Command("SET CONNECTIONMODE SRCP COMMAND"); // preset following mode: COMMAND MODE
send(command);
if (!command.reply().succeeded()) throw new IOException("Handshake failed: "+command.reply());
writeln("SET CONNECTIONMODE SRCP COMMAND"); // preset following mode: COMMAND MODE
reply = new Reply(scanner);
if (reply.code != OK_MODE) throw new IOException("Handshake failed: "+reply);
writeln("GO"); // switch mode
reply = new Reply(scanner);
if (reply.code != OK) throw new IOException("Handshake failed: "+reply);
command = new Command("GO"); // switch mode
send(command);
if (!command.reply().succeeded()) throw new IOException("Handshake failed: "+command.reply());
}
private JSONObject json() {
@ -124,10 +97,21 @@ public class ControlUnit extends Thread implements Constants{ @@ -124,10 +97,21 @@ public class ControlUnit extends Thread implements Constants{
}
public static void main(String[] args) throws InterruptedException {
ControlUnit cu = new ControlUnit().setEndpoint("Modellbahn", DEFAULT_PORT).setBus(1).restart();
ControlUnit cu = new ControlUnit(null).setEndpoint("Modellbahn", DEFAULT_PORT).setBus(1).restart();
Thread.sleep(1000);
cu.queue("SET {} POWER ON");
cu.queue("SET {} GL 1 0 10 128");
cu.queue(new Command("SET {} POWER ON") {
@Override
public void onSuccess() {
LOG.debug("Power on");
}
@Override
public void onFailure(Reply reply) {
LOG.debug("Was not able to turn power on: {}",reply.message());
}
});
Thread.sleep(1000);
cu.end();
}
@ -166,10 +150,9 @@ public class ControlUnit extends Thread implements Constants{ @@ -166,10 +150,9 @@ public class ControlUnit extends Thread implements Constants{
return win;
}
public Command queue(String command) {
Command promise = new Command(command);
queue.add(promise);
return promise;
public Command queue(Command command) {
queue.add(command);
return command;
}
/**
@ -190,7 +173,7 @@ public class ControlUnit extends Thread implements Constants{ @@ -190,7 +173,7 @@ public class ControlUnit extends Thread implements Constants{
Thread.sleep(10);
} else {
Command command = queue.pop();
command.complete(send(command));
send(command);
}
} catch (InterruptedException | IOException e) {
e.printStackTrace();
@ -215,10 +198,12 @@ public class ControlUnit extends Thread implements Constants{ @@ -215,10 +198,12 @@ public class ControlUnit extends Thread implements Constants{
* @return
* @throws IOException
*/
private Reply send(Command command) throws IOException {
if (command == null) return null;
writeln(command.toString());
return new Reply(scanner);
private void send(Command command) throws IOException {
if (command == null || command.toString() == null) return;
String data = command.toString().replace("{}", ""+bus);
socket.getOutputStream().write((data+"\n").getBytes(StandardCharsets.US_ASCII));
LOG.info("sent {}.",data);
command.readReplyFrom(scanner);
}
private ControlUnit setBus(int bus) {
@ -239,7 +224,7 @@ public class ControlUnit extends Thread implements Constants{ @@ -239,7 +224,7 @@ public class ControlUnit extends Thread implements Constants{
scanner = new Scanner(socket.getInputStream());
handshake();
stopped = false;
} catch (IOException e) {
} catch (IOException | TimeoutException e) {
throw new IllegalStateException(e);
}
super.start();
@ -249,11 +234,23 @@ public class ControlUnit extends Thread implements Constants{ @@ -249,11 +234,23 @@ public class ControlUnit extends Thread implements Constants{
return Translation.get(Application.class, text, fills);
}
private Object togglePower() {
private Command togglePower() {
power = !power;
String PW = power?"ON":"OFF";
queue("SET {} POWER "+PW);
return t("Turned power {}.",PW);
Command command = new Command("SET {} POWER "+PW) {
@Override
public void onSuccess() {
plan.stream(t("Turned power {}.",PW));
}
@Override
public void onFailure(Reply reply) {
plan.stream(t("Was not able to turn power {}!",PW));
}
};
return queue(command);
}
@ -263,10 +260,4 @@ public class ControlUnit extends Thread implements Constants{ @@ -263,10 +260,4 @@ public class ControlUnit extends Thread implements Constants{
if (params.containsKey(BUS)) bus = Integer.parseInt(params.get(BUS));
return t("Updated control unit settings");
}
private void writeln(String data) throws IOException {
data = data.replace("{}", ""+bus);
socket.getOutputStream().write((data+"\n").getBytes(StandardCharsets.US_ASCII));
LOG.info("sent {}.",data);
}
}

5
src/main/java/de/srsoftware/web4rail/Plan.java

@ -13,7 +13,6 @@ import java.util.Map; @@ -13,7 +13,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.Vector;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -100,7 +99,7 @@ public class Plan implements Constants{ @@ -100,7 +99,7 @@ public class Plan implements Constants{
public HashMap<String,Tile> tiles = new HashMap<String,Tile>();
private HashSet<Block> blocks = new HashSet<Block>();
private HashMap<Integer, Route> routes = new HashMap<Integer, Route>();
private ControlUnit controlUnit = new ControlUnit();
private ControlUnit controlUnit = new ControlUnit(this);
public Plan() {
new Heartbeat().start();
@ -520,7 +519,7 @@ public class Plan implements Constants{ @@ -520,7 +519,7 @@ public class Plan implements Constants{
stream(t("Warning: {}",t("Ghost train @ {}",contact)));
}
public CompletableFuture<ControlUnit.Reply> queue(String command) {
public Command queue(Command command) {
return controlUnit.queue(command);
}
}

67
src/main/java/de/srsoftware/web4rail/Route.java

@ -6,13 +6,13 @@ import java.io.FileReader; @@ -6,13 +6,13 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import java.util.concurrent.CompletableFuture;
import org.json.JSONArray;
import org.json.JSONException;
@ -22,7 +22,6 @@ import org.slf4j.LoggerFactory; @@ -22,7 +22,6 @@ import org.slf4j.LoggerFactory;
import de.keawe.tools.translations.Translation;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.ControlUnit.Reply;
import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.actions.Action;
import de.srsoftware.web4rail.actions.ActivateRoute;
@ -292,34 +291,20 @@ public class Route implements Constants{ @@ -292,34 +291,20 @@ public class Route implements Constants{
file.close();
}
public CompletableFuture<Reply> lock(Train train) throws IOException {
Vector<Tile> locked = new Vector<Tile>();
public boolean lock() {
ArrayList<Tile> lockedTiles = new ArrayList<Tile>();
try {
for (Tile tile : path) locked.add(tile.lock(this)); // try to lock all tiles along the path
} catch (Exception e) { // if something fails: unlock all tiles locked so far
for (Tile tile : locked) try {
for (Tile tile : path) lockedTiles.add(tile.lock(this));
} catch (IOException e) {
for (Tile tile: lockedTiles) try {
tile.unlock();
} catch (IOException ex) {
LOG.warn("Problem while unlocking {}",ex);
} catch (IOException inner) {
LOG.warn("Was not able to unlock {}!",tile,inner);
}
throw e;
return false;
}
CompletableFuture<Reply> promise = null;
for (Entry<Turnout, State> entry : turnouts.entrySet()) {// try to switch all turnouts of this route
CompletableFuture<Reply> reply = entry.getKey().state(entry.getValue()); // switching a turnout is an asynchronous process, so it returns a CompletableFuture here
promise = promise == null ? reply : promise.thenCombine(reply, (a,b) -> a);
}
if (promise == null) promise = CompletableFuture.completedFuture(null);
promise.exceptionally(ex -> {
for (Tile tile : locked) try {
tile.unlock();
} catch (IOException e) {
LOG.warn("Problem while unlocking {}",e);
}
throw new RuntimeException(ex);
}).thenRun(() -> this.train = train);
return promise;
return true;
}
public List<Route> multiply(int size) {
@ -413,9 +398,27 @@ public class Route implements Constants{ @@ -413,9 +398,27 @@ public class Route implements Constants{
if (lastTile instanceof Turnout) addTurnout((Turnout) lastTile,state);
}
public Route setSignals(String state) throws IOException {
for (Signal signal : signals) signal.state(state == null ? "go" : state);
return this;
public boolean setSignals(String state) throws IOException {
for (Signal signal : signals) {
if (!signal.state(state == null ? Signal.GO : state)) return false;
}
return true;
}
public boolean setTurnouts() {
Turnout turnout = null;
for (Entry<Turnout, State> entry : turnouts.entrySet()) try {
turnout = entry.getKey();
State targetVal = entry.getValue();
if (!turnout.state(targetVal).succeeded()) return false;
try {
Thread.sleep(500);
} catch (InterruptedException e) {}
} catch (IOException e) {
LOG.warn("Was not able to switch turnout {}!",turnout,e);
return false;
}
return true;
}
public Route start(Block block,Direction from) {
@ -443,6 +446,12 @@ public class Route implements Constants{ @@ -443,6 +446,12 @@ public class Route implements Constants{
return getClass().getSimpleName()+"("+name()+")";
}
public boolean train(Train train) {
if (this.train != null && this.train != train) return false;
this.train = train;
return true;
}
public Route unlock() throws IOException {
setSignals(Signal.STOP);
for (Tile tile : path) tile.unlock();

25
src/main/java/de/srsoftware/web4rail/moving/Locomotive.java

@ -7,6 +7,7 @@ import java.util.Vector; @@ -7,6 +7,7 @@ import java.util.Vector;
import org.json.JSONObject;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.Command;
import de.srsoftware.web4rail.Constants;
import de.srsoftware.web4rail.Device;
import de.srsoftware.web4rail.Plan;
@ -146,7 +147,20 @@ public class Locomotive extends Car implements Constants,Device{ @@ -146,7 +147,20 @@ public class Locomotive extends Car implements Constants,Device{
case ZIMO:
proto = "Z"; break;
}
plan.queue("INIT {} GL "+address+" "+proto);
plan.queue(new Command("INIT {} GL "+address+" "+proto) {
@Override
public void onSuccess() {
super.onSuccess();
plan.stream(t("{} initialized.",this));
}
@Override
public void onFailure(Reply r) {
super.onFailure(r);
plan.stream(t("Was not able to initialize {}!",this));
}
});
init = true;
}
@ -226,7 +240,14 @@ public class Locomotive extends Car implements Constants,Device{ @@ -226,7 +240,14 @@ public class Locomotive extends Car implements Constants,Device{
}
private void queue() {
plan.queue("SET {} GL "+address+" "+(reverse?1:0)+" "+speed+" "+VMAX+" "+(f1?1:0)+" "+(f2?1:0)+" "+(f3?1:0)+" "+(f4?1:0));
plan.queue(new Command("SET {} GL "+address+" "+(reverse?1:0)+" "+speed+" "+VMAX+" "+(f1?1:0)+" "+(f2?1:0)+" "+(f3?1:0)+" "+(f4?1:0)) {
@Override
public void onFailure(Reply reply) {
super.onFailure(reply);
plan.stream(t("Failed to send command to {}: {}",this,reply.message()));
}
});
}
public String setSpeed(int newSpeed) {

29
src/main/java/de/srsoftware/web4rail/moving/Train.java

@ -23,6 +23,7 @@ import de.srsoftware.web4rail.Application; @@ -23,6 +23,7 @@ import de.srsoftware.web4rail.Application;
import de.srsoftware.web4rail.Constants;
import de.srsoftware.web4rail.Plan;
import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.actions.SetSignalsToStop;
import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.Window;
import de.srsoftware.web4rail.tags.Button;
@ -366,22 +367,18 @@ public class Train implements Constants { @@ -366,22 +367,18 @@ public class Train implements Constants {
if (availableRoutes.isEmpty()) return t("No free routes from {}",block);
route = availableRoutes.get(rand.nextInt(availableRoutes.size()));
route.lock(this).thenApply(reply -> {
try {
route.setSignals(null);
if (direction != route.startDirection) turn();
setSpeed(100);
return t("started {}",this);
} catch (Exception e) {
throw new RuntimeException(e);
}
}).thenAccept(message -> plan.stream(message))
.exceptionally(ex -> {
plan.stream(ex.getMessage());
throw new RuntimeException(ex);
});
return t("Trying to start {}",this);
if (!route.lock()) return t("Was not able to lock {}",route);
String error = null;
if (!route.setTurnouts()) error = t("Was not able to set all turnouts!");
if (error == null && !route.setSignals(null)) error = t("Was not able to set all signals!");
if (error == null && !route.train(this)) error = t("Was not able to assign {} to {}!",this,route);
if (error == null) {
setSpeed(128);
return t("Started {}",this);
}
route.unlock();
this.block.train(this); // re-set train on previous block
return error;
}
private Object stop() {

4
src/main/java/de/srsoftware/web4rail/tiles/Signal.java

@ -10,6 +10,7 @@ import de.srsoftware.web4rail.Plan.Direction; @@ -10,6 +10,7 @@ import de.srsoftware.web4rail.Plan.Direction;
public abstract class Signal extends Tile{
public static final String STOP = "stop";
public static final String GO = "go";
private String state = STOP;
public Signal() {
@ -25,9 +26,10 @@ public abstract class Signal extends Tile{ @@ -25,9 +26,10 @@ public abstract class Signal extends Tile{
public abstract boolean isAffectedFrom(Direction dir);
public void state(String state) throws IOException {
public boolean state(String state) throws IOException {
this.state = state;
plan.stream("place "+tag(null));
return true;
}
@Override

64
src/main/java/de/srsoftware/web4rail/tiles/Turnout.java

@ -3,12 +3,13 @@ package de.srsoftware.web4rail.tiles; @@ -3,12 +3,13 @@ package de.srsoftware.web4rail.tiles;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeoutException;
import org.json.JSONObject;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.ControlUnit.Reply;
import de.srsoftware.web4rail.Command;
import de.srsoftware.web4rail.Command.Reply;
import de.srsoftware.web4rail.Device;
import de.srsoftware.web4rail.Protocol;
import de.srsoftware.web4rail.tags.Fieldset;
@ -41,6 +42,8 @@ public abstract class Turnout extends Tile implements Device{ @@ -41,6 +42,8 @@ public abstract class Turnout extends Tile implements Device{
init();
return super.click();
}
protected abstract String commandFor(State newState);
public void error(Reply reply) {
this.error = true;
@ -52,11 +55,30 @@ public abstract class Turnout extends Tile implements Device{ @@ -52,11 +55,30 @@ public abstract class Turnout extends Tile implements Device{
throw new RuntimeException(reply.message());
}
protected void init() {
protected Reply init() {
if (!initialized) {
plan.queue("INIT {} GA "+address+" "+proto());
initialized = true;
Command command = new Command("INIT {} GA "+address+" "+proto()) {
@Override
public void onSuccess() {
super.onSuccess();
initialized = true;
}
@Override
public void onFailure(Reply r) {
super.onSuccess();
initialized = false;
}
};
try {
return plan.queue(command).reply();
} catch (TimeoutException e) {
LOG.warn(e.getMessage());
}
}
return new Reply(200, "OK");
}
@Override
@ -111,7 +133,37 @@ public abstract class Turnout extends Tile implements Device{ @@ -111,7 +133,37 @@ public abstract class Turnout extends Tile implements Device{
return state;
}
public abstract CompletableFuture<Reply> state(State newState) throws IOException;
public Reply state(State newState) throws IOException {
Reply reply = init();
if (reply != null && !reply.succeeded()) return reply;
LOG.debug("Setting {} to {}",this,newState);
try {
String cmd = commandFor(newState);
return plan.queue(new Command(cmd) {
@Override
public void onSuccess() {
super.onSuccess();
try {
Turnout.this.state = newState;
plan.place(Turnout.this);
} catch (IOException e) {}
}
@Override
protected void onFailure(Reply reply) {
super.onFailure(reply);
plan.stream(t("Unable to switch {}: {}",this,reply.message()));
}
}).reply();
} catch (TimeoutException e) {
LOG.warn(e.getMessage());
}
return new Reply(417,t("Timeout while trying to switch {}.",this));
}
public void success() {
this.error = false;

16
src/main/java/de/srsoftware/web4rail/tiles/Turnout3E.java

@ -1,16 +1,19 @@ @@ -1,16 +1,19 @@
package de.srsoftware.web4rail.tiles;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import de.srsoftware.web4rail.Connector;
import de.srsoftware.web4rail.ControlUnit.Reply;
import de.srsoftware.web4rail.Plan.Direction;
public class Turnout3E extends Turnout{
@Override
public String commandFor(State newState) {
LOG.warn("Turnout3E.state({}) not implemented, yet!",newState);
throw new IllegalStateException();
}
@Override
public Map<Connector, State> connections(Direction from) {
switch (from) {
@ -29,11 +32,4 @@ public class Turnout3E extends Turnout{ @@ -29,11 +32,4 @@ public class Turnout3E extends Turnout{
return new HashMap<>();
}
}
@Override
public CompletableFuture<Reply> state(State newState) throws IOException {
// TODO Auto-generated method stub
LOG.warn("Turnout3E.state({}) not implemented, yet!",newState);
return null;
}
}

48
src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java

@ -2,10 +2,8 @@ package de.srsoftware.web4rail.tiles; @@ -2,10 +2,8 @@ package de.srsoftware.web4rail.tiles;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.ControlUnit.Reply;
import de.srsoftware.web4rail.tags.Fieldset;
import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Label;
@ -19,16 +17,22 @@ public class TurnoutL extends Turnout { @@ -19,16 +17,22 @@ public class TurnoutL extends Turnout {
Object o = super.click();
if (route != null) {
plan.stream(t("{} is locked by {}!",this,route));
} else {
CompletableFuture<Reply> promise = state(state == State.STRAIGHT ? State.LEFT : State.STRAIGHT);
promise.exceptionally(ex -> {
LOG.warn("Failed to toggle turnout: ",ex);
throw new RuntimeException(ex);
}).thenAccept(reply -> LOG.debug("Success: {}",reply));
}
} else state(state == State.STRAIGHT ? State.LEFT : State.STRAIGHT);
return o;
}
@Override
protected String commandFor(State newState) {
switch (newState) {
case LEFT:
return "SET {} GA "+address+" "+portB+" 1 "+delay;
case STRAIGHT:
return "SET {} GA "+address+" "+portA+" 1 "+delay;
default:
throw new IllegalStateException();
}
}
@Override
public Tag propForm() {
Tag form = super.propForm();
@ -43,31 +47,7 @@ public class TurnoutL extends Turnout { @@ -43,31 +47,7 @@ public class TurnoutL extends Turnout {
new Input(LEFT, portB).numeric().addTo(new Label(t("Left port"))).addTo(fieldset);
return form;
}
@Override
public CompletableFuture<Reply> state(State newState) throws IOException {
init();
LOG.debug("Requesting to set {} to {}",this,newState);
CompletableFuture<Reply> result;
switch (newState) {
case LEFT:
result = plan.queue("SET {} GA "+address+" "+portB+" 1 "+delay);
break;
case STRAIGHT:
result = plan.queue("SET {} GA "+address+" "+portA+" 1 "+delay);
break;
default:
throw new IllegalStateException();
}
return result.thenApply(reply -> {
LOG.debug("{} received {}",getClass().getSimpleName(),reply);
if (!reply.is(200)) error(reply);
state = newState;
success();
return reply;
});
}
@Override
public Tile update(HashMap<String, String> params) throws IOException {
if (params.containsKey(STRAIGHT)) portA = Integer.parseInt(params.get(STRAIGHT));

39
src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java

@ -2,10 +2,8 @@ package de.srsoftware.web4rail.tiles; @@ -2,10 +2,8 @@ package de.srsoftware.web4rail.tiles;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.ControlUnit.Reply;
import de.srsoftware.web4rail.tags.Fieldset;
import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Label;
@ -23,6 +21,19 @@ public class TurnoutR extends Turnout { @@ -23,6 +21,19 @@ public class TurnoutR extends Turnout {
return o;
}
@Override
public String commandFor(State newState) {
switch (newState) {
case RIGHT:
return "SET {} GA "+address+" "+portB+" 1 "+delay;
case STRAIGHT:
return "SET {} GA "+address+" "+portA+" 1 "+delay;
default:
throw new IllegalStateException();
}
}
@Override
public Tag propForm() {
Tag form = super.propForm();
@ -44,28 +55,4 @@ public class TurnoutR extends Turnout { @@ -44,28 +55,4 @@ public class TurnoutR extends Turnout {
if (params.containsKey(RIGHT)) portB = Integer.parseInt(params.get(RIGHT));
return super.update(params);
}
@Override
public CompletableFuture<Reply> state(State newState) throws IOException {
init();
LOG.debug("Setting {} to {}",this,newState);
CompletableFuture<Reply> result;
switch (newState) {
case RIGHT:
result = plan.queue("SET {} GA "+address+" "+portB+" 1 "+delay);
break;
case STRAIGHT:
result = plan.queue("SET {} GA "+address+" "+portA+" 1 "+delay);
break;
default:
throw new IllegalStateException();
}
return result.thenApply(reply -> {
LOG.debug("{} received {}",getClass().getSimpleName(),reply);
if (!reply.is(200)) error(reply);
state = newState;
success();
return reply;
});
}
}

Loading…
Cancel
Save