commit 72ee93e4873071bef5f986a1b53953710b1b872c Author: Sami Samhuri Date: Thu Apr 1 22:51:09 2010 -0700 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c027e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +TestHarness/Frameworks diff --git a/CPWebSocket.j b/CPWebSocket.j new file mode 100644 index 0000000..2894f40 --- /dev/null +++ b/CPWebSocket.j @@ -0,0 +1,81 @@ +// +// CPWebSocket.j +// +// Copyright 2010 Sami Samhuri +// +// MIT license +// + +@import + +// FIXME export these ... #define? +var CPWebSocketStateConnecting = 0, + CPWebSocketStateOpen = 1, + CPWebSocketStateClosing = 2, + CPWebSocketStateClosed = 3; + +@implementation CPWebSocket : CPObject +{ + JSObject _ws; + id delegate; +} + ++ (id) openWebSocketWithURL: (CPString)url_ delegate: (id) delegate_ +{ + return [[self alloc] initWithURL: url_ delegate: delegate_]; +} + +- (id) initWithURL: (CPString)url_ delegate: (id) delegate_ +{ + self = [super init]; + if (self) { + _ws = new WebSocket(url_); + delegate = delegate_; + [self _setupCallbacks]; + } + return self; +} + +- (void) _setupCallbacks +{ + _ws.onopen = function() { + [delegate webSocketDidOpen: self]; + }; + _ws.onclose = function(event) { + [delegate webSocketDidClose: self]; + }; + _ws.onmessage = function(event) { + [delegate webSocket: self didReceiveMessage: event.data]; + }; + _ws.onerror = function(event) { + [delegate webSocketDidReceiveError: self]; + }; +} + +- (CPString) URL +{ + return _ws.URL; +} + +- (CPNumber) state +{ + return _ws.state; +} + +- (CPNumber) bytesBuffered +{ + return _ws.bufferedAmount; +} + +- (void) close +{ + _ws.close(); +} + +- (BOOL) send: (CPString) data +{ + // TODO check the state, should not be CPWebSocketConnecting + return _ws.send(data); +} + +@end diff --git a/README.md b/README.md new file mode 100644 index 0000000..1caa17a --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +CPWebSocket +=========== + +A WebSocket implementation for Cappuccino. + +Test it out by running runserver.js from node.websocket[1] (with +Node[2]) and then browsing to TestHarness/index.html with a browser +that supports WebSockets (such as Google Chrome). + +[1] http://github.com/shazow/node.websocket.js +[2] http://github.com/ry/node + + +License +======= + +Copyright 2010 Sami Samhuri +MIT License diff --git a/TestHarness/AppController.j b/TestHarness/AppController.j new file mode 100644 index 0000000..d986ab4 --- /dev/null +++ b/TestHarness/AppController.j @@ -0,0 +1,101 @@ +/* + * AppController.j + * CPWebSocket TestHarness + * + * Created by Sami Samhuri on April 1, 2010. + * Copyright 2010, Sami Samhuri All rights reserved. + * + * MIT license + * + */ + +@import +@import "../CPWebSocket.j" + +CPLogRegister(CPLogConsole); + +@implementation AppController : CPObject +{ + CPMenu mainMenu; + CPLabel label; + CPWebSocket webSocket; +} + +- (void)applicationDidFinishLaunching:(CPNotification)aNotification +{ + var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask], + contentView = [theWindow contentView]; + + label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()]; + [label setFont:[CPFont boldSystemFontOfSize:24.0]]; + [label setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin | CPViewMinYMargin | CPViewMaxYMargin]; + + [contentView addSubview:label]; + [theWindow orderFront:self]; + + [self setLabelText:@"Hello WebSocket World!"]; + [self createMainMenu]; +} + +- (void) openWebSocket +{ + webSocket = [CPWebSocket openWebSocketWithURL: @"ws://localhost:8080" delegate: self]; +} + +- (void) webSocketDidOpen: (CPWebSocket)ws +{ + [self setLabelText: @">>> web socket open: " + [ws URL]]; +} + +- (void) webSocket: (CPWebSocket)ws didReceiveMessage: (CPString)message +{ + [self setLabelText: @">>> web socket received: " + message]; +} + +- (void) webSocketDidClose: (CPWebSocket)ws +{ + [self setLabelText: @">>> web socket closed"]; +} + +- (void) webSocketDidReceiveError: (CPWebSocket)ws +{ + [self setLabelText: @">>> web socket error, state: " + [ws state]]; +} + +- (void) sendMessage +{ + [webSocket send: @"ping"]; +} + +- (void) closeWebSocket +{ + [webSocket close]; +} + +- (void) createMainMenu +{ + mainMenu = [[CPMenu alloc] initWithTitle:@"TestHarness"]; + var topMenuItem = [mainMenu addItemWithTitle:"CPWebSocket Tests" action:nil keyEquivalent:nil]; + var menu = [[CPMenu alloc] init]; + [menu addItemWithTitle: @"Open WebSocket" + action: @selector(openWebSocket) + keyEquivalent: "1"]; + [menu addItemWithTitle: @"Send Message" + action: @selector(sendMessage) + keyEquivalent: "2"]; + [menu addItemWithTitle: @"Close WebSocket" + action: @selector(closeWebSocket) + keyEquivalent: "5"]; + [mainMenu setSubmenu:menu forItem:topMenuItem]; + [[CPApplication sharedApplication] setMainMenu:mainMenu]; + [CPMenu setMenuBarVisible:YES]; +} + +- (void) setLabelText: (CPString) text +{ + [label setStringValue: text]; + [label sizeToFit]; + [label setCenter:[contentView center]]; +} + +@end diff --git a/TestHarness/Info.plist b/TestHarness/Info.plist new file mode 100644 index 0000000..adc3d83 --- /dev/null +++ b/TestHarness/Info.plist @@ -0,0 +1,12 @@ + + + + + CPApplicationDelegateClass + AppController + CPBundleName + TestHarness + CPPrincipalClass + CPApplication + + diff --git a/TestHarness/Jakefile b/TestHarness/Jakefile new file mode 100644 index 0000000..f4fa6e2 --- /dev/null +++ b/TestHarness/Jakefile @@ -0,0 +1,81 @@ +/* + * Jakefile + * TestHarness + * + * Created by You on April 1, 2010. + * Copyright 2010, Your Company All rights reserved. + */ + +var ENV = require("system").env, + FILE = require("file"), + JAKE = require("jake"), + task = JAKE.task, + FileList = JAKE.FileList, + app = require("cappuccino/jake").app, + configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug", + OS = require("os"); + +app ("TestHarness", function(task) +{ + task.setBuildIntermediatesPath(FILE.join("Build", "TestHarness.build", configuration)); + task.setBuildPath(FILE.join("Build", configuration)); + + task.setProductName("TestHarness"); + task.setIdentifier("com.yourcompany.TestHarness"); + task.setVersion("1.0"); + task.setAuthor("Your Company"); + task.setEmail("feedback @nospam@ yourcompany.com"); + task.setSummary("TestHarness"); + task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**"))); + task.setResources(new FileList("Resources/*")); + task.setIndexFilePath("index.html"); + task.setInfoPlistPath("Info.plist"); + + if (configuration === "Debug") + task.setCompilerFlags("-DDEBUG -g"); + else + task.setCompilerFlags("-O"); +}); + +function printResults(configuration) +{ + print("----------------------------") + print(configuration+" app built at path: "+FILE.join("Build", configuration, "TestHarness")); + print("----------------------------") +} + +task ("default", ["TestHarness"], function() +{ + printResults(configuration); +}); + +task ("build", ["default"]); + +task ("debug", function() +{ + ENV["CONFIGURATION"] = "Debug"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("release", function() +{ + ENV["CONFIGURATION"] = "Release"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("run", ["debug"], function() +{ + OS.system(["open", FILE.join("Build", "Debug", "TestHarness", "index.html")]); +}); + +task ("run-release", ["release"], function() +{ + OS.system(["open", FILE.join("Build", "Release", "TestHarness", "index.html")]); +}); + +task ("deploy", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Deployment", "TestHarness")); + OS.system(["press", "-f", FILE.join("Build", "Release", "TestHarness"), FILE.join("Build", "Deployment", "TestHarness")]); + printResults("Deployment") +}); diff --git a/TestHarness/Resources/spinner.gif b/TestHarness/Resources/spinner.gif new file mode 100644 index 0000000..06dbc2b Binary files /dev/null and b/TestHarness/Resources/spinner.gif differ diff --git a/TestHarness/index-debug.html b/TestHarness/index-debug.html new file mode 100644 index 0000000..9a14efd --- /dev/null +++ b/TestHarness/index-debug.html @@ -0,0 +1,86 @@ + + + + + + + + TestHarness + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + diff --git a/TestHarness/index.html b/TestHarness/index.html new file mode 100644 index 0000000..1fa9331 --- /dev/null +++ b/TestHarness/index.html @@ -0,0 +1,71 @@ + + + + + + + + TestHarness + + + + + + + + + + + + +
+
+ + + +
+
+ + + + diff --git a/TestHarness/main.j b/TestHarness/main.j new file mode 100644 index 0000000..baa6626 --- /dev/null +++ b/TestHarness/main.j @@ -0,0 +1,18 @@ +/* + * AppController.j + * TestHarness + * + * Created by You on April 1, 2010. + * Copyright 2010, Your Company All rights reserved. + */ + +@import +@import + +@import "AppController.j" + + +function main(args, namedArgs) +{ + CPApplicationMain(args, namedArgs); +}