Skip to content
Snippets Groups Projects
Commit 0470d663 authored by Nicklas Persia Tufteland's avatar Nicklas Persia Tufteland
Browse files

Merge branch '21-implement-functionality-that-makes-game-state-persistent' into 'dev'

Resolve "Implement functionality that makes game state persistent"

Closes #21

See merge request !29
parents 5798e959 beddce0c
No related branches found
No related tags found
2 merge requests!41final delivery,!29Resolve "Implement functionality that makes game state persistent"
Pipeline #287405 passed
......@@ -6,12 +6,20 @@ import edu.ntnu.idatt2003.model.ChaosGameFileHandler;
import edu.ntnu.idatt2003.view.MainPageView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.InputMismatchException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
/**
* The controller class for the main page of the ChaosGame application.
......@@ -23,6 +31,23 @@ public class MainPageController {
private final MainPageView view;
private static final String TRANSFORMATIONS_PATH = "src/main/resources/transformations/";
private static final String SERIALIZED_GAME_PATH = "src/main/resources/savedTransformation.ser";
private static final Logger LOGGER = Logger.getLogger(MainPageController.class.getName());
static {
try {
// Ensure the logs directory exists
new File("logs").mkdirs();
FileHandler fileHandler = new FileHandler("logs/application.log", false);
fileHandler.setFormatter(new SimpleFormatter());
fileHandler.setLevel(Level.WARNING);
LOGGER.addHandler(fileHandler);
LOGGER.setLevel(Level.ALL);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* The constructor for the MainPageController class.
......@@ -30,12 +55,12 @@ public class MainPageController {
* and renders the view.
*/
public MainPageController() {
this.game = new ChaosGame(ChaosGameDescriptionFactory
.get(ChaosGameDescriptionFactory.descriptionTypeEnum.SIERPINSKI_TRIANGLE),
600, 600);
this.game = loadGameState();
this.view = new MainPageView(this);
this.game.registerObserver(view);
this.view.render();
Runtime.getRuntime().addShutdownHook(new Thread(this::saveGameState));
LOGGER.log(Level.INFO, "MainPageController initialized successfully.");
}
/**
......@@ -64,6 +89,7 @@ public class MainPageController {
*/
public void runSteps(int steps) {
game.runSteps(steps);
LOGGER.log(Level.INFO, "Chaos game simulation ran {0} steps successfully.", steps);
}
/**
......@@ -74,25 +100,21 @@ public class MainPageController {
* @throws InputMismatchException If the file is not found or the input is invalid.
*/
public void uploadFile(File file) {
try {
LOGGER.log(Level.INFO, "Uploading file: {0}", file.getName());
validateFile(file);
if (!Files.exists(Path.of(TRANSFORMATIONS_PATH + file.getName()))
|| view.askConfirmation("File already exists. Do you want to overwrite it?")) {
storeFile(file);
}
} catch (Exception e) {
view.showAlert(e.getMessage());
}
}
private void validateFile(File file)
throws InputMismatchException, FileNotFoundException {
private void validateFile(File file) {
try {
new ChaosGameFileHandler().readFromFile(file);
} catch (InputMismatchException e) {
throw new InputMismatchException(e.getMessage());
} catch (FileNotFoundException e) {
throw new FileNotFoundException(e.getMessage());
} catch (InputMismatchException | FileNotFoundException e) {
view.showAlert(e.getMessage());
LOGGER.log(Level.WARNING, "Error uploading file. File was not uploaded.");
}
}
......@@ -107,10 +129,13 @@ public class MainPageController {
String destinationPath = projectPath + File.separator
+ TRANSFORMATIONS_PATH + file.getName();
Files.copy(file.toPath(), Path.of(destinationPath), StandardCopyOption.REPLACE_EXISTING);
LOGGER.log(Level.INFO, "File stored successfully in {0}", destinationPath);
} catch (IOException e) {
throw new InputMismatchException("Error copying file: " + e.getMessage());
view.showAlert("Error storing file. Please try again.");
LOGGER.log(Level.WARNING, "Error storing file. File was not stored.");
}
}
/**
* Change the transformation-type of the chaos game.
*
......@@ -119,6 +144,39 @@ public class MainPageController {
public void changeTransformation(ChaosGameDescriptionFactory
.descriptionTypeEnum descriptionType) {
game.changeTransformation(descriptionType);
LOGGER.log(Level.INFO, "Transformation was changed successfully to {0}"
, descriptionType);
}
private void saveGameState() {
LOGGER.log(Level.INFO, "Saving game state.");
game.removeObserver(view);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(SERIALIZED_GAME_PATH))) {
oos.writeObject(game);
LOGGER.log(Level.INFO, "Game state saved successfully in {0}", SERIALIZED_GAME_PATH);
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Failed to save game state. Next time the application is"
+ " started, the game will be launched in same game state as this time.");
}
}
public ChaosGame loadGameState() {
LOGGER.log(Level.INFO, "Loading game state.");
File file = new File(SERIALIZED_GAME_PATH);
if (file.exists()) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
ChaosGame loadedGame = (ChaosGame) ois.readObject();
LOGGER.log(Level.INFO, "Game state loaded successfully.");
return loadedGame;
} catch (IOException | ClassNotFoundException e) {
LOGGER.log(Level.WARNING, "Failed to load game state. Creating new game.");
}
} else {
LOGGER.log(Level.WARNING, "No saved game state found. Creating new game.");
}
return new ChaosGame(ChaosGameDescriptionFactory
.get(ChaosGameDescriptionFactory.descriptionTypeEnum.SIERPINSKI_TRIANGLE),
600, 600);
}
}
package edu.ntnu.idatt2003.model;
import java.io.Serializable;
/**
* Represents a 2-dimensional affine transformation.
* Contains a constructor and a method for transforming a 2-dimensional vector.
......@@ -7,7 +9,7 @@ package edu.ntnu.idatt2003.model;
* autor: nicklapt
*/
public class AffineTransform2D implements Transform2D {
public class AffineTransform2D implements Transform2D, Serializable {
/**
* The 2x2 matrix of the affine transformation.
......
package edu.ntnu.idatt2003.model;
import java.io.Serializable;
/**
* Class for creating a canvas for the chaos game.
* Contains methods for converting coordinates to indices on the canvas, and for displaying the canvas.
......@@ -7,7 +9,7 @@ package edu.ntnu.idatt2003.model;
* Goal: act as a model for a canvas for the chaos game.
*/
public class ChaosCanvas {
public class ChaosCanvas implements Serializable {
private final int[][] canvas;
private final int width;
......
package edu.ntnu.idatt2003.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
......@@ -11,7 +12,7 @@ import java.util.Random;
* Goal: act as a model for a chaos game.
*/
public class ChaosGame {
public class ChaosGame implements Serializable {
private ChaosCanvas canvas;
private ChaosGameDescription description;
......
package edu.ntnu.idatt2003.model;
import java.io.Serializable;
import java.util.List;
/**
......@@ -8,7 +9,7 @@ import java.util.List;
* the game, and the transformations to be used.
* Goal: act as a model for a chaos game description.
*/
public class ChaosGameDescription {
public class ChaosGameDescription implements Serializable {
/**
* The minimum (bottom left) coordinates of the game.
*/
......
package edu.ntnu.idatt2003.model;
import java.io.Serializable;
/**
* Represents a subclass that extends the {@link Vector2d}.
* It adds the additional functionality of finding the square root of a complex number.
......@@ -7,7 +9,7 @@ package edu.ntnu.idatt2003.model;
*
* @author svhaa
*/
public class Complex extends Vector2d {
public class Complex extends Vector2d implements Serializable {
/**
* Constructs a Complex object.
*
......
package edu.ntnu.idatt2003.model;
import java.io.Serializable;
/**
* Represents a Julia transformation applied to 2D vectors.
* Contains a constructor and a method for transforming a 2D vector.
......@@ -7,7 +9,7 @@ package edu.ntnu.idatt2003.model;
*
* @author sverrgha
*/
public class JuliaTransform implements Transform2D {
public class JuliaTransform implements Transform2D, Serializable {
/**
* The point to transform the 2D vector by.
......
package edu.ntnu.idatt2003.model;
import java.io.Serializable;
import java.util.Locale;
/**
......@@ -7,7 +8,7 @@ import java.util.Locale;
*
* @author nicklapt
*/
public class Matrix2x2 {
public class Matrix2x2 implements Serializable {
private final double a00;
private final double a01;
......
package edu.ntnu.idatt2003.model;
import java.io.Serializable;
/**
* Represents a 2-dimensional vector.
* Contains a constructor and getters for the x0 and x1 attributes.
......@@ -8,7 +10,7 @@ package edu.ntnu.idatt2003.model;
*
* @author sverrgha
*/
public class Vector2d {
public class Vector2d implements Serializable {
/**
* The first coordinate of the vector.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment