Progress towards in-launcher download ui. Works, but is very fragile.

This commit is contained in:
Paul Chote
2010-11-20 13:05:30 +13:00
parent b4b05c3f4e
commit 2fc88e439d
4 changed files with 80 additions and 49 deletions

View File

@@ -8,14 +8,6 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
typedef enum {
Initializing,
Downloading,
Complete,
Cancelled,
Error
} DownloadStatus;
@class GameInstall; @class GameInstall;
@interface Download : NSObject @interface Download : NSObject
{ {
@@ -24,12 +16,12 @@ typedef enum {
NSString *filename; NSString *filename;
GameInstall *game; GameInstall *game;
NSTask *task; NSTask *task;
DownloadStatus status; NSString * status;
int bytesCompleted; int bytesCompleted;
int bytesTotal; int bytesTotal;
} }
@property(readonly) NSString *key; @property(readonly) NSString *key;
@property(readonly) DownloadStatus status; @property(readonly) NSString *status;
@property(readonly) int bytesCompleted; @property(readonly) int bytesCompleted;
@property(readonly) int bytesTotal; @property(readonly) int bytesTotal;

View File

@@ -32,7 +32,7 @@
filename = [aFilename retain]; filename = [aFilename retain];
key = [aKey retain]; key = [aKey retain];
game = [aGame retain]; game = [aGame retain];
status = Initializing; status = @"Initializing";
bytesCompleted = -1; bytesCompleted = -1;
bytesTotal = -1; bytesTotal = -1;
@@ -65,17 +65,17 @@
if ([type isEqualToString:@"Error"]) if ([type isEqualToString:@"Error"])
{ {
status = Error; status = @"Error";
} }
else if ([type isEqualToString:@"Status"]) else if ([type isEqualToString:@"Status"])
{ {
if ([message isEqualToString:@"Initializing"]) if ([message isEqualToString:@"Initializing"])
{ {
status = Initializing; status = @"Initializing";
} }
else if ([message isEqualToString:@"Completed"]) else if ([message isEqualToString:@"Completed"])
{ {
status = Complete; status = @"Complete";
} }
// Parse download status info // Parse download status info
@@ -97,7 +97,7 @@
- (void)cancel - (void)cancel
{ {
NSLog(@"Cancelling"); NSLog(@"Cancelling");
status = Cancelled; status = @"Cancelled";
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]]; [nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]];
[nc removeObserver:self name:NSTaskDidTerminateNotification object:task]; [nc removeObserver:self name:NSTaskDidTerminateNotification object:task];

View File

@@ -42,13 +42,13 @@ static JSBridge *SharedInstance;
methods = [[NSDictionary dictionaryWithObjectsAndKeys: methods = [[NSDictionary dictionaryWithObjectsAndKeys:
@"launchMod", NSStringFromSelector(@selector(launchMod:)), @"launchMod", NSStringFromSelector(@selector(launchMod:)),
@"log", NSStringFromSelector(@selector(log:)), @"log", NSStringFromSelector(@selector(log:)),
@"existsInMod", NSStringFromSelector(@selector(exists:inMod:)), @"existsInMod", NSStringFromSelector(@selector(fileExists:inMod:)),
// File downloading // File downloading
@"existsInCache", NSStringFromSelector(@selector(existsInCache:)), @"existsInCache", NSStringFromSelector(@selector(existsInCache:)),
@"downloadToCache", NSStringFromSelector(@selector(downloadUrl:withName:key:)), @"downloadToCache", NSStringFromSelector(@selector(downloadUrl:withName:key:)),
@"cancelDownload", NSStringFromSelector(@selector(cancelDownload:)), @"cancelDownload", NSStringFromSelector(@selector(cancelDownload:)),
@"isDownloading", NSStringFromSelector(@selector(isDownloading:)), @"downloadStatus", NSStringFromSelector(@selector(downloadStatus:)),
@"bytesCompleted", NSStringFromSelector(@selector(bytesCompleted:)), @"bytesCompleted", NSStringFromSelector(@selector(bytesCompleted:)),
@"bytesTotal", NSStringFromSelector(@selector(bytesTotal:)), @"bytesTotal", NSStringFromSelector(@selector(bytesTotal:)),
nil] retain]; nil] retain];
@@ -124,9 +124,13 @@ static JSBridge *SharedInstance;
[controller cancelDownload:key]; [controller cancelDownload:key];
} }
- (BOOL)isDownloading:(NSString *)key - (NSString *)downloadStatus:(NSString *)key
{ {
return [controller downloadWithKey:key] != nil; Download *d = [controller downloadWithKey:key];
if (d == nil)
return @"Invalid";
return [d status];
} }
- (int)bytesCompleted:(NSString *)key - (int)bytesCompleted:(NSString *)key

View File

@@ -90,10 +90,9 @@
// Returns 2 if basic files plus music are installed // Returns 2 if basic files plus music are installed
function packagesInstalled() function packagesInstalled()
{ {
if (window.external.existsInMod('packages/conquer.mix','cnc') != 1) if (window.external.existsInMod("packages/conquer.mix","cnc") != 1)
return 0; return 0;
return (window.external.existsInMod("packages/scores.mix","cnc") == 1) ? 2 : 1;
return (window.external.existsInMod('packages/scores.mix','cnc') == 1) ? 2 : 1;
} }
function play() function play()
@@ -101,39 +100,71 @@
window.external.launchMod("cnc"); window.external.launchMod("cnc");
} }
function download1() function download()
{ {
window.external.downloadToCache("http://localhost/~paul/cnc-packages.zip","test.zip","cnc-packages"); window.external.downloadToCache("http://localhost/~paul/cnc-packages.zip","cnc-packages.zip","cnc-packages");
document.getElementById("install-download").style.display = "none";
document.getElementById("install-downloading").style.display = "";
} }
function download2() function cancel()
{
window.external.downloadToCache("http://localhost/~paul/ra-packages.zip","test2.zip","ra-packages");
}
function cancel1()
{ {
window.external.cancelDownload("cnc-packages"); window.external.cancelDownload("cnc-packages");
// TODO: Remove incomplete file from cache
// TODO: Restore buttons to the before-downloading state
} }
function cancel2() function extract()
{ {
window.external.cancelDownload("ra-packages"); window.external.log("Todo: Extract package");
} }
function onLoad() function onLoad()
{ {
document.getElementById("buttons-install").style.display = (packagesInstalled() == 0) ? "" : "none"; var installed = packagesInstalled();
document.getElementById("buttons-upgrade").style.display = (packagesInstalled() == 1) ? "" : "none"; document.getElementById("buttons-install").style.display = (installed == 0) ? "" : "none";
document.getElementById("buttons-play").style.display = (packagesInstalled() == 2) ? "" : "none"; document.getElementById("buttons-upgrade").style.display = (installed == 1) ? "" : "none";
document.getElementById("buttons-play").style.display = (installed == 2) ? "" : "none";
window.external.log("installed: "+installed);
// Select the correct subsection
if (installed == 0)
{
var downloaded = window.external.existsInCache("cnc-packages.zip");
window.external.log("downloaded: "+downloaded);
document.getElementById("install-extract").style.display = downloaded ? "" : "none";
document.getElementById("install-download").style.display = !downloaded ? "" : "none";
}
} }
function downloadProgressed(file) function downloadProgressed(file)
{ {
var total = window.external.bytesTotal(file); if (file != "cnc-packages")
var downloaded = window.external.bytesCompleted(file); return;
var percent = (100*downloaded/total).toPrecision(3);
window.external.log("file: "+file+" "+downloaded+"/"+total+" ("+percent+"%)"); var status = window.external.downloadStatus(file);
if (status == "Complete")
{
document.getElementById("install-extract").style.display = "";
document.getElementById("install-downloading").style.display = "none";
}
var total = window.external.bytesTotal(file);
var downloaded = window.external.bytesCompleted(file);
var multiplier = 1/1024.0;
var unit = "kB";
var max = max(total,downloaded); // total may be -1 if the server doesn't supply a size
if (max > 1.1*1024*1024)
{
multiplier /= 1024;
unit = "MB";
}
total = (total*multiplier).toPrecision(2);
downloaded = (downloaded*multiplier).toPrecision(2);
document.getElementById("download-status").value = downloaded+"/"+total+" "+unit;
window.external.log("file: "+file+" "+downloaded+"/"+total+" ("+percent+"%)");
} }
</script> </script>
@@ -144,7 +175,7 @@
</div> </div>
<div id="main"> <div id="main">
<div id="content"> <!-- div id="content">
<h2>Latest News</h2> <h2>Latest News</h2>
<div> <div>
<h3>Version XXYYZZ Available</h3> <h3>Version XXYYZZ Available</h3>
@@ -154,17 +185,21 @@
<li>Bugfixes!!!</li> <li>Bugfixes!!!</li>
</ul> </ul>
</div> </div>
</div> </div -->
<div id="buttons-install" class="buttons"> <div id="buttons-install" class="buttons">
<div class="desc">The original game data is required before you can play this mod.<br /> <div class="desc">The original game data is required before you can play this mod.<br />
Installing from web will install the minimal files required to play.<br /> Installing from web will install the minimal files required to play.
Installing from CD will also install the music and movie files for an improved game experience. </div>
<div id="install-download">
<input type="button" class="button" onclick="download();" value="Download" />
</div>
<div id="install-downloading" style="display:none">
<input type="button" class="button" id="download-status" value="Initializing..." />
<input type="button" class="button" onclick="cancel();" value="Cancel" />
</div>
<div id="install-extract">
<input type="button" class="button" onclick="install();" value="Install" />
</div> </div>
<input type="button" class="button" onclick="download1();" value="Download1" />
<input type="button" class="button" onclick="cancel1();" value="Cancel1" />
<input type="button" class="button" onclick="download2();" value="Download2" />
<input type="button" class="button" onclick="cancel2();" value="Cancel2" />
</div> </div>
<div id="buttons-upgrade" class="buttons" style="display:none"> <div id="buttons-upgrade" class="buttons" style="display:none">
<div class="desc"> <div class="desc">