|
| 1 | + |
| 2 | +var Module; |
| 3 | + |
| 4 | +if (typeof Module === 'undefined') Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()'); |
| 5 | + |
| 6 | +if (!Module.expectedDataFileDownloads) { |
| 7 | + Module.expectedDataFileDownloads = 0; |
| 8 | + Module.finishedDataFileDownloads = 0; |
| 9 | +} |
| 10 | +Module.expectedDataFileDownloads++; |
| 11 | +(function() { |
| 12 | + var loadPackage = function(metadata) { |
| 13 | + |
| 14 | + var PACKAGE_PATH; |
| 15 | + if (typeof window === 'object') { |
| 16 | + PACKAGE_PATH = window['encodeURIComponent'](window.location.pathname.toString().substring(0, window.location.pathname.toString().lastIndexOf('/')) + '/'); |
| 17 | + } else if (typeof location !== 'undefined') { |
| 18 | + // worker |
| 19 | + PACKAGE_PATH = encodeURIComponent(location.pathname.toString().substring(0, location.pathname.toString().lastIndexOf('/')) + '/'); |
| 20 | + } else { |
| 21 | + throw 'using preloaded data can only be done on a web page or in a web worker'; |
| 22 | + } |
| 23 | + var PACKAGE_NAME = 'game.data'; |
| 24 | + var REMOTE_PACKAGE_BASE = 'game.data'; |
| 25 | + if (typeof Module['locateFilePackage'] === 'function' && !Module['locateFile']) { |
| 26 | + Module['locateFile'] = Module['locateFilePackage']; |
| 27 | + Module.printErr('warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)'); |
| 28 | + } |
| 29 | + var REMOTE_PACKAGE_NAME = typeof Module['locateFile'] === 'function' ? |
| 30 | + Module['locateFile'](REMOTE_PACKAGE_BASE) : |
| 31 | + ((Module['filePackagePrefixURL'] || '') + REMOTE_PACKAGE_BASE); |
| 32 | + |
| 33 | + var REMOTE_PACKAGE_SIZE = metadata.remote_package_size; |
| 34 | + var PACKAGE_UUID = metadata.package_uuid; |
| 35 | + |
| 36 | + function fetchRemotePackage(packageName, packageSize, callback, errback) { |
| 37 | + var xhr = new XMLHttpRequest(); |
| 38 | + xhr.open('GET', packageName, true); |
| 39 | + xhr.responseType = 'arraybuffer'; |
| 40 | + xhr.onprogress = function(event) { |
| 41 | + var url = packageName; |
| 42 | + var size = packageSize; |
| 43 | + if (event.total) size = event.total; |
| 44 | + if (event.loaded) { |
| 45 | + if (!xhr.addedTotal) { |
| 46 | + xhr.addedTotal = true; |
| 47 | + if (!Module.dataFileDownloads) Module.dataFileDownloads = {}; |
| 48 | + Module.dataFileDownloads[url] = { |
| 49 | + loaded: event.loaded, |
| 50 | + total: size |
| 51 | + }; |
| 52 | + } else { |
| 53 | + Module.dataFileDownloads[url].loaded = event.loaded; |
| 54 | + } |
| 55 | + var total = 0; |
| 56 | + var loaded = 0; |
| 57 | + var num = 0; |
| 58 | + for (var download in Module.dataFileDownloads) { |
| 59 | + var data = Module.dataFileDownloads[download]; |
| 60 | + total += data.total; |
| 61 | + loaded += data.loaded; |
| 62 | + num++; |
| 63 | + } |
| 64 | + total = Math.ceil(total * Module.expectedDataFileDownloads/num); |
| 65 | + if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')'); |
| 66 | + } else if (!Module.dataFileDownloads) { |
| 67 | + if (Module['setStatus']) Module['setStatus']('Downloading data...'); |
| 68 | + } |
| 69 | + }; |
| 70 | + xhr.onerror = function(event) { |
| 71 | + throw new Error("NetworkError for: " + packageName); |
| 72 | + } |
| 73 | + xhr.onload = function(event) { |
| 74 | + if (xhr.status == 200 || xhr.status == 304 || xhr.status == 206 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0 |
| 75 | + var packageData = xhr.response; |
| 76 | + callback(packageData); |
| 77 | + } else { |
| 78 | + throw new Error(xhr.statusText + " : " + xhr.responseURL); |
| 79 | + } |
| 80 | + }; |
| 81 | + xhr.send(null); |
| 82 | + }; |
| 83 | + |
| 84 | + function handleError(error) { |
| 85 | + console.error('package error:', error); |
| 86 | + }; |
| 87 | + |
| 88 | + function runWithFS() { |
| 89 | + |
| 90 | + function assert(check, msg) { |
| 91 | + if (!check) throw msg + new Error().stack; |
| 92 | + } |
| 93 | + |
| 94 | + |
| 95 | + function DataRequest(start, end, crunched, audio) { |
| 96 | + this.start = start; |
| 97 | + this.end = end; |
| 98 | + this.crunched = crunched; |
| 99 | + this.audio = audio; |
| 100 | + } |
| 101 | + DataRequest.prototype = { |
| 102 | + requests: {}, |
| 103 | + open: function(mode, name) { |
| 104 | + this.name = name; |
| 105 | + this.requests[name] = this; |
| 106 | + Module['addRunDependency']('fp ' + this.name); |
| 107 | + }, |
| 108 | + send: function() {}, |
| 109 | + onload: function() { |
| 110 | + var byteArray = this.byteArray.subarray(this.start, this.end); |
| 111 | + |
| 112 | + this.finish(byteArray); |
| 113 | + |
| 114 | + }, |
| 115 | + finish: function(byteArray) { |
| 116 | + var that = this; |
| 117 | + |
| 118 | + Module['FS_createDataFile'](this.name, null, byteArray, true, true, true); // canOwn this data in the filesystem, it is a slide into the heap that will never change |
| 119 | + Module['removeRunDependency']('fp ' + that.name); |
| 120 | + |
| 121 | + this.requests[this.name] = null; |
| 122 | + } |
| 123 | + }; |
| 124 | + |
| 125 | + var files = metadata.files; |
| 126 | + for (i = 0; i < files.length; ++i) { |
| 127 | + new DataRequest(files[i].start, files[i].end, files[i].crunched, files[i].audio).open('GET', files[i].filename); |
| 128 | + } |
| 129 | + |
| 130 | + |
| 131 | + var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; |
| 132 | + var IDB_RO = "readonly"; |
| 133 | + var IDB_RW = "readwrite"; |
| 134 | + var DB_NAME = "EM_PRELOAD_CACHE"; |
| 135 | + var DB_VERSION = 1; |
| 136 | + var METADATA_STORE_NAME = 'METADATA'; |
| 137 | + var PACKAGE_STORE_NAME = 'PACKAGES'; |
| 138 | + function openDatabase(callback, errback) { |
| 139 | + try { |
| 140 | + var openRequest = indexedDB.open(DB_NAME, DB_VERSION); |
| 141 | + } catch (e) { |
| 142 | + return errback(e); |
| 143 | + } |
| 144 | + openRequest.onupgradeneeded = function(event) { |
| 145 | + var db = event.target.result; |
| 146 | + |
| 147 | + if(db.objectStoreNames.contains(PACKAGE_STORE_NAME)) { |
| 148 | + db.deleteObjectStore(PACKAGE_STORE_NAME); |
| 149 | + } |
| 150 | + var packages = db.createObjectStore(PACKAGE_STORE_NAME); |
| 151 | + |
| 152 | + if(db.objectStoreNames.contains(METADATA_STORE_NAME)) { |
| 153 | + db.deleteObjectStore(METADATA_STORE_NAME); |
| 154 | + } |
| 155 | + var metadata = db.createObjectStore(METADATA_STORE_NAME); |
| 156 | + }; |
| 157 | + openRequest.onsuccess = function(event) { |
| 158 | + var db = event.target.result; |
| 159 | + callback(db); |
| 160 | + }; |
| 161 | + openRequest.onerror = function(error) { |
| 162 | + errback(error); |
| 163 | + }; |
| 164 | + }; |
| 165 | + |
| 166 | + /* Check if there's a cached package, and if so whether it's the latest available */ |
| 167 | + function checkCachedPackage(db, packageName, callback, errback) { |
| 168 | + var transaction = db.transaction([METADATA_STORE_NAME], IDB_RO); |
| 169 | + var metadata = transaction.objectStore(METADATA_STORE_NAME); |
| 170 | + |
| 171 | + var getRequest = metadata.get("metadata/" + packageName); |
| 172 | + getRequest.onsuccess = function(event) { |
| 173 | + var result = event.target.result; |
| 174 | + if (!result) { |
| 175 | + return callback(false); |
| 176 | + } else { |
| 177 | + return callback(PACKAGE_UUID === result.uuid); |
| 178 | + } |
| 179 | + }; |
| 180 | + getRequest.onerror = function(error) { |
| 181 | + errback(error); |
| 182 | + }; |
| 183 | + }; |
| 184 | + |
| 185 | + function fetchCachedPackage(db, packageName, callback, errback) { |
| 186 | + var transaction = db.transaction([PACKAGE_STORE_NAME], IDB_RO); |
| 187 | + var packages = transaction.objectStore(PACKAGE_STORE_NAME); |
| 188 | + |
| 189 | + var getRequest = packages.get("package/" + packageName); |
| 190 | + getRequest.onsuccess = function(event) { |
| 191 | + var result = event.target.result; |
| 192 | + callback(result); |
| 193 | + }; |
| 194 | + getRequest.onerror = function(error) { |
| 195 | + errback(error); |
| 196 | + }; |
| 197 | + }; |
| 198 | + |
| 199 | + function cacheRemotePackage(db, packageName, packageData, packageMeta, callback, errback) { |
| 200 | + var transaction_packages = db.transaction([PACKAGE_STORE_NAME], IDB_RW); |
| 201 | + var packages = transaction_packages.objectStore(PACKAGE_STORE_NAME); |
| 202 | + |
| 203 | + var putPackageRequest = packages.put(packageData, "package/" + packageName); |
| 204 | + putPackageRequest.onsuccess = function(event) { |
| 205 | + var transaction_metadata = db.transaction([METADATA_STORE_NAME], IDB_RW); |
| 206 | + var metadata = transaction_metadata.objectStore(METADATA_STORE_NAME); |
| 207 | + var putMetadataRequest = metadata.put(packageMeta, "metadata/" + packageName); |
| 208 | + putMetadataRequest.onsuccess = function(event) { |
| 209 | + callback(packageData); |
| 210 | + }; |
| 211 | + putMetadataRequest.onerror = function(error) { |
| 212 | + errback(error); |
| 213 | + }; |
| 214 | + }; |
| 215 | + putPackageRequest.onerror = function(error) { |
| 216 | + errback(error); |
| 217 | + }; |
| 218 | + }; |
| 219 | + |
| 220 | + function processPackageData(arrayBuffer) { |
| 221 | + Module.finishedDataFileDownloads++; |
| 222 | + assert(arrayBuffer, 'Loading data file failed.'); |
| 223 | + assert(arrayBuffer instanceof ArrayBuffer, 'bad input to processPackageData'); |
| 224 | + var byteArray = new Uint8Array(arrayBuffer); |
| 225 | + var curr; |
| 226 | + |
| 227 | + // copy the entire loaded file into a spot in the heap. Files will refer to slices in that. They cannot be freed though |
| 228 | + // (we may be allocating before malloc is ready, during startup). |
| 229 | + if (Module['SPLIT_MEMORY']) Module.printErr('warning: you should run the file packager with --no-heap-copy when SPLIT_MEMORY is used, otherwise copying into the heap may fail due to the splitting'); |
| 230 | + var ptr = Module['getMemory'](byteArray.length); |
| 231 | + Module['HEAPU8'].set(byteArray, ptr); |
| 232 | + DataRequest.prototype.byteArray = Module['HEAPU8'].subarray(ptr, ptr+byteArray.length); |
| 233 | + |
| 234 | + var files = metadata.files; |
| 235 | + for (i = 0; i < files.length; ++i) { |
| 236 | + DataRequest.prototype.requests[files[i].filename].onload(); |
| 237 | + } |
| 238 | + Module['removeRunDependency']('datafile_game.data'); |
| 239 | + |
| 240 | + }; |
| 241 | + Module['addRunDependency']('datafile_game.data'); |
| 242 | + |
| 243 | + if (!Module.preloadResults) Module.preloadResults = {}; |
| 244 | + |
| 245 | + function preloadFallback(error) { |
| 246 | + console.error(error); |
| 247 | + console.error('falling back to default preload behavior'); |
| 248 | + fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, processPackageData, handleError); |
| 249 | + }; |
| 250 | + |
| 251 | + openDatabase( |
| 252 | + function(db) { |
| 253 | + checkCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, |
| 254 | + function(useCached) { |
| 255 | + Module.preloadResults[PACKAGE_NAME] = {fromCache: useCached}; |
| 256 | + if (useCached) { |
| 257 | + console.info('loading ' + PACKAGE_NAME + ' from cache'); |
| 258 | + fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, processPackageData, preloadFallback); |
| 259 | + } else { |
| 260 | + console.info('loading ' + PACKAGE_NAME + ' from remote'); |
| 261 | + fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, |
| 262 | + function(packageData) { |
| 263 | + cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID}, processPackageData, |
| 264 | + function(error) { |
| 265 | + console.error(error); |
| 266 | + processPackageData(packageData); |
| 267 | + }); |
| 268 | + } |
| 269 | + , preloadFallback); |
| 270 | + } |
| 271 | + } |
| 272 | + , preloadFallback); |
| 273 | + } |
| 274 | + , preloadFallback); |
| 275 | + |
| 276 | + if (Module['setStatus']) Module['setStatus']('Downloading...'); |
| 277 | + |
| 278 | + } |
| 279 | + if (Module['calledRun']) { |
| 280 | + runWithFS(); |
| 281 | + } else { |
| 282 | + if (!Module['preRun']) Module['preRun'] = []; |
| 283 | + Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it |
| 284 | + } |
| 285 | + |
| 286 | + } |
| 287 | + loadPackage({"package_uuid":"80826f15-f924-4428-a8c4-e984743417c6","remote_package_size":62246034,"files":[{"filename":"/game.love","crunched":0,"start":0,"end":62246034,"audio":false}]}); |
| 288 | + |
| 289 | +})(); |
0 commit comments