Skip to content

Commit

Permalink
simple web gui to communicate with gama headless daemon
Browse files Browse the repository at this point in the history
  • Loading branch information
hqnghi88 committed Mar 9, 2022
1 parent 82f67f8 commit d600af9
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 46 deletions.
134 changes: 108 additions & 26 deletions msi.gama.headless/SimpleGUI.html
Expand Up @@ -43,33 +43,10 @@
</style>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script>
$( function() {
$( ".column" ).sortable({
connectWith: ".column",
handle: ".portlet-header",
cancel: ".portlet-toggle",
placeholder: "portlet-placeholder ui-corner-all"
}).resizable({
grid: 100
});

$( ".portlet" )
.addClass( "ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" )
.find( ".portlet-header" )
.addClass( "ui-widget-header ui-corner-all" )
.prepend( "<span class='ui-icon ui-icon-minusthick portlet-toggle'></span>");

$( ".portlet-toggle" ).on( "click", function() {
var icon = $( this );
icon.toggleClass( "ui-icon-minusthick ui-icon-plusthick" );
icon.closest( ".portlet" ).find( ".portlet-content" ).toggle();
});
} );
</script>

</head>
<body>
<div class="column">
<div class="column" id="col1">

<div class="portlet">
<div class="portlet-header">Controller</div>
Expand All @@ -84,6 +61,7 @@
Experiment:</td><td>
<input type="text" name="message"></td></tr>
<tr><td colspan=2>
<input type="button" onclick="addWidget()" value="Add">
<input type="submit" value="Load">
<input type="submit" value="Compile">
<input type="submit" value="Launch"></td></tr>
Expand Down Expand Up @@ -134,10 +112,114 @@


<script>

init();
function rehook(){

$( function() {
$( ".column" ).sortable({
connectWith: ".column",
handle: ".portlet-header",
cancel: ".portlet-toggle",
placeholder: "portlet-placeholder ui-corner-all"
}).resizable({
grid: 100
});

$( ".portlet" )
.addClass( "ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" )
.find( ".portlet-header" )
.addClass( "ui-widget-header ui-corner-all" )
;

$( ".portlet-toggle" ).on( "click", function() {

var icon = $( this );
console.log(icon);
icon.toggleClass( "ui-icon-minusthick ui-icon-plusthick" );
icon.closest( ".portlet" ).find( ".portlet-content" ).toggle();

});
$( ".portlet-close" ).on( "click", function() {
$(this).parent().parent().remove();
});
} );
}
function init(){

$( function() {
$( ".column" ).sortable({
connectWith: ".column",
handle: ".portlet-header",
cancel: ".portlet-toggle",
placeholder: "portlet-placeholder ui-corner-all"
}).resizable({
grid: 100
});

$( ".portlet" )
.addClass( "ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" )
.find( ".portlet-header" )
.addClass( "ui-widget-header ui-corner-all" )
.prepend( "<span class='ui-icon ui-icon-closethick portlet-close'></span>")
.prepend( "<span class='ui-icon ui-icon-minusthick portlet-toggle'></span>")
;

$( ".portlet-toggle" ).on( "click", function() {

var icon = $( this );
console.log(icon);
icon.toggleClass( "ui-icon-minusthick ui-icon-plusthick" );
icon.closest( ".portlet" ).find( ".portlet-content" ).toggle();

});
$( ".portlet-close" ).on( "click", function() {
$(this).parent().parent().remove();
});
} );
}
function addWidget(){
var tag = document.createElement("div");

tag.className="portlet ui-widget ui-widget-content ui-helper-clearfix ui-corner-all";
var phead = document.createElement("div");//.createTextNode("Tutorix is the best e-learning platform");
phead.className="portlet-header ui-sortable-handle ui-widget-header ui-corner-all";
phead.textContent = "Widget";
var pspan = document.createElement("span");
pspan.className="ui-icon ui-icon-closethick portlet-close";
phead.insertBefore(pspan,phead.firstChild);
var pspan1 = document.createElement("span");
pspan1.className="ui-icon ui-icon-minusthick portlet-toggle";
phead.appendChild(pspan1);
var pcont = document.createElement("div");
pcont.className="portlet-content";
pcont.textContent = "Widget content";
tag.appendChild(phead);
tag.appendChild(pcont);

/*
var tag = document.createElement("div");
tag.className="portlet";
var phead = document.createElement("div");//.createTextNode("Tutorix is the best e-learning platform");
phead.className="portlet-header";
phead.textContent = "Widget";
var pcont = document.createElement("div");
pcont.className="portlet-content";
pcont.textContent = "Widget content";
tag.appendChild(phead);
tag.appendChild(pcont);
*/
document.getElementById("col1").appendChild(tag);

rehook();
}
$.fn.scrollBottom = function() {
return $(this).scrollTop($(this)[0].scrollHeight);
};
let socket = new WebSocket("ws://localhost:6868");
let socket = new WebSocket("ws://localhost:6868/launch");

socket.binaryType = 'arraybuffer';
// send message from the form
Expand Down
Expand Up @@ -621,6 +621,8 @@ public void runGamlSimulation(final List<String> args) throws IOException, GamaH

public void createSocketServer() throws UnknownHostException {
socketServer = new GamaWebSocketServer(this.socket,this);
socketServer.endpoints.put("/compile", new CompileEndPoint());
socketServer.endpoints.put("/launch", new LaunchEndPoint());
socketServer.start();
System.out.println("ChatServer started on port: " + socketServer.getPort());
System.setOut(new WebSocketPrintStream(System.out, socketServer));
Expand Down
@@ -0,0 +1,24 @@
package msi.gama.headless.runtime;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;

import org.java_websocket.WebSocket;

import msi.gama.headless.core.GamaHeadlessException;

public class CompileEndPoint implements Endpoint{

@Override
public void onOpen(WebSocket socket) {
socket.send("Hello!");
}

@Override
public void onMessage(GamaWebSocketServer server, WebSocket socket, String message) {
socket.send(message);

}

}
Expand Up @@ -35,11 +35,14 @@
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

Expand All @@ -54,13 +57,25 @@
/**
* A simple WebSocketServer implementation. Keeps track of a "chatroom".
*/
public class GamaWebSocketServer extends WebSocketServer {
interface Endpoint {
void onOpen(WebSocket socket);
void onMessage(GamaWebSocketServer server, WebSocket socket, String message);
// add other event handlers here
}

public class GamaWebSocketServer extends WebSocketServer {
Map<String, Endpoint> endpoints = Collections.synchronizedMap(new HashMap<>());
Map<WebSocket, Endpoint> saved_endpoints = Collections.synchronizedMap(new HashMap<>());

private Application app;

public GamaWebSocketServer(int port, Application ap) throws UnknownHostException {
super(new InetSocketAddress(port));
app=ap;
super(new InetSocketAddress(port));
app = ap;
}
public Application getDefaultApp() {
return app;
}

public GamaWebSocketServer(InetSocketAddress address) {
super(address);
}
Expand All @@ -83,6 +98,15 @@ public void onOpen(WebSocket conn, ClientHandshake handshake) {
broadcast("new connection: " + handshake.getResourceDescriptor()); // This method sends a message to all clients
// connected
System.out.println(conn.getRemoteSocketAddress().getAddress().getHostAddress() + " entered the room!");



String path = URI.create(handshake.getResourceDescriptor()).getPath();
Endpoint endpoint = endpoints.get(path);
if(endpoint != null) {
saved_endpoints.put(conn, endpoint);
endpoint.onOpen(conn);
}
}

@Override
Expand All @@ -93,22 +117,7 @@ public void onClose(WebSocket conn, int code, String reason, boolean remote) {

@Override
public void onMessage(WebSocket conn, String message) {
broadcast(message);
System.out.println(conn + ": " + message);
if(message.equals("run")) {
try {
app.runGamlSimulation (Arrays.asList("-gaml","C:\\GAMA\\headless\\samples\\toto" ,"prey_predatorExp","C:\\GAMA\\headless\\samples\\predatorPrey\\predatorPrey.gaml"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GamaHeadlessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
saved_endpoints.get(conn).onMessage(this,conn,message);
}

@Override
Expand Down
@@ -0,0 +1,75 @@
package msi.gama.headless.runtime;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import org.java_websocket.WebSocket;

import msi.gama.common.GamlFileExtension;
import msi.gama.headless.common.Globals;
import msi.gama.headless.core.GamaHeadlessException;
import msi.gama.headless.job.ExperimentJob;
import msi.gama.headless.job.IExperimentJob;
import msi.gama.headless.script.ExperimentationPlanFactory;
import msi.gama.headless.xml.XMLWriter;

public class LaunchEndPoint implements Endpoint {

@Override
public void onOpen(WebSocket socket) {
socket.send("You have connected to chat");
}

public void runGamlSimulation(GamaWebSocketServer server, final List<String> args)
throws IOException, GamaHeadlessException {
final String pathToModel = args.get(args.size() - 1);

if (!GamlFileExtension.isGaml(pathToModel)) {
System.exit(-1);
}
final String argExperimentName = args.get(args.size() - 2);
final String argGamlFile = args.get(args.size() - 1);

final List<IExperimentJob> jb = ExperimentationPlanFactory.buildExperiment(argGamlFile);
ExperimentJob selectedJob = null;
for (final IExperimentJob j : jb) {
if (j.getExperimentName().equals(argExperimentName)) {
selectedJob = (ExperimentJob) j;
break;
}
}
if (selectedJob == null)
return;
Globals.OUTPUT_PATH = args.get(args.size() - 3);

// selectedJob.setBufferedWriter(new XMLWriter(Globals.OUTPUT_PATH + "/" + Globals.OUTPUT_FILENAME + ".xml"));

// if (args.contains(THREAD_PARAMETER)) {
// this.numberOfThread = Integer.parseInt(after(args, THREAD_PARAMETER));
// } else {
// numberOfThread = SimulationRuntime.UNDEFINED_QUEUE_SIZE;
// }
server.getDefaultApp().processorQueue = new LocalSimulationRuntime(SimulationRuntime.UNDEFINED_QUEUE_SIZE);

server.getDefaultApp().processorQueue.pushSimulation(selectedJob);

}

@Override
public void onMessage(GamaWebSocketServer server, WebSocket socket, String message) {
server.broadcast(message);
System.out.println(socket + ": " + message);
if (message.equals("run")) {
try {
runGamlSimulation(server, Arrays.asList("-gaml", "C:\\GAMA\\headless\\samples\\toto",
"prey_predatorExp", "C:\\GAMA\\headless\\samples\\predatorPrey\\predatorPrey.gaml"));
} catch (IOException |GamaHeadlessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}

0 comments on commit d600af9

Please sign in to comment.