Skip to content
Snippets Groups Projects
Commit c85cc13d authored by Johannes Mey's avatar Johannes Mey
Browse files

restructure webserver and main controller

parent d76006ef
No related branches found
No related tags found
1 merge request!1festival updatesfestival updatesfestival updatesfestival updatesfestival
......@@ -6,13 +6,11 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import de.tudresden.inf.st.mg.common.MotionGrammarConfig;
import de.tudresden.inf.st.mg.common.MotionGrammarParser;
import de.tudresden.inf.st.mg.common.TableDeserializer;
import de.tudresden.inf.st.mg.common.Webserver;
import de.tudresden.inf.st.mg.jastadd.model.JastAddList;
import de.tudresden.inf.st.mg.jastadd.model.RobotWorld;
import de.tudresden.inf.st.mg.jastadd.model.Table;
import de.tudresden.inf.st.mg.jastadd.model.World;
import io.javalin.Javalin;
import io.javalin.core.JavalinConfig;
import io.javalin.websocket.WsContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -21,25 +19,15 @@ import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
public class ImmersiveSortingController {
public static final Path TIDY_AST_DIAGRAM_DIR = Path.of("src", "gen", "resources", "diagrams", "parsing", "tidy");
private static final Logger logger = LoggerFactory.getLogger(ImmersiveSortingController.class);
private static final Map<WsContext, String> clients = new ConcurrentHashMap<>();
private static ImmersiveSortingController INSTANCE;
private final RobotWorld world;
private ParseThread parse;
private Diagram ast;
private Diagram context;
private boolean initialized = false;
public ImmersiveSortingController(boolean simulate) {
MotionGrammarConfig.astDiagramDir = TIDY_AST_DIAGRAM_DIR;
......@@ -64,9 +52,19 @@ public class ImmersiveSortingController {
e.printStackTrace();
}
initializeWebserver();
// initialize webserver
Webserver ws = Webserver.getInstance();
ws.setCallback("cell1", (String command) -> {
logger.info("got message " + command);
if ("parse".equals(command)) {
startParse();
} else if ("reset".equals(command)) {
resetSelections();
printContext("reset selection");
}
});
initialized = true;
World.enableContextPrinting(true);
world.printContext("initial");
......@@ -107,20 +105,13 @@ public class ImmersiveSortingController {
* on localhost:1883
*/
public static void main(String[] args) {
ImmersiveSortingController controller = ImmersiveSortingController.getInstance();
ImmersiveSortingController controller = new ImmersiveSortingController(false);
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException ignored) {
}
}
public static ImmersiveSortingController getInstance() {
if (INSTANCE == null) {
INSTANCE = new ImmersiveSortingController(false);
}
return INSTANCE;
}
public void startParse() {
if (parse != null && parse.isAlive()) {
parse.stopParsing();
......@@ -141,79 +132,6 @@ public class ImmersiveSortingController {
world.printContext(message);
}
private void initializeWebserver() {
ast = new Diagram(new Date(), 0, "<no rule>", "", "ast");
context = new Diagram(Date.from(Instant.now()), 0, "<no rule>", "", "context");
Javalin webserver = Javalin.create(JavalinConfig::enableCorsForAllOrigins).start(7070);
webserver.get("/", ctx -> ctx.result("the context is delivered at /context and the ast is delivered at /ast"));
webserver.get("/ast/", ctx -> {
ctx.json(ast);
});
webserver.get("/context/", ctx -> {
ctx.json(context);
});
webserver.ws("ast-events", ws -> {
ws.onConnect(ctx -> {
System.err.println("somebody connected " + ctx.host());
clients.put(ctx, ctx.host());
});
ws.onClose(ctx -> {
System.err.println("somebody disconnected");
clients.remove(ctx);
});
ws.onMessage(ctx -> {
if (initialized) {
logger.info("got message " + ctx.message());
} else {
logger.error("ignoring message " + ctx.message() + ", because system is not initialized yet");
return;
}
if ("parse".equals(ctx.message())) {
startParse();
} else if ("reset".equals(ctx.message())) {
resetSelections();
printContext("reset selection");
}
});
});
}
public void publish(Date timestamp, int step, String parseRule, Path diagramPath, String type) {
try {
if ("ast".equals(type)) {
ast = new Diagram(timestamp, step, parseRule, Files.readString(diagramPath), type);
clients.keySet().forEach(session -> session.send(ast));
} else if ("context".equals(type)) {
context = new Diagram(timestamp, step, parseRule, Files.readString(diagramPath), type);
clients.keySet().forEach(session -> session.send(context));
}
} catch (IOException e) {
System.err.println("Unable to read " + type + " diagram file " + diagramPath);
e.printStackTrace();
}
}
public static class Diagram {
public Date timestamp;
public int step;
public String parseRule;
public String diagram;
public String type;
public Diagram(Date timestamp, int step, String parseRule, String diagram, String type) {
this.timestamp = timestamp;
this.step = step;
this.parseRule = parseRule;
this.diagram = diagram;
this.type = type;
}
}
class ParseThread extends Thread {
private RobotParser parser;
......
......@@ -3,7 +3,6 @@ package de.tudresden.inf.st.mg.common;
import de.tudresden.inf.st.jastadd.dumpAst.ast.Dumper;
import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamBooleanSetting;
import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamStringSetting;
import de.tudresden.inf.st.mg.ImmersiveSortingController;
import de.tudresden.inf.st.mg.jastadd.model.*;
import java.io.IOException;
......@@ -34,7 +33,7 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> {
}
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch(InterruptedException e) {
} catch (InterruptedException ignored) {
}
}
......@@ -84,7 +83,7 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> {
.skinParam(SkinParamBooleanSetting.Shadowing, false)
.skinParam(SkinParamStringSetting.backgroundColor, "white")
.dumpAsSVG(svgPath);
ImmersiveSortingController.getInstance().publish(new Date(), timeStep_, step, svgPath, "ast");
Webserver.getInstance().publish(new Date(), timeStep_, step, svgPath, "ast");
timeStep_++;
} catch (IOException e) {
e.printStackTrace();
......
package de.tudresden.inf.st.mg.common;
import io.javalin.Javalin;
import io.javalin.core.JavalinConfig;
import io.javalin.websocket.WsContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
public class Webserver {
private static final Logger logger = LoggerFactory.getLogger(Webserver.class);
private final Map<WsContext, String> clients = new ConcurrentHashMap<>();
private static Webserver INSTANCE;
private Diagram ast;
private Diagram context;
private final Map<String, Consumer<String>> callbacks = new ConcurrentHashMap<>();
private Webserver() {
ast = new Diagram(new Date(), 0, "<no rule>", "", "ast");
context = new Diagram(Date.from(Instant.now()), 0, "<no rule>", "", "context");
Javalin webserver = Javalin.create(JavalinConfig::enableCorsForAllOrigins).start(7070);
webserver.get("/", ctx -> ctx.result("the context is delivered at /context and the ast is delivered at /ast"));
webserver.get("/ast/", ctx -> {
ctx.json(ast);
});
webserver.get("/context/", ctx -> {
ctx.json(context);
});
webserver.ws("ast-events", ws -> {
ws.onConnect(ctx -> {
System.err.println("somebody connected " + ctx.host());
clients.put(ctx, ctx.host());
});
ws.onClose(ctx -> {
System.err.println("somebody disconnected");
clients.remove(ctx);
});
ws.onMessage(ctx -> {
String[] splitString = ctx.message().split("\\s");
if (splitString.length == 2) {
if (callbacks.containsKey(splitString[0])) {
callbacks.get(splitString[0]).accept(splitString[1]);
}
} else {
logger.error("Unable to execute command, because it does not fit the command syntax: " + ctx.message());
}
});
});
}
public static Webserver getInstance() {
if (INSTANCE == null) {
INSTANCE = new Webserver();
}
return INSTANCE;
}
public void setCallback(String client, Consumer<String> callback) {
callbacks.put(client, callback);
}
public void publish(Date timestamp, int step, String parseRule, Path diagramPath, String type) {
try {
if ("ast".equals(type)) {
ast = new Diagram(timestamp, step, parseRule, Files.readString(diagramPath), type);
clients.keySet().forEach(session -> session.send(ast));
} else if ("context".equals(type)) {
context = new Diagram(timestamp, step, parseRule, Files.readString(diagramPath), type);
clients.keySet().forEach(session -> session.send(context));
}
} catch (IOException e) {
System.err.println("Unable to read " + type + " diagram file " + diagramPath);
e.printStackTrace();
}
}
public static class Diagram {
public Date timestamp;
public int step;
public String parseRule;
public String diagram;
public String type;
public Diagram(Date timestamp, int step, String parseRule, String diagram, String type) {
this.timestamp = timestamp;
this.step = step;
this.parseRule = parseRule;
this.diagram = diagram;
this.type = type;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment