rolled back usage of CompletableFuture in favour of callbacks

This commit is contained in:
Stephan Richter
2020-10-27 16:39:11 +01:00
parent f5dbb0916a
commit ad25dd8166
11 changed files with 316 additions and 200 deletions

View File

@@ -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{
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

View File

@@ -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{
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{
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{
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;

View File

@@ -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{
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;
}
}

View File

@@ -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 {
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 {
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));

View File

@@ -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 {
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 {
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;
});
}
}