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
Branches
No related tags found
1 merge request!1festival updatesfestival updatesfestival updatesfestival updatesfestival
...@@ -6,13 +6,11 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; ...@@ -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.MotionGrammarConfig;
import de.tudresden.inf.st.mg.common.MotionGrammarParser; import de.tudresden.inf.st.mg.common.MotionGrammarParser;
import de.tudresden.inf.st.mg.common.TableDeserializer; 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.JastAddList;
import de.tudresden.inf.st.mg.jastadd.model.RobotWorld; 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.Table;
import de.tudresden.inf.st.mg.jastadd.model.World; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -21,25 +19,15 @@ import java.io.IOException; ...@@ -21,25 +19,15 @@ import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Instant;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
public class ImmersiveSortingController { public class ImmersiveSortingController {
public static final Path TIDY_AST_DIAGRAM_DIR = Path.of("src", "gen", "resources", "diagrams", "parsing", "tidy"); 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 Logger logger = LoggerFactory.getLogger(ImmersiveSortingController.class);
private static final Map<WsContext, String> clients = new ConcurrentHashMap<>();
private static ImmersiveSortingController INSTANCE;
private final RobotWorld world; private final RobotWorld world;
private ParseThread parse; private ParseThread parse;
private Diagram ast;
private Diagram context;
private boolean initialized = false;
public ImmersiveSortingController(boolean simulate) { public ImmersiveSortingController(boolean simulate) {
MotionGrammarConfig.astDiagramDir = TIDY_AST_DIAGRAM_DIR; MotionGrammarConfig.astDiagramDir = TIDY_AST_DIAGRAM_DIR;
...@@ -64,9 +52,19 @@ public class ImmersiveSortingController { ...@@ -64,9 +52,19 @@ public class ImmersiveSortingController {
e.printStackTrace(); 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.enableContextPrinting(true);
world.printContext("initial"); world.printContext("initial");
...@@ -107,20 +105,13 @@ public class ImmersiveSortingController { ...@@ -107,20 +105,13 @@ public class ImmersiveSortingController {
* on localhost:1883 * on localhost:1883
*/ */
public static void main(String[] args) { public static void main(String[] args) {
ImmersiveSortingController controller = ImmersiveSortingController.getInstance(); ImmersiveSortingController controller = new ImmersiveSortingController(false);
try { try {
Thread.sleep(Long.MAX_VALUE); Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException ignored) { } catch (InterruptedException ignored) {
} }
} }
public static ImmersiveSortingController getInstance() {
if (INSTANCE == null) {
INSTANCE = new ImmersiveSortingController(false);
}
return INSTANCE;
}
public void startParse() { public void startParse() {
if (parse != null && parse.isAlive()) { if (parse != null && parse.isAlive()) {
parse.stopParsing(); parse.stopParsing();
...@@ -141,79 +132,6 @@ public class ImmersiveSortingController { ...@@ -141,79 +132,6 @@ public class ImmersiveSortingController {
world.printContext(message); 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 { class ParseThread extends Thread {
private RobotParser parser; private RobotParser parser;
......
...@@ -3,7 +3,6 @@ package de.tudresden.inf.st.mg.common; ...@@ -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.Dumper;
import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamBooleanSetting; import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamBooleanSetting;
import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamStringSetting; 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 de.tudresden.inf.st.mg.jastadd.model.*;
import java.io.IOException; import java.io.IOException;
...@@ -34,7 +33,7 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> { ...@@ -34,7 +33,7 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> {
} }
try { try {
TimeUnit.MILLISECONDS.sleep(100); TimeUnit.MILLISECONDS.sleep(100);
} catch(InterruptedException e) { } catch (InterruptedException ignored) {
} }
} }
...@@ -84,7 +83,7 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> { ...@@ -84,7 +83,7 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> {
.skinParam(SkinParamBooleanSetting.Shadowing, false) .skinParam(SkinParamBooleanSetting.Shadowing, false)
.skinParam(SkinParamStringSetting.backgroundColor, "white") .skinParam(SkinParamStringSetting.backgroundColor, "white")
.dumpAsSVG(svgPath); .dumpAsSVG(svgPath);
ImmersiveSortingController.getInstance().publish(new Date(), timeStep_, step, svgPath, "ast"); Webserver.getInstance().publish(new Date(), timeStep_, step, svgPath, "ast");
timeStep_++; timeStep_++;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); 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