Use utility app for http requests; Make them async.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
SidebarEntry *sidebarItems;
|
||||
GameInstall *game;
|
||||
NSDictionary *allMods;
|
||||
NSMutableArray *httpRequests;
|
||||
NSMutableDictionary *downloads;
|
||||
BOOL hasMono;
|
||||
|
||||
@@ -33,6 +34,7 @@
|
||||
- (SidebarEntry *)sidebarModsTree;
|
||||
- (SidebarEntry *)sidebarOtherTree;
|
||||
|
||||
- (void)fetchURL:(NSString *)url withCallback:(NSString *)cb;
|
||||
- (BOOL)registerDownload:(NSString *)key withURL:(NSString *)url filePath:(NSString *)path;
|
||||
- (Download *)downloadWithKey:(NSString *)key;
|
||||
- (BOOL)hasSupportedMono;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#import "ImageAndTextCell.h"
|
||||
#import "JSBridge.h"
|
||||
#import "Download.h"
|
||||
#import "HttpRequest.h"
|
||||
|
||||
@implementation Controller
|
||||
@synthesize allMods;
|
||||
@@ -32,6 +33,7 @@
|
||||
game = [[GameInstall alloc] initWithPath:gamePath];
|
||||
[[JSBridge sharedInstance] setController:self];
|
||||
downloads = [[NSMutableDictionary alloc] init];
|
||||
httpRequests = [[NSMutableArray alloc] init];
|
||||
hasMono = [self hasSupportedMono];
|
||||
if (hasMono)
|
||||
{
|
||||
@@ -120,6 +122,7 @@
|
||||
{
|
||||
[sidebarItems release]; sidebarItems = nil;
|
||||
[downloads release]; downloads = nil;
|
||||
[httpRequests release]; httpRequests = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -176,6 +179,17 @@
|
||||
return [downloads objectForKey:key];
|
||||
}
|
||||
|
||||
- (void)fetchURL:(NSString *)url withCallback:(NSString *)cb
|
||||
{
|
||||
// Clean up any completed requests
|
||||
for (int i = [httpRequests count] - 1; i >= 0; i--)
|
||||
if ([[httpRequests objectAtIndex:i] terminated])
|
||||
[httpRequests removeObjectAtIndex:i];
|
||||
|
||||
// Create request
|
||||
[httpRequests addObject:[HttpRequest requestWithURL:url callback:cb game:game]];
|
||||
}
|
||||
|
||||
#pragma mark Sidebar Datasource and Delegate
|
||||
- (NSInteger)outlineView:(NSOutlineView *)anOutlineView numberOfChildrenOfItem:(id)item
|
||||
{
|
||||
@@ -245,6 +259,10 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn
|
||||
#pragma mark WebView delegates
|
||||
- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowObject forFrame:(WebFrame *)frame
|
||||
{
|
||||
// Cancel any in progress http requests
|
||||
for (HttpRequest *r in httpRequests)
|
||||
[r cancel];
|
||||
|
||||
[windowObject setValue:[JSBridge sharedInstance] forKey:@"external"];
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
[[NSFileManager defaultManager] removeItemAtPath:filename error:NULL];
|
||||
bytesCompleted = bytesTotal = -1;
|
||||
|
||||
[[JSBridge sharedInstance] notifyDownloadProgress:self];
|
||||
[[JSBridge sharedInstance] runCallback:@"downloadProgressed" withArgument:[self key]];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
name:NSFileHandleReadCompletionNotification
|
||||
object:[[task standardOutput] fileHandleForReading]];
|
||||
@@ -120,7 +120,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
[[JSBridge sharedInstance] notifyDownloadProgress:self];
|
||||
[[JSBridge sharedInstance] runCallback:@"downloadProgressed" withArgument:[self key]];
|
||||
|
||||
// Keep reading
|
||||
if ([n object] != nil)
|
||||
@@ -171,8 +171,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
[[JSBridge sharedInstance] notifyExtractProgress:self];
|
||||
|
||||
[[JSBridge sharedInstance] runCallback:@"extractProgressed" withArgument:[self key]];
|
||||
|
||||
// Keep reading
|
||||
if ([n object] != nil)
|
||||
[[n object] readInBackgroundAndNotify];
|
||||
|
||||
@@ -19,6 +19,5 @@
|
||||
|
||||
+ (JSBridge *)sharedInstance;
|
||||
- (void)setController:(Controller *)aController;
|
||||
- (void)notifyDownloadProgress:(Download *)download;
|
||||
- (void)notifyExtractProgress:(Download *)download;
|
||||
- (void)runCallback:(NSString *)cb withArgument:(NSString *)arg;
|
||||
@end
|
||||
|
||||
@@ -44,7 +44,7 @@ static JSBridge *SharedInstance;
|
||||
@"log", NSStringFromSelector(@selector(log:)),
|
||||
@"existsInMod", NSStringFromSelector(@selector(fileExists:inMod:)),
|
||||
@"metadata", NSStringFromSelector(@selector(metadata:forMod:)),
|
||||
@"httpRequest", NSStringFromSelector(@selector(httpRequest:)),
|
||||
@"httpRequest", NSStringFromSelector(@selector(httpRequest:withCallback:)),
|
||||
|
||||
// File downloading
|
||||
@"registerDownload", NSStringFromSelector(@selector(registerDownload:withURL:filename:)),
|
||||
@@ -71,6 +71,13 @@ static JSBridge *SharedInstance;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)runCallback:(NSString *)cb withArgument:(NSString *)arg
|
||||
{
|
||||
NSString *cmd = [NSString stringWithFormat:@"%@('%@')", cb,
|
||||
[arg stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]];
|
||||
[[[controller webView] windowScriptObject] evaluateWebScript:cmd];
|
||||
}
|
||||
|
||||
#pragma mark JS API methods
|
||||
|
||||
- (BOOL)launchMod:(NSString *)aMod
|
||||
@@ -155,18 +162,6 @@ static JSBridge *SharedInstance;
|
||||
return (d == nil) ? -1 : [d bytesTotal];
|
||||
}
|
||||
|
||||
- (void)notifyDownloadProgress:(Download *)download
|
||||
{
|
||||
[[[controller webView] windowScriptObject] evaluateWebScript:
|
||||
[NSString stringWithFormat:@"downloadProgressed('%@')",[download key]]];
|
||||
}
|
||||
|
||||
- (void)notifyExtractProgress:(Download *)download
|
||||
{
|
||||
[[[controller webView] windowScriptObject] evaluateWebScript:
|
||||
[NSString stringWithFormat:@"extractProgressed('%@')",[download key]]];
|
||||
}
|
||||
|
||||
- (BOOL)extractDownload:(NSString *)key toPath:(NSString *)aFile inMod:(NSString *)aMod
|
||||
{
|
||||
Download *d = [controller downloadWithKey:key];
|
||||
@@ -233,12 +228,9 @@ static JSBridge *SharedInstance;
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (NSString *)httpRequest:(NSString *)url
|
||||
- (void)httpRequest:(NSString *)url withCallback:(NSString *)cb
|
||||
{
|
||||
NSLog(@"Requesting url %@",url);
|
||||
NSString *response = [NSString stringWithContentsOfURL:[NSURL URLWithString:url] encoding:NSASCIIStringEncoding error:NULL];
|
||||
NSLog(@"Response %@",response);
|
||||
return response;
|
||||
[controller fetchURL:url withCallback:cb];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
DA81FC3F12911E2B00C48F2F /* GameInstall.m in Sources */ = {isa = PBXBuildFile; fileRef = DA81FC3E12911E2B00C48F2F /* GameInstall.m */; };
|
||||
DA9295A712921DF900EDB02E /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9295A612921DF900EDB02E /* WebKit.framework */; };
|
||||
DA9296901292328200EDB02E /* SidebarEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DA92968F1292328200EDB02E /* SidebarEntry.m */; };
|
||||
DAA3F31C12CBF60D00E214BF /* HttpRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA3F31B12CBF60D00E214BF /* HttpRequest.m */; };
|
||||
DAB887F5129E5D6C00C99407 /* SDL in Resources */ = {isa = PBXBuildFile; fileRef = DAB887EE129E5D6100C99407 /* SDL */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -49,6 +50,8 @@
|
||||
DA9295A612921DF900EDB02E /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
|
||||
DA92968E1292328200EDB02E /* SidebarEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SidebarEntry.h; sourceTree = "<group>"; };
|
||||
DA92968F1292328200EDB02E /* SidebarEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SidebarEntry.m; sourceTree = "<group>"; };
|
||||
DAA3F31A12CBF60D00E214BF /* HttpRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpRequest.h; sourceTree = "<group>"; };
|
||||
DAA3F31B12CBF60D00E214BF /* HttpRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HttpRequest.m; sourceTree = "<group>"; };
|
||||
DAB887EE129E5D6100C99407 /* SDL */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = SDL; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -80,8 +83,10 @@
|
||||
DA7D85661295E92900E58547 /* Download.m */,
|
||||
DA92968E1292328200EDB02E /* SidebarEntry.h */,
|
||||
DA92968F1292328200EDB02E /* SidebarEntry.m */,
|
||||
DA38212012925344003B0BB5 /* JSBridge.h */,
|
||||
DA38212112925344003B0BB5 /* JSBridge.m */,
|
||||
DA38212012925344003B0BB5 /* JSBridge.h */,
|
||||
DAA3F31A12CBF60D00E214BF /* HttpRequest.h */,
|
||||
DAA3F31B12CBF60D00E214BF /* HttpRequest.m */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
@@ -229,6 +234,7 @@
|
||||
DA9296901292328200EDB02E /* SidebarEntry.m in Sources */,
|
||||
DA38212212925344003B0BB5 /* JSBridge.m in Sources */,
|
||||
DA7D85671295E92900E58547 /* Download.m in Sources */,
|
||||
DAA3F31C12CBF60D00E214BF /* HttpRequest.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -85,29 +85,48 @@ namespace OpenRA.Utility
|
||||
public static void DownloadUrl(string argValue)
|
||||
{
|
||||
string[] args = argValue.Split(',');
|
||||
string url = args[0];
|
||||
WebClient wc = new WebClient();
|
||||
|
||||
if (args.Length == 1)
|
||||
{
|
||||
wc.DownloadStringCompleted += DownloadStringCompleted;
|
||||
|
||||
wc.DownloadStringAsync(new Uri(url));
|
||||
}
|
||||
else if (args.Length == 2)
|
||||
{
|
||||
string path = args[1].Replace("~",Environment.GetFolderPath(Environment.SpecialFolder.Personal));
|
||||
|
||||
wc.DownloadProgressChanged += DownloadProgressChanged;
|
||||
wc.DownloadFileCompleted += DownloadFileCompleted;
|
||||
|
||||
Console.WriteLine("Downloading {0} to {1}", url, path);
|
||||
Console.WriteLine("Status: Initializing");
|
||||
|
||||
if (args.Length != 2)
|
||||
wc.DownloadFileAsync(new Uri(url), path);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Error: invalid syntax");
|
||||
return;
|
||||
}
|
||||
string url = args[0];
|
||||
string path = args[1].Replace("~",Environment.GetFolderPath(Environment.SpecialFolder.Personal));
|
||||
|
||||
WebClient wc = new WebClient();
|
||||
wc.DownloadProgressChanged += DownloadProgressChanged;
|
||||
wc.DownloadFileCompleted += DownloadFileCompleted;
|
||||
|
||||
Console.WriteLine("Downloading {0} to {1}", url, path);
|
||||
Console.WriteLine("Status: Initializing");
|
||||
|
||||
wc.DownloadFileAsync(new Uri(url), path);
|
||||
while (!completed)
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
static bool completed = false;
|
||||
|
||||
static void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
|
||||
{
|
||||
if (e.Error != null)
|
||||
Console.WriteLine("Error: {0}", e.Error.Message);
|
||||
else
|
||||
Console.WriteLine(e.Result);
|
||||
completed = true;
|
||||
}
|
||||
|
||||
static void DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
|
||||
{
|
||||
if (e.Error != null)
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace OpenRA.Utility
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" -l,--list-mods List currently installed mods");
|
||||
Console.WriteLine(" -i=MODS,--mod-info=MODS List metadata for MODS (comma separated list of mods)");
|
||||
Console.WriteLine(" --download-url=URL,DEST Download a file from URL to DEST");
|
||||
Console.WriteLine(" --download-url=URL,DEST Download a file from URL to DEST (omit DEST to print to stdout)");
|
||||
Console.WriteLine(" --extract-zip=ZIPFILE,PATH Extract the zip ZIPFILE to DEST (relative to openra dir)");
|
||||
Console.WriteLine(" --install-ra-packages=PATH Install required packages for RA from CD to PATH");
|
||||
Console.WriteLine(" --install-cnc-packages=PATH Install required packages for C&C from CD to PATH");
|
||||
|
||||
@@ -123,15 +123,23 @@
|
||||
window.external.extractDownload("cnc-packages","packages","cnc");
|
||||
}
|
||||
|
||||
function versionCallback(version)
|
||||
{
|
||||
document.getElementById("latestversion").innerHTML = version;
|
||||
}
|
||||
|
||||
function motdCallback(motd)
|
||||
{
|
||||
document.getElementById("motd").innerHTML = motd;
|
||||
}
|
||||
|
||||
function onLoad()
|
||||
{
|
||||
refreshSections();
|
||||
var version = window.external.metadata("VERSION", "cnc");
|
||||
document.getElementById("installedversion").innerHTML = version;
|
||||
document.getElementById("latestversion").innerHTML = window.external.httpRequest("http://master.open-ra.org/VERSION");
|
||||
var motd = window.external.httpRequest("http://master.open-ra.org/motd.php?v="+version);
|
||||
if (motd != undefined)
|
||||
document.getElementById("motd").innerHTML = motd.substring(3);
|
||||
window.external.httpRequest("http://master.open-ra.org/VERSION", "versionCallback");
|
||||
window.external.httpRequest("http://master.open-ra.org/motd.php?v="+version, "motdCallback");
|
||||
}
|
||||
|
||||
function refreshSections()
|
||||
@@ -223,7 +231,7 @@
|
||||
|
||||
<div id="main">
|
||||
<div id="content">
|
||||
<p>Latest version: <span id="latestversion">Unknown</span></p>
|
||||
<p>Latest version: <span id="latestversion">Checking...</span></p>
|
||||
<p id="motd"></p>
|
||||
</div>
|
||||
<div id="buttons-install" class="buttons" style="display:none">
|
||||
|
||||
@@ -123,16 +123,23 @@
|
||||
window.external.extractDownload("ra-packages","packages","ra");
|
||||
}
|
||||
|
||||
function versionCallback(version)
|
||||
{
|
||||
document.getElementById("latestversion").innerHTML = version;
|
||||
}
|
||||
|
||||
function motdCallback(motd)
|
||||
{
|
||||
document.getElementById("motd").innerHTML = motd;
|
||||
}
|
||||
|
||||
function onLoad()
|
||||
{
|
||||
refreshSections();
|
||||
var version = window.external.metadata("VERSION", "ra");
|
||||
var version = window.external.metadata("VERSION", "cnc");
|
||||
document.getElementById("installedversion").innerHTML = version;
|
||||
document.getElementById("latestversion").innerHTML = window.external.httpRequest("http://master.open-ra.org/VERSION");
|
||||
var motd = window.external.httpRequest("http://master.open-ra.org/motd.php?v="+version);
|
||||
|
||||
if (motd != undefined)
|
||||
document.getElementById("motd").innerHTML = motd.substring(3);
|
||||
window.external.httpRequest("http://master.open-ra.org/VERSION", "versionCallback");
|
||||
window.external.httpRequest("http://master.open-ra.org/motd.php?v="+version, "motdCallback");
|
||||
}
|
||||
|
||||
function refreshSections()
|
||||
@@ -224,7 +231,7 @@
|
||||
|
||||
<div id="main">
|
||||
<div id="content">
|
||||
<p>Latest version: <span id="latestversion">Unknown</span></p>
|
||||
<p>Latest version: <span id="latestversion">Checking...</span></p>
|
||||
<p id="motd"></p>
|
||||
</div>
|
||||
<div id="buttons-install" class="buttons" style="display:none">
|
||||
|
||||
Reference in New Issue
Block a user