|
1 | 1 | var GDragonRubyGameId = 'dragonruby-sandbox'; |
2 | 2 | var GDragonRubyGameTitle = 'DragonRuby Sandbox'; |
3 | 3 | var GDragonRubyDevTitle = 'DragonRuby'; |
4 | | -var GDragonRubyGameVersion = '1.0'; |
| 4 | +var GDragonRubyGameVersion = '2.0'; |
5 | 5 | var GDragonRubyIcon = '/metadata/icon.png'; |
6 | 6 |
|
7 | 7 | function syncDataFiles(dbname, baseurl) |
@@ -31,7 +31,7 @@ function syncDataFiles(dbname, baseurl) |
31 | 31 | total_to_download: 0, |
32 | 32 | total_downloaded: 0, |
33 | 33 | total_files: 0, |
34 | | - pending_files: 0 |
| 34 | + pending_files: [] |
35 | 35 | }; |
36 | 36 |
|
37 | 37 | var log = function(str) { console.log("CACHEAPPDATA: " + str); } |
@@ -104,15 +104,16 @@ function syncDataFiles(dbname, baseurl) |
104 | 104 | failed("Couldn't open local database: " + event.target.error.message); |
105 | 105 | }; |
106 | 106 |
|
| 107 | + // !!! FIXME: there _has_ to be a better way to do this, right? |
| 108 | + var hash_count = function(h) { |
| 109 | + var k = Object.keys(h); |
| 110 | + return (k === undefined) ? 0 : k.length; |
| 111 | + } |
| 112 | + |
107 | 113 | var finished_file = function(fname) { |
108 | 114 | debug("Finished writing '" + fname + "' to the database!"); |
109 | | - state.pending_files--; |
110 | | - if (state.pending_files < 0) { |
111 | | - state.pending_files = 0; |
112 | | - debug("Uhoh, pending_files went negative?!"); |
113 | | - } |
114 | | - if (state.pending_files == 0) { |
115 | | - succeeded(); |
| 115 | + if ((hash_count(state.xhrs) == 0) && (state.pending_files.length == 0)) { |
| 116 | + succeeded(); // nothing downloading, nothing new to download, and everything is written to disk. Success! |
116 | 117 | } |
117 | 118 | }; |
118 | 119 |
|
@@ -144,76 +145,89 @@ function syncDataFiles(dbname, baseurl) |
144 | 145 | }; |
145 | 146 | }; |
146 | 147 |
|
| 148 | + var download_another_file = function() { |
| 149 | + if (state.pending_files.length == 0) { |
| 150 | + return false; // nothing to do. |
| 151 | + } |
| 152 | + |
| 153 | + var remotefname = state.pending_files.pop(); |
| 154 | + var remoteitem = state.remote_manifest[remotefname]; |
| 155 | + var xhr = new XMLHttpRequest(); |
| 156 | + state.xhrs[remotefname] = xhr; |
| 157 | + xhr.previously_loaded = 0; |
| 158 | + xhr.filename = remotefname; |
| 159 | + xhr.filesize = remoteitem.filesize; |
| 160 | + xhr.filetime = remoteitem.filetime; |
| 161 | + xhr.expected_filesize = remoteitem.filesize; |
| 162 | + xhr.responseType = "arraybuffer"; |
| 163 | + xhr.addEventListener("error", function(e) { failed("Download error on '" + e.target.filename + "'!"); }); |
| 164 | + xhr.addEventListener("timeout", function(e) { failed("Download timeout on '" + e.target.filename + "'!"); }); |
| 165 | + xhr.addEventListener("abort", function(e) { failed("Download abort on '" + e.target.filename + "'!"); }); |
| 166 | + |
| 167 | + xhr.addEventListener('progress', function(e) { |
| 168 | + if (state.reported_result) { return; } |
| 169 | + var xhr = e.target; |
| 170 | + var additional = e.loaded - xhr.previously_loaded; |
| 171 | + state.total_downloaded += additional; |
| 172 | + xhr.previously_loaded = e.loaded; |
| 173 | + debug("Downloaded " + additional + " more bytes for file '" + xhr.filename + "'"); |
| 174 | + var percent = state.total_to_download ? Math.floor((state.total_downloaded / state.total_to_download) * 100.0) : 0; |
| 175 | + progress("Downloaded " + percent + "% (" + Math.ceil(state.total_downloaded / 1048576) + "/" + Math.ceil(state.total_to_download / 1048576) + " megabytes)"); |
| 176 | + }); |
| 177 | + |
| 178 | + xhr.addEventListener("load", function(e) { |
| 179 | + if (state.reported_result) { return; } |
| 180 | + var xhr = e.target; |
| 181 | + if (xhr.status != 200) { |
| 182 | + failed("Server reported failure downloading '" + xhr.filename + "'!"); |
| 183 | + } else { |
| 184 | + debug("Finished download of '" + xhr.filename + "'!"); |
| 185 | + state.total_downloaded -= xhr.previously_loaded; |
| 186 | + state.total_downloaded += xhr.expected_filesize; |
| 187 | + xhr.previously_loaded = xhr.expected_filesize; |
| 188 | + delete state.xhrs[xhr.filename]; |
| 189 | + var percent = state.total_to_download ? Math.floor((state.total_downloaded / state.total_to_download) * 100.0) : 0; |
| 190 | + progress("Downloaded " + percent + "% (" + Math.ceil(state.total_downloaded / 1048576) + "/" + Math.ceil(state.total_to_download / 1048576) + " megabytes)"); |
| 191 | + download_another_file(); // kick off another download now that this one is done. |
| 192 | + store_file(xhr); |
| 193 | + } |
| 194 | + }); |
| 195 | + |
| 196 | + debug("Starting download of '" + xhr.filename + "'..."); |
| 197 | + xhr.open("get", baseurl + remotefname + urlrandomizerarg, true); |
| 198 | + xhr.send(); |
| 199 | + return true; |
| 200 | + } |
| 201 | + |
147 | 202 | var download_new_files = function() { |
148 | 203 | if (state.reported_result) { return; } |
149 | 204 | progress("Downloading new files..."); |
150 | | - var downloadme = []; |
151 | 205 | for (var i in state.remote_manifest) { |
152 | 206 | var remoteitem = state.remote_manifest[i]; |
153 | 207 | var remotefname = i; |
154 | 208 | if (typeof state.local_manifest[remotefname] !== "undefined") { |
155 | 209 | debug("remote filename '" + remotefname + "' already downloaded."); |
156 | 210 | } else { |
157 | 211 | debug("remote filename '" + remotefname + "' needs downloading."); |
158 | | - // the browser will let a handful of these go in parallel, and |
159 | | - // then will queue the rest, firing events as appropriate |
160 | | - // when it gets around to them, so just fire them all off |
161 | | - // here. |
162 | | - |
163 | 212 | // !!! FIXME: use the Fetch API, plus streaming, as an option. |
164 | 213 | // !!! FIXME: It can use less memory, since it doesn't need |
165 | 214 | // !!! FIXME: to keep the whole file in memory. |
166 | 215 | state.total_to_download += remoteitem.filesize; |
167 | 216 | state.total_files++; |
168 | | - state.pending_files++; |
169 | | - |
170 | | - var xhr = new XMLHttpRequest(); |
171 | | - state.xhrs[remotefname] = xhr; |
172 | | - xhr.previously_loaded = 0; |
173 | | - xhr.filename = remotefname; |
174 | | - xhr.filesize = state.remote_manifest[i].filesize; |
175 | | - xhr.filetime = state.remote_manifest[i].filetime; |
176 | | - xhr.expected_filesize = remoteitem.filesize; |
177 | | - xhr.responseType = "arraybuffer"; |
178 | | - xhr.addEventListener("error", function(e) { failed("Download error on '" + e.target.filename + "'!"); }); |
179 | | - xhr.addEventListener("timeout", function(e) { failed("Download timeout on '" + e.target.filename + "'!"); }); |
180 | | - xhr.addEventListener("abort", function(e) { failed("Download abort on '" + e.target.filename + "'!"); }); |
181 | | - |
182 | | - xhr.addEventListener('progress', function(e) { |
183 | | - if (state.reported_result) { return; } |
184 | | - var xhr = e.target; |
185 | | - var additional = e.loaded - xhr.previously_loaded; |
186 | | - state.total_downloaded += additional; |
187 | | - xhr.previously_loaded = e.loaded; |
188 | | - debug("Downloaded " + additional + " more bytes for file '" + xhr.filename + "'"); |
189 | | - var percent = state.total_to_download ? Math.floor((state.total_downloaded / state.total_to_download) * 100.0) : 0; |
190 | | - progress("Downloaded " + percent + "% (" + Math.ceil(state.total_downloaded / 1048576) + "/" + Math.ceil(state.total_to_download / 1048576) + " megabytes)"); |
191 | | - }); |
192 | | - |
193 | | - xhr.addEventListener("load", function(e) { |
194 | | - if (state.reported_result) { return; } |
195 | | - var xhr = e.target; |
196 | | - if (xhr.status != 200) { |
197 | | - failed("Server reported failure downloading '" + xhr.filename + "'!"); |
198 | | - } else { |
199 | | - debug("Finished download of '" + xhr.filename + "'!"); |
200 | | - state.total_downloaded -= xhr.previously_loaded; |
201 | | - state.total_downloaded += xhr.expected_filesize; |
202 | | - xhr.previously_loaded = xhr.expected_filesize; |
203 | | - delete state.xhrs[xhr.filename]; |
204 | | - var percent = state.total_to_download ? Math.floor((state.total_downloaded / state.total_to_download) * 100.0) : 0; |
205 | | - progress("Downloaded " + percent + "% (" + Math.ceil(state.total_downloaded / 1048576) + "/" + Math.ceil(state.total_to_download / 1048576) + " megabytes)"); |
206 | | - store_file(xhr); |
207 | | - } |
208 | | - }); |
209 | | - |
210 | | - xhr.open("get", baseurl + remotefname + urlrandomizerarg, true); |
211 | | - xhr.send(); |
| 217 | + state.pending_files.push(remotefname) |
212 | 218 | } |
213 | 219 | } |
214 | 220 |
|
215 | | - if (state.pending_files == 0) { |
| 221 | + if (state.pending_files.length == 0) { |
216 | 222 | succeeded(); // we're already done. :) |
| 223 | + return; |
| 224 | + } |
| 225 | + |
| 226 | + var max_concurrent_downloads = 4; |
| 227 | + while (download_another_file()) { |
| 228 | + if (hash_count(state.xhrs) >= max_concurrent_downloads) { |
| 229 | + break; // we'll start another as each download completes. |
| 230 | + } |
217 | 231 | } |
218 | 232 | }; |
219 | 233 |
|
|
0 commit comments