|
From: <ste...@us...> - 2011-07-05 17:03:29
|
Revision: 1604
http://rails.svn.sourceforge.net/rails/?rev=1604&view=rev
Author: stefanfrey
Date: 2011-07-05 17:03:23 +0000 (Tue, 05 Jul 2011)
Log Message:
-----------
Refactored the load code into a new Class GameLoader
Modified Paths:
--------------
trunk/18xx/LocalisedText.properties
trunk/18xx/rails/game/Game.java
trunk/18xx/rails/game/GameManager.java
trunk/18xx/rails/util/ListAndFixSavedFiles.java
Added Paths:
-----------
trunk/18xx/rails/util/GameLoader.java
Modified: trunk/18xx/LocalisedText.properties
===================================================================
--- trunk/18xx/LocalisedText.properties 2011-07-04 23:34:57 UTC (rev 1603)
+++ trunk/18xx/LocalisedText.properties 2011-07-05 17:03:23 UTC (rev 1604)
@@ -354,11 +354,11 @@
LaysTileAtFor={0} lays tile #{1} at hex {2}/{3} for {4}
LDIncome=LD income is
LeaveAuctionOnPass=Leave private auction on pass
-LoadFailed=Load failed, reason: {0}
+LoadFailed=Load failed.\n\Reason = {0}\n\To improve Rails please submit save file to Rails user list at \n\ rai...@li...
LoadGame=Load Game
LoadRecentGame=Load Recent
LOAD=Load
-LoadInterrupted=Load interrupted at this point, you can continue play from here
+LoadInterrupted=Load interrupted at this point, you can continue play from here.\n\To improve Rails please submit save file to Rails user list at \n\ rai...@li...
LoansNotAllowed={0} may not take any loans
Major=Major
MAP=Map
Modified: trunk/18xx/rails/game/Game.java
===================================================================
--- trunk/18xx/rails/game/Game.java 2011-07-04 23:34:57 UTC (rev 1603)
+++ trunk/18xx/rails/game/Game.java 2011-07-05 17:03:23 UTC (rev 1604)
@@ -13,6 +13,7 @@
import rails.common.parser.GameFileParser;
import rails.common.parser.GameOption;
import rails.game.action.PossibleAction;
+import rails.util.GameLoader;
public class Game {
public static final String version = "1.4.1+";
@@ -118,9 +119,32 @@
return true;
}
+
+
+ public static Game load(String filepath) {
+
+ // use GameLoader object to load game
+ GameLoader gameLoader = new GameLoader();
+ gameLoader.loadGameData(filepath);
+ try{
+ gameLoader.initGame();
+ gameLoader.loadActionsAndComments();
+ } catch (ConfigurationException e) {
+ log.fatal("Load failed", e);
+ DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage()));
+ }
+ try{
+ gameLoader.replayGame();
+ } catch (Exception e) {
+ log.fatal("Replay failed", e);
+ DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage()));
+ }
+ return gameLoader.getGame();
+ }
+
@SuppressWarnings("unchecked")
- public static Game load(String filepath) {
+ public static Game load_old(String filepath) {
Game game = null;
Modified: trunk/18xx/rails/game/GameManager.java
===================================================================
--- trunk/18xx/rails/game/GameManager.java 2011-07-04 23:34:57 UTC (rev 1603)
+++ trunk/18xx/rails/game/GameManager.java 2011-07-05 17:03:23 UTC (rev 1604)
@@ -1049,8 +1049,8 @@
return true;
}
+ /** allows callback from GameLoader */
public void finishLoading () {
-
guiHints.clearVisibilityHints();
}
@@ -1141,72 +1141,44 @@
}
return result;
}
-
- @SuppressWarnings("unchecked")
+ /**
+ * tries to reload the current game
+ * executes the additional action(s)
+ */
protected boolean reload(GameAction reloadAction) {
-
+ log.info("Reloading started");
+
+ /* Use gameLoader to load the game data */
+ GameLoader gameLoader = new GameLoader();
String filepath = reloadAction.getFilepath();
- log.info("Reloading game from file " + filepath);
- String filename = filepath.replaceAll(".*[/\\\\]", "");
+ gameLoader.loadGameData(filepath);
+
+ /* followed by actions and comments */
+ try{
+ gameLoader.loadActionsAndComments();
+ } catch (ConfigurationException e) {
+ log.fatal("Load failed", e);
+ DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage()));
+ }
+ log.debug("Starting to compare loaded actions");
+
+ /* gameLoader actions get compared to the executed actions of the current game */
+ List<PossibleAction> savedActions = gameLoader.getActions();
+
+ setReloading(true);
+
+ // Check size
+ if (savedActions.size() < executedActions.size()) {
+ DisplayBuffer.add(LocalText.getText("LoadFailed",
+ "loaded file has less actions than current game"));
+ return true;
+ }
+
+ // Check action identity
+ int index = 0;
+ PossibleAction executedAction;
try {
- ObjectInputStream ois =
- new ObjectInputStream(new FileInputStream(
- new File(filepath)));
-
- // See Game.load(). Here we don't do as much checking. */
- Object object = ois.readObject();
- if (object instanceof String) {
- log.info("Reading Rails "+(String)object+" saved file "+filename);
- object = ois.readObject();
- } else {
- log.info("Reading Rails (pre-1.0.7) saved file "+filename);
- }
- if (object instanceof String) {
- log.info("File was saved at "+(String)object);
- object = ois.readObject();
- }
- String name = (String) ois.readObject();
- log.debug("Saved game="+name);
- Map<String, String> selectedGameOptions =
- (Map<String, String>) ois.readObject();
- List<String> playerNames = (List<String>) ois.readObject();
-
- log.debug("Starting to compare loaded actions");
-
- List<PossibleAction> savedActions;
- int numberOfActions = 0;
- setReloading(true);
-
- Object actionObject = ois.readObject();
- if (actionObject instanceof List) {
- // Old-style: one List of PossibleActions
- savedActions = (List<PossibleAction>) actionObject;
- numberOfActions = savedActions.size();
- } else {
- // New style: separate PossibleActionsObjects, since Rails 1.3.1
- savedActions = new ArrayList<PossibleAction>();
- while (actionObject instanceof PossibleAction) {
- savedActions.add((PossibleAction) actionObject);
- numberOfActions++;
- try {
- actionObject = ois.readObject();
- } catch (EOFException e) {
- break;
- }
- }
- }
-
- // Check size
- if (numberOfActions < executedActions.size()) {
- DisplayBuffer.add(LocalText.getText("LoadFailed",
- "loaded file has less actions than current game"));
- return true;
- }
-
- // Check action identity
- int index = 0;
- PossibleAction executedAction;
for (PossibleAction savedAction : savedActions) {
if (index < executedActions.size()) {
executedAction = executedActions.get(index);
@@ -1230,40 +1202,25 @@
}
}
index++;
- }
-
- if (actionObject instanceof SortedMap) {
- ReportBuffer.setCommentItems((SortedMap<Integer, String>) actionObject);
- log.debug("Found sorted map");
- } else {
- try {
- object = ois.readObject();
- if (object instanceof SortedMap) {
- ReportBuffer.setCommentItems((SortedMap<Integer, String>) object);
- }
- } catch (IOException e) {
- // continue without comments, if any IOException occurs
- // sometimes not only the EOF Exception is raised
- // but also the java.io.StreamCorruptedException: invalid type code
- }
- }
-
- ois.close();
- ois = null;
-
- setReloading(false);
- finishLoading();
- log.info("Reloading finished");
-
+ }
} catch (Exception e) {
log.error("Reload failed", e);
DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage()));
return true;
}
+
+
+ setReloading(false);
+ finishLoading();
+ // use new comments (without checks)
+ ReportBuffer.setCommentItems(gameLoader.getComments());
+
+ log.info("Reloading finished");
return true;
}
+
protected boolean export(GameAction exportAction) {
String filename = exportAction.getFilepath();
Added: trunk/18xx/rails/util/GameLoader.java
===================================================================
--- trunk/18xx/rails/util/GameLoader.java (rev 0)
+++ trunk/18xx/rails/util/GameLoader.java 2011-07-05 17:03:23 UTC (rev 1604)
@@ -0,0 +1,252 @@
+package rails.util;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.log4j.Logger;
+
+import rails.common.DisplayBuffer;
+import rails.common.LocalText;
+import rails.common.parser.ConfigurationException;
+import rails.game.Game;
+import rails.game.GameManager;
+import rails.game.GameManagerI;
+import rails.game.ReportBuffer;
+import rails.game.action.PossibleAction;
+
+/**
+ * @author freystef
+ *
+ */
+public class GameLoader {
+
+ protected static Logger log =
+ Logger.getLogger(Game.class.getPackage().getName());
+
+ private boolean dataLoadDone;
+ private boolean initialized;
+
+ private ObjectInputStream ois;
+
+ private String saveVersion;
+ private String saveDate;
+ private Long saveFileVersionID;
+ private String saveGameName;
+ private Map<String, String> selectedGameOptions;
+ private List<String> playerNames;
+ private List<PossibleAction> listOfActions;
+ private SortedMap<Integer, String> userComments;
+
+ private Game loadedGame;
+
+ public String getGameData() {
+ StringBuilder s = new StringBuilder();
+ s.append("Rails saveVersion = " + saveVersion + "\n");
+ s.append("File was saved at " + saveDate + "\n");
+ s.append("Saved versionID=" + saveFileVersionID + "\n");
+ s.append("Save game=" + saveGameName + "\n");
+ for (String key : selectedGameOptions.keySet()) {
+ s.append("Option "+key+"="+selectedGameOptions.get(key)+ "\n");
+ }
+ int i=1;
+ for (String player : playerNames) {
+ s.append("Player "+(i++)+": "+player + "\n");
+ }
+ return s.toString();
+ }
+
+ public Game getGame() {
+ return loadedGame;
+ }
+
+ public List<PossibleAction> getActions() {
+ return listOfActions;
+ }
+
+ public SortedMap<Integer, String> getComments() {
+ return userComments;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void loadGameData(String filepath) {
+
+ dataLoadDone = true;
+ log.info("Loading game from file " + filepath);
+ String filename = filepath.replaceAll(".*[/\\\\]", "");
+
+ try {
+ ois = new ObjectInputStream(new FileInputStream(
+ new File(filepath)));
+
+ Object object = ois.readObject();
+ if (object instanceof String) {
+ // New in 1.0.7: Rails version & save date/time.
+ saveVersion = (String)object;
+ object = ois.readObject();
+ } else {
+ // Allow for older saved file versions.
+ saveVersion = "pre-1.0.7";
+ }
+
+ log.info("Reading Rails " + saveVersion +" saved file "+filename);
+
+ if (object instanceof String) {
+ saveDate = (String)object;
+ log.info("File was saved at "+ saveDate);
+ object = ois.readObject();
+ }
+
+ // read versionID for serialization compatibility
+ saveFileVersionID = (Long) object;
+ log.debug("Saved versionID="+saveFileVersionID+" (object="+object+")");
+ long GMsaveFileVersionID = GameManager.saveFileVersionID;
+
+ if (saveFileVersionID != GMsaveFileVersionID) {
+ throw new Exception("Save version " + saveFileVersionID
+ + " is incompatible with current version "
+ + GMsaveFileVersionID);
+ }
+
+ // read name of saved game
+ saveGameName = (String) ois.readObject();
+ log.debug("Saved game="+ saveGameName);
+
+ // read selected game options and player names
+ selectedGameOptions = (Map<String, String>) ois.readObject();
+ log.debug("Selected game options = " + selectedGameOptions);
+ playerNames = (List<String>) ois.readObject();
+ log.debug("Player names = " + playerNames);
+
+ } catch (Exception e) {
+ log.fatal("Load failed", e);
+ DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage()));
+ }
+
+
+ }
+
+ public Game initGame() throws ConfigurationException {
+
+ // check if initial load was done
+ if (!dataLoadDone) {
+ throw new ConfigurationException("No game was loaded");
+ }
+
+ // initialize loadedGame
+ loadedGame = new Game(saveGameName, playerNames, selectedGameOptions);
+
+ if (!loadedGame.setup()) {
+ loadedGame = null;
+ throw new ConfigurationException("Error in setting up " + saveGameName);
+ }
+
+ String startError = loadedGame.start();
+ if (startError != null) {
+ DisplayBuffer.add(startError);
+ }
+
+ return loadedGame;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public boolean loadActionsAndComments() throws ConfigurationException {
+ if (!dataLoadDone) {
+ throw new ConfigurationException("No game was loaded");
+ }
+ // Read game actions into listOfActions
+ try {
+ // read next object in stream
+ Object actionObject = null;
+ while (true) { // Single-pass loop.
+ try {
+ actionObject = ois.readObject();
+ } catch (EOFException e) {
+ // Allow saved file at start of game (with no actions).
+ break;
+
+ }
+ if (actionObject instanceof List) {
+ // Until Rails 1.3: one List of PossibleAction
+ listOfActions = (List<PossibleAction>) actionObject;
+ } else if (actionObject instanceof PossibleAction) {
+ listOfActions = new ArrayList<PossibleAction>();
+ // Since Rails 1.3.1: separate PossibleActionsObjects
+ while (actionObject instanceof PossibleAction) {
+ listOfActions.add((PossibleAction)actionObject);
+ try {
+ actionObject = ois.readObject();
+ } catch (EOFException e) {
+ break;
+ }
+ }
+ }
+ break;
+ }
+ /**
+ todo: the code below is far from perfect, but robust
+ */
+
+ // init user comments to have a defined object in any case
+ userComments = new TreeMap<Integer,String>();
+
+ // at the end of file user comments are added as SortedMap
+ if (actionObject instanceof SortedMap) {
+ userComments = (SortedMap<Integer, String>) actionObject;
+ log.debug("file load: found user comments");
+ } else {
+ try {
+ Object object = ois.readObject();
+ if (object instanceof SortedMap) {
+ userComments = (SortedMap<Integer, String>) actionObject;
+ log.debug("file load: found user comments");
+ }
+ } catch (IOException e) {
+ // continue without comments, if any IOException occurs
+ // sometimes not only the EOF Exception is raised
+ // but also the java.io.StreamCorruptedException: invalid type code
+ }
+ }
+ ois.close();
+ ois = null;
+ initialized = true;
+ } catch (Exception e) {
+ log.fatal("Load failed", e);
+ DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage()));
+ initialized = false;
+ }
+ return initialized;
+ }
+
+ public void replayGame() throws Exception {
+ if (!initialized) {
+ throw new ConfigurationException("No game was loaded/initialized");
+ }
+
+ GameManagerI gameManager = loadedGame.getGameManager();
+ log.debug("Starting to execute loaded actions");
+ gameManager.setReloading(true);
+
+ for (PossibleAction action : listOfActions) {
+ if (!gameManager.processOnReload(action)) {
+ log.error ("Load interrupted");
+ DisplayBuffer.add(LocalText.getText("LoadInterrupted"));
+ break;
+ }
+ }
+
+ gameManager.setReloading(false);
+ ReportBuffer.setCommentItems(userComments);
+
+ // callback to GameManager
+ gameManager.finishLoading();
+ }
+}
Property changes on: trunk/18xx/rails/util/GameLoader.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/18xx/rails/util/ListAndFixSavedFiles.java
===================================================================
--- trunk/18xx/rails/util/ListAndFixSavedFiles.java 2011-07-04 23:34:57 UTC (rev 1603)
+++ trunk/18xx/rails/util/ListAndFixSavedFiles.java 2011-07-05 17:03:23 UTC (rev 1604)
@@ -36,6 +36,7 @@
private List<Object> savedObjects = new ArrayList<Object>(512);
private List<PossibleAction> executedActions;
+ private SortedMap<Integer,String> userComments;
private int vbarPos;
@@ -156,100 +157,33 @@
JFileChooser jfc = new JFileChooser();
jfc.setCurrentDirectory(new File(saveDirectory));
-
+
if (jfc.showOpenDialog(getContentPane()) == JFileChooser.APPROVE_OPTION) {
File selectedFile = jfc.getSelectedFile();
filepath = selectedFile.getPath();
saveDirectory = selectedFile.getParent();
+
+ // use GameLoader object to load game
+ GameLoader gameLoader = new GameLoader();
- log.debug("Loading game from file " + filepath);
- String filename = filepath.replaceAll(".*[/\\\\]", "");
-
- try {
- ObjectInputStream ois =
- new ObjectInputStream(new FileInputStream(
- new File(filepath)));
-
- // New in 1.0.7: Rails version & save date/time.
- // Allow for older saved file versions.
-
- Object object = ois.readObject();
- savedObjects.add(object);
- if (object instanceof String) {
- add((String)object+" saved file "+filename);
- object = ois.readObject();
- savedObjects.add(object);
- } else {
- add("Reading Rails (pre-1.0.7) saved file "+filename);
- }
- if (object instanceof String) {
- add("File was saved at "+(String)object);
- object = ois.readObject();
- savedObjects.add(object);
- }
-
- long versionID = (Long) object;
- add("Saved versionID="+versionID+" (object="+object+")");
- long saveFileVersionID = GameManager.saveFileVersionID;
- String name = (String) ois.readObject();
- savedObjects.add(name);
- add("Saved game="+name);
-
- Map<String, String> selectedGameOptions =
- (Map<String, String>) ois.readObject();
- savedObjects.add(selectedGameOptions);
- for (String key : selectedGameOptions.keySet()) {
- add("Option "+key+"="+selectedGameOptions.get(key));
- }
-
- List<String> playerNames = (List<String>) ois.readObject();
- savedObjects.add(playerNames);
- int i=1;
- for (String player : playerNames) {
- add("Player "+(i++)+": "+player);
- }
-
- Game game = new Game(name, playerNames, selectedGameOptions);
-
- if (!game.setup()) {
- throw new ConfigurationException("Error in setting up " + name);
- }
-
- Object firstActionObject = ois.readObject();
- if (firstActionObject instanceof List) {
- // Old-style: one List of PossibleActions
- executedActions =
- (List<PossibleAction>) firstActionObject;
- savedObjects.add(executedActions);
- } else {
- // New style: separate PossibleActionsObjects, since Rails 1.3.1
- executedActions = new ArrayList<PossibleAction>();
- PossibleAction action = (PossibleAction) firstActionObject;
- while (true) {
- savedObjects.add (action);
- executedActions.add(action);
- try {
- action = (PossibleAction) ois.readObject();
- } catch (EOFException e) {
- break;
- } catch (ClassCastException e) {
- log.error ("Aborting on non-action object: "+ e.getMessage());
- break;
- }
- }
- }
+ gameLoader.loadGameData(filepath);
+ add(gameLoader.getGameData());
+ try{
+ gameLoader.initGame();
+ gameLoader.loadActionsAndComments();
+ executedActions = gameLoader.getActions();
+ userComments = gameLoader.getComments();
setReportText(true);
-
- ois.close();
- } catch (Exception e) {
- System.out.println(e.getMessage());
- e.printStackTrace();
+
+ } catch (ConfigurationException e) {
+ log.fatal("Load failed", e);
+ DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage()));
}
}
}
-
+
public void add (String text) {
if (text.length() > 0) {
headerText.append(text);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|