From 65b12271bfd4645526338fb9375dba67fa3f73bc Mon Sep 17 00:00:00 2001
From: Nao Pross <naopross@thearcway.org>
Date: Tue, 20 Nov 2018 19:37:04 +0100
Subject: Refractor game state change detection / locks

---
 src/subconscious/Game.java                 | 68 +++++++++++++++++++-----------
 src/subconscious/Subconscious.java         |  6 +++
 src/subconscious/graphics/BattleScene.java |  1 +
 src/subconscious/graphics/GameWindow.java  |  5 ++-
 4 files changed, 53 insertions(+), 27 deletions(-)

diff --git a/src/subconscious/Game.java b/src/subconscious/Game.java
index 61c0836..7828105 100644
--- a/src/subconscious/Game.java
+++ b/src/subconscious/Game.java
@@ -2,6 +2,9 @@ package subconscious;
 
 import java.util.ArrayList;
 
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.Condition;
 
 /* Game
  * Contains informations about the current state of the game used in an
@@ -9,34 +12,33 @@ import java.util.ArrayList;
  */
 public class Game {
     public enum State {
-        MENU, PAUSE, LOADING,
+        // main menu
+        MENU, 
         // state in which the player is awake (real world)
         REALITY,
         // state in which the player is dreaming (imaginary world)
-        DREAM 
+        DREAM,
+        // intermediate states
+        PAUSE, CLOSING,
     }
 
-    private State state;
-    private boolean stateChanged;
+    private State state = State.MENU;
+    private final Lock stateLock = new ReentrantLock();
+    private Condition stateChanged;
     
-    private boolean running;
-    private boolean gameOver;
+    private boolean running = true;
+    private boolean gameOver = false;
 
-    private ArrayList<Actor> actors;
-    private ArrayList<Map> maps;
+    private ArrayList<Actor> actors = new ArrayList<>();
+    private ArrayList<Map> maps = new ArrayList<>();
     private Map currentMap;
 
     // TODO: load audio?
     private MapLoader mapLoader = new MapLoader();
 
     public Game() {
-        this.setState(State.MENU);
-
-        this.running = true;
-        this.gameOver = false;
-
-        this.actors = new ArrayList<>();
-        this.maps = new ArrayList<>();
+        // set up stateLock
+        stateChanged = stateLock.newCondition();
 
         // TODO: this will be replaced with a dynamic mechanism based
         //       on the progress within the game
@@ -48,19 +50,18 @@ public class Game {
 
     public void start() {
         this.setState(State.DREAM);
-
     }
 
-    public Map getMap() {
-        return currentMap;
+    public void update() {
+
     }
 
     /* methods to manage the state */
     public void setState(State state) {
-        if (this.state == state)
-            return;
+        stateLock.lock();
+        this.stateChanged.signal();
+        stateLock.unlock();
 
-        this.stateChanged = true;
         this.state = state;
     }
 
@@ -69,15 +70,32 @@ public class Game {
     }
 
     public State waitStateChange() {
-        while (!this.stateChanged);
-        this.stateChanged = false;
+        stateLock.lock();
+        try {
+            stateChanged.await();
+        } catch (InterruptedException ex) {
+            ex.printStackTrace();
+        } finally {
+            stateLock.unlock();
+        }
 
         return this.state;
     }
 
+    /* methods to manage map and map loading */
+    public Map getMap() {
+        return currentMap;
+    }
+
     /* accessors */
-    public boolean isRunning() { return running; }
-    public void quit() { this.running = false; }
+    public boolean isRunning() {
+        return running;
+    }
+
+    public void quit() {
+        this.setState(State.CLOSING);
+        this.running = false;
+    }
 
     public boolean isGameOver() { return gameOver; }
     public void gameOver() { this.gameOver = true; }
diff --git a/src/subconscious/Subconscious.java b/src/subconscious/Subconscious.java
index 88d9f70..bf57424 100644
--- a/src/subconscious/Subconscious.java
+++ b/src/subconscious/Subconscious.java
@@ -2,8 +2,14 @@ package subconscious;
 
 import subconscious.graphics.GameWindow;
 
+// for debugging
+import java.lang.Thread;
+
 public class Subconscious {
     public static void main(String[] args) {
+    	// for debugging
+    	Thread.currentThread().setName("Main");
+
         // TODO: in the future this will be loaded from a save file
         Game g = new Game();
         GameWindow w = new GameWindow(g);
diff --git a/src/subconscious/graphics/BattleScene.java b/src/subconscious/graphics/BattleScene.java
index 6366d18..5cdfad7 100644
--- a/src/subconscious/graphics/BattleScene.java
+++ b/src/subconscious/graphics/BattleScene.java
@@ -29,6 +29,7 @@ import javax.swing.JFrame;
 import javax.swing.JPanel;
 import javax.swing.JButton;
 
+
 @SuppressWarnings("serial")
 public class BattleScene extends MapScene implements ActionListener {
 
diff --git a/src/subconscious/graphics/GameWindow.java b/src/subconscious/graphics/GameWindow.java
index 19f8ce1..d7bb655 100644
--- a/src/subconscious/graphics/GameWindow.java
+++ b/src/subconscious/graphics/GameWindow.java
@@ -14,7 +14,6 @@ import javax.swing.JButton;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 
-
 /* GameWindow
  * This class manages the graphical part of the game, such as loading and
  * unloading scenes, and the window itself
@@ -101,6 +100,8 @@ public class GameWindow extends JFrame implements ActionListener {
 			}
 
 		}
+
+		this.quit();
 	}
 
 	private void loadScene(Scene scene) {
@@ -168,7 +169,7 @@ public class GameWindow extends JFrame implements ActionListener {
 	public void actionPerformed(ActionEvent e) {
 		if (e.getActionCommand().startsWith("btn")) {
 			if (e.getActionCommand().equals("btn-exit")) {
-				this.quit();
+				this.game.quit();
 				return;
 			}
 
-- 
cgit v1.2.1