Commit 512137ae authored by Stefan Michel's avatar Stefan Michel

-Thread handling veraendert:

-es wird immernoch das deprectaded stop() genutzt
-pause ist disabled, da die genaue funktionsweise nicht bekannt ist
-thread stoppt wenn hamster gegen eine mauer oder eine wand laeuft
-code duplication entfernt: jetzt in selectionLogic methode
-geschwindigkeitsslider funktioniert
-zustand des feldes laesst sich niht veraendern waehrend ein thread laeuft
parent d33a3e05
package model;
import application.Main;
import model.exceptions.BorderException;
import model.exceptions.NoCornException;
import model.exceptions.WallException;
......@@ -10,6 +11,7 @@ import model.exceptions.WallException;
public class Hamster extends Thread {
private Terrain terrain;
private volatile boolean running;
public Hamster() {
}
......@@ -26,11 +28,15 @@ public class Hamster extends Thread {
int nextCol = getNextCol();
int nextRow = getNextRow();
if (!freeFront()) {
throw new BorderException();
}
if (!terrain.setHamsterPostion(nextCol, nextRow)) {
throw new WallException("Hier steht eine Wand");
}
} catch (RuntimeException e) {
} catch (WallException | BorderException e) {
Main.playDeathSound();
stopHamster();
}
}
......@@ -98,6 +104,21 @@ public class Hamster extends Thread {
@Invisible
public void run() {
running = true;
main();
running = false;
terrain.setChanged();
terrain.notifyObservers();
}
public void stopHamster() {
super.stop();
running = false;
terrain.setChanged();
terrain.notifyObservers();
}
public boolean isRunning() {
return this.running;
}
}
......@@ -32,6 +32,7 @@ public class Terrain extends Observable {
int hamsterCorns = 0;
int[][] map;
private double speed;
public Terrain() {
......@@ -54,7 +55,7 @@ public class Terrain extends Observable {
this.hamsterCol = col;
this.hamsterRow = row;
setChanged();
notifyObservers();
notifyObserversWithThreads();
return true;
} else
return false;
......@@ -183,13 +184,11 @@ public class Terrain extends Observable {
notifyObservers();
}
@Override
public void notifyObservers() {
public void notifyObserversWithThreads() {
super.notifyObservers();
if (hamster != null && hamster.isAlive()) {
try {
System.out.println(hamster.getState().toString());
hamster.sleep(500);
hamster.sleep((long) (-1 * speed + 1000));
} catch (InterruptedException e) {
try {
hamster.wait();
......@@ -250,6 +249,14 @@ public class Terrain extends Observable {
return hamster;
}
public boolean isRunningThread() {
return hamster.isRunning();
}
public void setChanged() {
super.setChanged();
}
// TODO: evtl loeschen
public void setHamsterDirection(int direction) throws IllegalArgumentException {
if (direction >= NORTH && direction <= WEST) {
......@@ -265,4 +272,8 @@ public class Terrain extends Observable {
this.hamster = hamster;
hamster.setTerrain(this);
}
public void setSpeed(double speed) {
this.speed = speed;
}
}
......@@ -2,6 +2,7 @@ package model;
import controller.IOController;
public class ThreadManager {
private Terrain terrain;
......@@ -20,11 +21,17 @@ public class ThreadManager {
}
public void stopThread() {
public void pauseThread() {
terrain.getHamster().interrupt();
}
public void pauseThread() {
public void stopThread() {
//TODO andere methode als stop finden
terrain.getHamster().stopHamster();
}
public void changeSpeed(double speed) {
terrain.setSpeed(speed);
}
}
......@@ -25,15 +25,13 @@ import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
/**
* Created by Stefan Michel on 14.11.17.
*/
public class MainViewCreationFX extends VBox {
public class MainViewCreationFX extends VBox implements Observer {
private final MenuBar menuBar = new MenuBar();
private final ToolBar toolBar = new ToolBar();
......@@ -50,6 +48,10 @@ public class MainViewCreationFX extends VBox {
private TextArea textArea;
private ContextMenu contextMenu;
private ThreadManager threadManager;
private Button start;
private Button pause;
private Button stopp;
private Slider slider;
public MainViewCreationFX(Terrain terrain, TerrainController terrainController, IOController ioController,
HamsterController hamsterController, ThreadManager threadManager) {
......@@ -59,6 +61,7 @@ public class MainViewCreationFX extends VBox {
this.hamsterController = hamsterController;
this.threadManager = threadManager;
this.terrain = terrain;
terrain.addObserver(this);
//Territory Pane erstellen
territoriumPanel = new TerritoriumPanelFX(terrain, terrainController);
......@@ -256,22 +259,8 @@ public class MainViewCreationFX extends VBox {
deleteMenuItem = new RadioMenuItem("_Kachel löschen");
// Hier die Daten vom MouseEvent werden nur an den TerrainController geschickt je nach dem welcher Button aktiv ist
territoriumPanel.setOnMouseClicked((MouseEvent event) -> {
if (event.getButton().equals(MouseButton.PRIMARY)) {
if (hamsterMenuItem.isSelected())
terrainController.moveHamster((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
if (cornMenuItem.isSelected())
terrainController.addCorn((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
if (wallMenuItem.isSelected())
terrainController.addWall((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
if (deleteMenuItem.isSelected())
terrainController.deleteTile((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
}
});
territoriumPanel.setOnMouseClicked((MouseEvent event) -> selectionLogic(hamsterMenuItem.isSelected(),
cornMenuItem.isSelected(), wallMenuItem.isSelected(), deleteMenuItem.isSelected(), event));
hamsterMenuItem.setToggleGroup(toggleGroup);
cornMenuItem.setToggleGroup(toggleGroup);
......@@ -372,22 +361,7 @@ public class MainViewCreationFX extends VBox {
ToggleButton delete = new ToggleButton(null, new ImageView(new Image("/Delete24.gif")));
// Hier die Daten vom MouseEvent werden nur an den TerrainController geschickt je nach dem welcher Button aktiv ist
territoriumPanel.setOnMouseClicked((MouseEvent event) -> {
if (event.getButton().equals(MouseButton.PRIMARY)) {
if (hamster.isSelected())
terrainController.moveHamster((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
if (corn.isSelected())
terrainController.addCorn((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
if (wall.isSelected())
terrainController.addWall((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
if (delete.isSelected())
terrainController.deleteTile((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
}
});
territoriumPanel.setOnMouseClicked((MouseEvent event) -> selectionLogic(hamster.isSelected(), corn.isSelected(), wall.isSelected(), delete.isSelected(), event));
// bind buttons to menubaritems
hamster.selectedProperty().bindBidirectional(this.hamsterMenuItem.selectedProperty());
......@@ -415,28 +389,68 @@ public class MainViewCreationFX extends VBox {
gib.setOnAction(event -> this.hamsterController.putDown());
// Simulation
Button start = new Button(null, new ImageView(new Image("/Play24.gif")));
Button pause = new Button(null, new ImageView(new Image("/Pause24.gif")));
Button stopp = new Button(null, new ImageView(new Image("/Stop24.gif")));
start = new Button(null, new ImageView(new Image("/Play24.gif")));
pause = new Button(null, new ImageView(new Image("/Pause24.gif")));
stopp = new Button(null, new ImageView(new Image("/Stop24.gif")));
pause.setDisable(true);
stopp.setDisable(true);
start.setOnAction(event -> {
threadManager.startThread();
start.setDisable(true);
});
pause.setOnAction(event -> threadManager.pauseThread());
stopp.setOnAction(event -> threadManager.stopThread());
pause.setOnAction(event -> {
threadManager.pauseThread();
});
stopp.setOnAction(event -> {
threadManager.stopThread();
});
// Slider
Slider geschwindigkeitSlider = new Slider();
slider = new Slider(0, 900, 450);
slider.valueProperty().addListener((observable, oldValue, newValue) -> threadManager.changeSpeed((double) newValue));
// zusammensetzen und returnen
toolBar.getItems().addAll(neu, open, new Separator(), speichern, kompilieren,
new Separator(), territorium, hamster, corn, wall, delete, new Separator(),
kornImMaul, linksUm, vor, nimm, gib, new Separator(), start, pause, stopp,
new Separator(), geschwindigkeitSlider);
new Separator(), slider);
}
private void selectionLogic(boolean hamsterSelected, boolean cornSelected, boolean wallSelected, boolean deleteSelected, MouseEvent event) {
if (event.getButton().equals(MouseButton.PRIMARY) && !terrain.isRunningThread()) {
if (hamsterSelected)
terrainController.moveHamster((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
if (cornSelected)
terrainController.addCorn((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
if (wallSelected)
terrainController.addWall((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
if (deleteSelected)
terrainController.deleteTile((int) event.getX() / TerritoriumPanelFX.TILE_SIZE,
(int) event.getY() / TerritoriumPanelFX.TILE_SIZE);
}
}
public void setFooterText(String s) {
footer.setText(s);
}
@Override
public void update(Observable o, Object arg) {
if (terrain.isRunningThread()) {
start.setDisable(true);
slider.setDisable(true);
stopp.setDisable(false);
} else {
start.setDisable(false);
slider.setDisable(false);
stopp.setDisable(true);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment