|
@@ -1,35 +1,54 @@
|
|
|
package connection.socket;
|
|
|
import java.net.*;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+import classes.HolonElement;
|
|
|
+import classes.HolonObject;
|
|
|
+import ui.controller.Control;
|
|
|
+
|
|
|
import java.io.*;
|
|
|
|
|
|
public class Server implements Runnable{
|
|
|
private ServerSocket serverSocket;
|
|
|
private Socket clientSocket;
|
|
|
- private PrintWriter out;
|
|
|
- private BufferedReader in;
|
|
|
- private boolean stopped = false;
|
|
|
+ private DataOutputStream out;
|
|
|
+ private DataInputStream in;
|
|
|
+ private boolean stopped = false;
|
|
|
+ private boolean connection = false;
|
|
|
private ui.view.Console console;
|
|
|
- public Server(int port, ui.view.Console console) throws IOException {
|
|
|
+
|
|
|
+
|
|
|
+ private HolonObject observed;
|
|
|
+ private HolonObjectModel model;
|
|
|
+ private Control control;
|
|
|
+
|
|
|
+ public Server(int port, ui.view.Console console, HolonObject observed, Control control) throws IOException {
|
|
|
+ this.observed = observed;
|
|
|
+ this.console = console;
|
|
|
+ this.control = control;
|
|
|
//Bind Port
|
|
|
serverSocket = new ServerSocket(port);
|
|
|
//Wait for Connection
|
|
|
Thread serverThread = new Thread(this);
|
|
|
serverThread.start();
|
|
|
- this.console = console;
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
public void stopServer() throws IOException {
|
|
|
- stopped = false;
|
|
|
+ stopped = true;
|
|
|
stopConnection();
|
|
|
- serverSocket.close();
|
|
|
+ if(serverSocket != null)serverSocket.close();
|
|
|
+ console.println("Server Closed");
|
|
|
}
|
|
|
|
|
|
private void stopConnection() throws IOException {
|
|
|
- in.close();
|
|
|
- out.close();
|
|
|
- clientSocket.close();
|
|
|
+ connection = false;
|
|
|
+ if(in != null)in.close();
|
|
|
+ if(out != null)out.close();
|
|
|
+ if(clientSocket != null)clientSocket.close();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -37,25 +56,225 @@ public class Server implements Runnable{
|
|
|
while(!stopped) {
|
|
|
try {
|
|
|
//Wait for new Connection
|
|
|
+ console.println("Wait for Connection..");
|
|
|
clientSocket = serverSocket.accept();
|
|
|
- console.println("A Connection from " + clientSocket.getInetAddress() + ":" + clientSocket.getPort());
|
|
|
- out = new PrintWriter(clientSocket.getOutputStream(), true);
|
|
|
- in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
|
|
|
- String inputLine;
|
|
|
- while ((inputLine = in.readLine()) != null) {
|
|
|
- console.println("Res: " + inputLine);
|
|
|
- if (".".equals(inputLine)) {
|
|
|
- out.println("bye");
|
|
|
- break;
|
|
|
- }
|
|
|
- out.println(inputLine);
|
|
|
- console.println("Send: " + inputLine);
|
|
|
+ console.println("Connection from " + clientSocket.getInetAddress() + ":" + clientSocket.getPort());
|
|
|
+ connection = true;
|
|
|
+ out = new DataOutputStream(clientSocket.getOutputStream());
|
|
|
+ in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream()));
|
|
|
+ if(observed == null) stopConnection();
|
|
|
+ createModel();
|
|
|
+ Thread updateThread = new Thread(new UpdateLoop());
|
|
|
+ updateThread.start();
|
|
|
+ //InputLoop
|
|
|
+ try {
|
|
|
+ inputLoop();
|
|
|
+ }catch(EOFException e){
|
|
|
+ console.println("Connection Closed");
|
|
|
}
|
|
|
stopConnection();
|
|
|
- }catch (IOException e) {
|
|
|
+ }
|
|
|
+ catch(SocketException e){
|
|
|
+ //ServerSocket is closed
|
|
|
+ stopped = true;
|
|
|
+ }
|
|
|
+ catch (IOException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
+ connection = false;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ private void inputLoop() throws IOException {
|
|
|
+ while (connection) {
|
|
|
+ //WaitForInput
|
|
|
+ byte inputByte = in.readByte();
|
|
|
+ //UpdateHoleg
|
|
|
+ if (inputByte == Command.SetAmount) {
|
|
|
+ if(observed == null) stopConnection();
|
|
|
+ console.println("Res: [" + inputByte + "] -> SetAmount");
|
|
|
+ int index = in.readInt();
|
|
|
+ int amount = in.readInt();
|
|
|
+ observed.getElements().get(index).setAmount(amount);
|
|
|
+
|
|
|
+ }else if (inputByte == Command.SetEnable) {
|
|
|
+ if(observed == null) stopConnection();
|
|
|
+ console.println("Res: [" + inputByte + "] -> SetEnable");
|
|
|
+ int index = in.readInt();
|
|
|
+ boolean enabled = in.readBoolean();
|
|
|
+ observed.getElements().get(index).setActive(enabled);
|
|
|
+ }else if (inputByte == Command.IncreaseAmount) {
|
|
|
+ if(observed == null) stopConnection();
|
|
|
+ console.println("Res: [" + inputByte + "] -> IncreaseAmount");
|
|
|
+ int index = in.readInt();
|
|
|
+ HolonElement ele = observed.getElements().get(index);
|
|
|
+ ele.setAmount(ele.getAmount()+1);
|
|
|
+
|
|
|
+ }else if (inputByte == Command.DecreaseAmount) {
|
|
|
+ if(observed == null) stopConnection();
|
|
|
+ console.println("Res: [" + inputByte + "] -> DecreaseAmount");
|
|
|
+ int index = in.readInt();
|
|
|
+ HolonElement ele = observed.getElements().get(index);
|
|
|
+ ele.setAmount(ele.getAmount()-1);
|
|
|
+
|
|
|
+ } else{
|
|
|
+ console.println("Res: [" + inputByte + "] -> unknown");
|
|
|
+ }
|
|
|
+ control.calculateStateAndVisualForCurrentTimeStep();
|
|
|
+ control.updateCanvas();
|
|
|
+ control.getGui().triggerUpdateController(null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
+ private void createModel() {
|
|
|
+ model = new HolonObjectModel();
|
|
|
+ int index = 0;
|
|
|
+ for(HolonElement ele :observed.getElements()) {
|
|
|
+ model.add(ele, index++);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public class UpdateLoop implements Runnable{
|
|
|
+ public UpdateLoop(){
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ sendUpdate();
|
|
|
+ while(!stopped && connection) {
|
|
|
+ if(checkForUpdates()){
|
|
|
+ sendUpdate();
|
|
|
+ }else {
|
|
|
+ waitOneSecond();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void waitOneSecond() {
|
|
|
+ //wait one second
|
|
|
+ try {
|
|
|
+ TimeUnit.SECONDS.sleep(5);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean checkForUpdates() {
|
|
|
+ //TODO Delete And CheckforUpdatesReal
|
|
|
+ //-->Test
|
|
|
+ waitOneSecond();
|
|
|
+ createModel();
|
|
|
+ //<--Test
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sendUpdate() {
|
|
|
+ try {
|
|
|
+ if(observed == null) stopConnection();
|
|
|
+ console.println("Send: [" + Command.Update + "] -> Update");
|
|
|
+ out.writeByte(Command.Update);
|
|
|
+ out.writeInt(model.size());
|
|
|
+ for(HolonElementWrapper wrapper : model.getElements()) {
|
|
|
+ out.writeUTF(wrapper.name);
|
|
|
+ out.writeInt(wrapper.amount);
|
|
|
+ out.writeFloat(wrapper.energy);
|
|
|
+ out.writeBoolean(wrapper.enabled);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ } catch (IOException e) {
|
|
|
+ if(connection)console.println(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public class Command {
|
|
|
+ //InputCommands
|
|
|
+ public static final int SetAmount = 10;
|
|
|
+ public static final int SetEnable = 11;
|
|
|
+ public static final int IncreaseAmount = 12;
|
|
|
+ public static final int DecreaseAmount = 13;
|
|
|
+ //UpdateResiveCommands
|
|
|
+ public static final int Update = 20;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public class HolonObjectModel {
|
|
|
+ //Field
|
|
|
+ private List<HolonElementWrapper> elements;
|
|
|
+ private String holonObjectName;
|
|
|
+
|
|
|
+ //constructor
|
|
|
+ public HolonObjectModel(){
|
|
|
+ elements = new ArrayList<HolonElementWrapper>();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void add(HolonElement ele, int index ) {
|
|
|
+ String name = ele.getEleName();
|
|
|
+ int amount =ele.getAmount();
|
|
|
+ float energy = ele.getEnergyPerElement();
|
|
|
+ boolean enabled = ele.isActive();
|
|
|
+ elements.add(new HolonElementWrapper(name, amount, energy, enabled, index));
|
|
|
+ }
|
|
|
+
|
|
|
+ public int size() {
|
|
|
+ return elements.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ //Getter/Setter
|
|
|
+ public List<HolonElementWrapper> getElements() {
|
|
|
+ return elements;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getHolonObjectName() {
|
|
|
+ return holonObjectName;
|
|
|
+ }
|
|
|
+ public void setHolonObjectName(String holonObjectName) {
|
|
|
+ this.holonObjectName = holonObjectName;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ public class HolonElementWrapper{
|
|
|
+ public int index;
|
|
|
+ public String name;
|
|
|
+ public int amount;
|
|
|
+ public float energy;
|
|
|
+ public boolean enabled;
|
|
|
+ public HolonElementWrapper(){
|
|
|
+
|
|
|
+ }
|
|
|
+ public HolonElementWrapper(String name, int amount, float energy, boolean enabled, int index){
|
|
|
+ this.name = name;
|
|
|
+ this.amount = amount;
|
|
|
+ this.energy = energy;
|
|
|
+ this.enabled = enabled;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public boolean equals(Object obj) {
|
|
|
+ if (obj == this) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (!(obj instanceof HolonElementWrapper)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ HolonElementWrapper element = (HolonElementWrapper) obj;
|
|
|
+ return this.name == element.name &&
|
|
|
+ this.amount == element.amount &&
|
|
|
+ this.energy == element.energy &&
|
|
|
+ this.enabled == element.enabled;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|