var LibraryHUMBLE = {
|
$HUMBLE_API: {
|
options: {
|
/**
|
* allows altering the incoming URL before it is fetched from the network
|
* ex. function(path) { return path; }
|
*/
|
locateAsset: null,
|
/**
|
* returns a key for the specified path. return null to NOT cache the specific resource
|
* for scoped keys.. return { scope: 'deadbeef', path: 'path' }, otherwise just return a string
|
* ex. function(path) { return path; }
|
*/
|
buildCacheKey: null,
|
/**
|
* function returning a hash like {width: 800, height: 600, locked: true}
|
* locked specifies whether the game should use that width/height.
|
* ex. function() { return { width: 800, height: 600, locked: true } }
|
*/
|
playerSize: null,
|
/**
|
* callback to handle the demo_ended API from in the game
|
* the callback takes no parameters.
|
*/
|
demoEndedCallback: null
|
},
|
/**
|
* allows configuring the HUMBLE_API simply call this method in a preRun to initialize..
|
* any option is accepted and will be added to the configuration hash.
|
* Also all hooks will be context of HUMBLE_API so this.options.myCustomKey will be accessible
|
*/
|
configure: function(options) {
|
for (var i in options) {
|
HUMBLE_API.options[i] = options[i];
|
}
|
},
|
|
locateAsset: function(path) {
|
if (HUMBLE_API.options.locateAsset) {
|
return HUMBLE_API.options.locateAsset.call(HUMBLE_API, path);
|
} else {
|
return path;
|
}
|
},
|
|
buildCacheKey: function(path) {
|
if (HUMBLE_API.options.buildCacheKey) {
|
return HUMBLE_API.options.buildCacheKey.call(HUMBLE_API, path);
|
} else {
|
return null;
|
}
|
},
|
|
pathToKey: function(path) {
|
if (typeof path == 'string') {
|
return { path: path, scope: '', key: ':' + path};
|
} else {
|
return { path: path.path, scope: path.scope, key: path.scope + ':' + path.path };
|
}
|
},
|
// deletes all entries for the specified scope
|
clearCacheByScope: function(scope, oncomplete) {
|
HUMBLE_API.getDB(function(err, db) {
|
if (err) return oncomplete(err);
|
|
var transaction = db.transaction([HUMBLE_API.DB_ASYNC_CACHE_STORE], 'readwrite');
|
transaction.onerror = function() { oncomplete(this.error); };
|
|
var store = transaction.objectStore(HUMBLE_API.DB_ASYNC_CACHE_STORE);
|
var index = store.index('scope');
|
|
index.openKeyCursor(IDBKeyRange.only(scope)).onsuccess = function(e) {
|
var cursor = event.target.result;
|
|
if (cursor) {
|
store.delete(cursor.primaryKey);
|
|
cursor.continue();
|
} else {
|
oncomplete(null);
|
}
|
};
|
});
|
},
|
storeToCache: function(path, byteArray, ondone) {
|
if (path === null) {
|
return ondone(null);
|
}
|
|
HUMBLE_API.getDB(function(err, db) {
|
if (err) return ondone(err);
|
|
var transaction = db.transaction([HUMBLE_API.DB_ASYNC_CACHE_STORE], 'readwrite');
|
transaction.onerror = function() { ondone(this.error); };
|
|
var store = transaction.objectStore(HUMBLE_API.DB_ASYNC_CACHE_STORE);
|
|
var data = HUMBLE_API.pathToKey(path);
|
data['data'] = byteArray;
|
|
var req = store.put(data);
|
|
req.onsuccess = function(e) {
|
ondone(null);
|
};
|
req.onerror = function() { ondone(this.error); };
|
});
|
},
|
fetchFromCache: function(path, ondone, onfail) {
|
if (path === null) {
|
return onfail(null);
|
}
|
HUMBLE_API.getDB(function(err, db) {
|
if (err) return onfail(err);
|
|
var transaction = db.transaction([HUMBLE_API.DB_ASYNC_CACHE_STORE], 'readonly');
|
transaction.onerror = function() { onfail(this.error); };
|
|
var store = transaction.objectStore(HUMBLE_API.DB_ASYNC_CACHE_STORE);
|
|
var data = HUMBLE_API.pathToKey(path);
|
|
var req = store.get(data.key);
|
req.onsuccess = function(e) {
|
if (e.target.result) {
|
var o = e.target.result;
|
ondone(o.data);
|
} else {
|
onfail(null);
|
}
|
};
|
req.onerror = function() { onfail(this.error); };
|
});
|
},
|
|
/* indexedDB access */
|
// borrowed from IDBFS
|
dbs: {},
|
indexedDB: function() {
|
if (typeof indexedDB !== 'undefined') return indexedDB;
|
var ret = null;
|
if (typeof window === 'object') ret = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
assert(ret, 'IDBFS used, but indexedDB not supported');
|
return ret;
|
},
|
DB_VERSION: 1,
|
DB_NAME: 'HUMBLE_API',
|
DB_ASYNC_CACHE_STORE: 'HUMBLE_API_ASYNC',
|
getDB: function(callback) {
|
var db = HUMBLE_API.dbs[HUMBLE_API.DB_NAME];
|
if (db) {
|
return callback(null, db);
|
}
|
|
var req;
|
try {
|
req = HUMBLE_API.indexedDB().open(HUMBLE_API.DB_NAME, HUMBLE_API.DB_VERSION)
|
} catch (e) {
|
return callback(e);
|
}
|
req.onupgradeneeded = function(e) {
|
var db = e.target.result;
|
|
var fileStore;
|
|
// Just replace it for now
|
fileStore = db.createObjectStore(HUMBLE_API.DB_ASYNC_CACHE_STORE, {keyPath: 'key'});
|
fileStore.createIndex('scope','scope',{ unique: false });
|
};
|
req.onsuccess = function() {
|
db = req.result;
|
|
HUMBLE_API.dbs[HUMBLE_API.DB_NAME] = db;
|
callback(null, db);
|
};
|
req.onerror = function() {
|
callback(this.error);
|
};
|
}
|
},
|
humble_init__deps: ['$CLOUDFS','$HUMBLE_API'],
|
humble_init: function() {
|
// Dummy function to pull in the rest of the functions
|
},
|
humble_sync__deps: ['$FS', '$CLOUDFS','$HUMBLE_API'],
|
humble_sync: function() {
|
FS.syncfs(function (err) {
|
console.log('File Sync');
|
});
|
},
|
humble_fetch_asset_data__deps: ['$BROWSER','$HUMBLE_API'],
|
humble_fetch_asset_data: function(assetPath, arg, onload, onerror) {
|
var path = Pointer_stringify(assetPath);
|
var cacheKey = HUMBLE_API.buildCacheKey(path);
|
|
HUMBLE_API.fetchFromCache(cacheKey, function(byteArray) {
|
var buffer = _malloc(byteArray.length);
|
HEAPU8.set(byteArray, buffer);
|
Runtime.dynCall('viii', onload, [arg, buffer, byteArray.length]);
|
_free(buffer);
|
}, function(err) {
|
try {
|
var url = HUMBLE_API.locateAsset(path);
|
Browser.asyncLoad(url, function (byteArray) {
|
HUMBLE_API.storeToCache(cacheKey, byteArray, function (err) {
|
var buffer = _malloc(byteArray.length);
|
HEAPU8.set(byteArray, buffer);
|
Runtime.dynCall('viii', onload, [arg, buffer, byteArray.length]);
|
_free(buffer);
|
});
|
}, function() {
|
if (onerror) Runtime.dynCall('vi', onerror, [arg]);
|
}, true /* NO run dependency */);
|
} catch(ex) {
|
if (onerror) Runtime.dynCall('vi', onerror, [arg]);
|
}
|
});
|
},
|
humble_get_player_size: function(w, h) {
|
var ret = {width: 0, height: 0, locked: false};
|
if (HUMBLE_API.options.playerSize) {
|
ret = HUMBLE_API.options.playerSize();
|
}
|
if (w) {{{ makeSetValue('w', '0', 'ret.width', 'i32') }}};
|
if (h) {{{ makeSetValue('h', '0', 'ret.height', 'i32') }}};
|
return ret.locked ? 1 : 0;
|
},
|
humble_demo_ended: function() {
|
if (HUMBLE_API.options.demoEndedCallback) {
|
return HUMBLE_API.options.demoEndedCallback.call(HUMBLE_API);
|
}
|
}
|
};
|
|
autoAddDeps(LibraryHUMBLE, '$HUMBLE_API');
|
mergeInto(LibraryManager.library, LibraryHUMBLE);
|