Permalink
Browse files

And add code to migrate save games

In case anyone started a game on the old version. Aargh explicit CPS is
so painful. I probably didn't have to bother with this code.
  • Loading branch information...
1 parent d4118d6 commit 5bda3f86d31f8ba38b99d01deb26b61ecb8197ce @davidben committed Mar 10, 2012
Showing with 117 additions and 3 deletions.
  1. +82 −1 src/res/nacl/filesystem.js
  2. +35 −2 src/res/nacl/uqm.js
View
83 src/res/nacl/filesystem.js
@@ -1,5 +1,14 @@
var FileSystemUtils = FileSystemUtils || {};
+FileSystemUtils.TaskManager = function (doneCallback) {
+ this.pending = 0;
+ this.doneCallback = doneCallback;
+};
+FileSystemUtils.TaskManager.prototype = {
+ push: function () { this.pending++; },
+ pop: function () { if (--this.pending == 0) this.doneCallback(); }
+};
+
FileSystemUtils.errorToString = function(code) {
switch (code) {
case FileError.QUOTA_EXCEEDED_ERR:
@@ -15,7 +24,7 @@ FileSystemUtils.errorToString = function(code) {
default:
return 'Unknown Error';
};
-}
+};
/** Reads a directory entry into a list. Calls successCallback on an
* Array on success. */
@@ -40,3 +49,75 @@ FileSystemUtils.readDirectory = function (dirEntry,
}
pumpReader();
};
+
+/** Copy a file cross-filesystems. */
+FileSystemUtils.xfsCopyFile = function (fileEntry, dirEntry, newName,
+ successCallback, errorCallback) {
+ console.log("Copying file " + fileEntry.name);
+ fileEntry.file(function (file) {
+ dirEntry.getFile(
+ newName, {create: true, exclusive: true}, function (destEntry) {
+ destEntry.createWriter(function (fileWriter) {
+ fileWriter.onwriteend = function (e) {
+ successCallback(destEntry);
+ };
+ fileWriter.onerror = errorCallback;
+ fileWriter.write(file);
+ });
+ }, errorCallback);
+ }, errorCallback);
+};
+
+/** Recursively a directory cross-filesystems. */
+FileSystemUtils.xfsCopyDirectory = function (srcDir, destDir, newName,
+ successCallback, errorCallback) {
+ console.log("Copying directory " + srcDir.name);
+ destDir.getDirectory(
+ newName, {create: true, exclusive: true}, function (destEntry) {
+ var tasks = new FileSystemUtils.TaskManager(function () {
+ successCallback(destEntry);
+ });
+
+ var dirReader = srcDir.createReader();
+ function loop() {
+ tasks.push();
+ dirReader.readEntries(function (results) {
+ if (results.length == 0) {
+ // Done.
+ tasks.pop();
+ return;
+ }
+ // Schedule a batch of copies.
+ for (var i = 0; i < results.length; i++) {
+ tasks.push();
+ if (results[i].isFile)
+ FileSystemUtils.xfsCopyFile(
+ results[i], destEntry, results[i].name,
+ tasks.pop.bind(tasks), errorCallback);
+ else
+ FileSystemUtils.xfsCopyDirectory(
+ results[i], destEntry, results[i].name,
+ tasks.pop.bind(tasks), errorCallback);
+ }
+ // And loop again.
+ loop();
+ tasks.pop();
+ }, errorCallback);
+ }
+ loop();
+ }, errorCallback);
+};
+
+/** getDirectory, but returns null instead of error if not found. */
+FileSystemUtils.getDirectoryOrNull = function (dirEntry, path,
+ successCallback, errorCallback) {
+ dirEntry.getDirectory(
+ path, {}, function (entry) { successCallback(entry); },
+ function (e) {
+ if (e.code == FileError.NOT_FOUND_ERR) {
+ successCallback(null);
+ } else {
+ errorCallback(e);
+ }
+ });
+};
View
37 src/res/nacl/uqm.js
@@ -127,10 +127,43 @@ function initializeModule(fsPersistent) {
// enough space.
window.webkitStorageInfo.requestQuota(
PERSISTENT, 2 * 1024 * 1024, function (grantedBytes) {
+ // Grab filesystems.
window.webkitRequestFileSystem(
PERSISTENT, grantedBytes, function (fsPersistent) {
- console.log("Got filesystem. Starting game.");
- initializeModule(fsPersistent);
+ window.webkitRequestFileSystem(
+ TEMPORARY, 350 * 1024 * 1024, function (fsTemporary) {
+ console.log("Got filesystems.");
+ onGotFileSystems(fsPersistent, fsTemporary);
+ }, onError);
}, onError);
}, function (e) { console.log(e); });
+
+ function onGotFileSystems(fsPersistent, fsTemporary) {
+ function startGame() {
+ console.log("Starting game.");
+ initializeModule(fsPersistent);
+ }
+
+ // Check if we need to migrate user data from the temporary
+ // filesystem. Isn't explicit CPS great?
+ FileSystemUtils.getDirectoryOrNull(
+ fsPersistent.root, "/userdata", function (dirEntry) {
+ if (dirEntry) {
+ startGame();
+ } else {
+ FileSystemUtils.getDirectoryOrNull(
+ fsTemporary.root, "/userdata", function (dirEntry) {
+ if (dirEntry) {
+ console.log("Migrating user data...");
+ FileSystemUtils.xfsCopyDirectory(
+ dirEntry, fsPersistent.root, "userdata",
+ startGame, onError);
+ } else {
+ startGame();
+ }
+ },
+ onError); // Just start the game.
+ }
+ }, onError);
+ }
}());

0 comments on commit 5bda3f8

Please sign in to comment.