From 51accf643dcf1b2d9999e351a68b1912ce08fb14 Mon Sep 17 00:00:00 2001 From: evancz Date: Wed, 30 Jan 2013 19:47:29 -0800 Subject: [PATCH] Change name of `WebSocket.send` to `WebSocket.open`. Begin adding documentation to raw JS files. --- core-js/Signal/HTTP.js | 49 +++++++++++++++++++++++++++++++----- core-js/Signal/Time.js | 50 +++++++++++++++++++++++++++++++------ core-js/Signal/Touch.js | 20 +++++++++++++++ core-js/Signal/WebSocket.js | 16 ++++++------ core-js/Signal/Window.js | 16 ++++++++++++ 5 files changed, 130 insertions(+), 21 deletions(-) diff --git a/core-js/Signal/HTTP.js b/core-js/Signal/HTTP.js index 1175156..8685142 100644 --- a/core-js/Signal/HTTP.js +++ b/core-js/Signal/HTTP.js @@ -1,6 +1,31 @@ + +/*! HTTP +A library for asynchronous HTTP requests (AJAX). See the +[WebSocket](http://elm-lang.org/docs/WebSocket.elm) library if +you have very strict latency requirements. +!*/ + Elm.HTTP = function() { var JS = Elm.JavaScript; var toElmString = Elm.JavaScript.castJSStringToString; + + /*[Creating Requests]*/ + + /** get :: String -> Request String + Create a GET request to the given url. + **/ + function get(url) { return request("GET")(url)(null)(["Nil"]); } + + /** post :: String -> String -> Request String + Create a POST request to the given url, carrying the given data. + **/ + function post(url) { return function(data) { + return request("POST")(url)(data)(["Nil"]); }; } + + /** request :: String -> String -> String -> [(String,String)] -> Request String + Create a customized request. Arguments are request type (get, post, put, + delete, etc.), target url, data, and a list of additional headers. + **/ function request(verb) { return function(url) { return function(data) { return function(headers) { return {0 : "Request", @@ -10,12 +35,6 @@ Elm.HTTP = function() { data : data === null ? null : JS.castStringToJSString(data), headers : headers }; }; }; }; } - /** get :: String -> Request String - Create a GET request to the given url. - **/ - function get(url) { return request("GET")(url)(null)(["Nil"]); } - function post(url) { return function(data) { - return request("POST")(url)(data)(["Nil"]); }; } function registerReq(queue,responses) { return function(req) { if (req.url !== "") { sendReq(queue,responses,req); } @@ -58,6 +77,19 @@ Elm.HTTP = function() { return null; } + /*[Responses]*/ + + /** data Response a = Waiting | Success a | Failure Int String + The datatype for responses. Success contains only the returned message. + Failures contain both an error code and an error message. + **/ + + /*[Sending Requests]*/ + + /** send :: Signal (Request a) -> Signal (Response String) + Performs an HTTP request with the given requests. Produces a signal + that carries the responses. + **/ function send(requests) { var responses = Elm.Signal.constant(["Waiting"]); var sender = Elm.Signal.lift(registerReq([],responses))(requests); @@ -65,6 +97,11 @@ Elm.HTTP = function() { return Elm.Signal.lift2(f)(responses)(sender); } + /** sendGet :: Signal String -> Signal (Response String) + Performs an HTTP GET request with the given urls. Produces a signal + that carries the responses. + **/ + return {get : get, post : post, request : request, diff --git a/core-js/Signal/Time.js b/core-js/Signal/Time.js index c0c4d05..759ee59 100644 --- a/core-js/Signal/Time.js +++ b/core-js/Signal/Time.js @@ -1,12 +1,35 @@ +/*! Time +Library for working with time. Type `Time` represents some number of +milliseconds. +!*/ + Elm.Time = function() { + + /*[Times]*/ + + /** hour, minute, second, ms :: Time + Units of time, making it easier to specify things like a + half-second `(second / 2)`. + **/ + function timeNow() { return (new window.Date).getTime(); } - function everyWhen(isOn) { return function(t) { - var clock = Elm.Signal.constant(timeNow()); - function tellTime() { Dispatcher.notify(clock.id, timeNow()); } - setInterval(tellTime, t); - return clock; - }; - } + + /*[Tickers]*/ + + /** fps :: Number -> Signal Time + Takes desired number of frames per second (fps). The resulting signal + gives a sequence of time deltas as quickly as possible until it reaches + the desired FPS. A time delta is the time between the last frame and the + current frame. + **/ + + /** fpsWhen :: Number -> Signal Bool -> Signal Time + Same as the fps function, but you can turn it on and off. Allows you + to do brief animations based on user input without major ineffeciencies. + The first time delta after a pause is always zero, no matter how long + the pause was. This way summing the deltas will actually give the amount + of time that the output signal has been running. + **/ function fpsWhen(desiredFPS) { return function (isOn) { var msPerFrame = 1000 / desiredFPS; var prev = timeNow(), curr = prev, diff = 0, wasOn = true; @@ -32,6 +55,19 @@ Elm.Time = function() { return Elm.Signal.lift2(f)(isOn)(ticker); }; } + + /** every :: Time -> Signal Time + Takes a time interval t. The resulting signal is the current time, + updated every t. + **/ + function everyWhen(isOn) { return function(t) { + var clock = Elm.Signal.constant(timeNow()); + function tellTime() { Dispatcher.notify(clock.id, timeNow()); } + setInterval(tellTime, t); + return clock; + }; + } + function since(t) { return function(s) { function cmp(a) { return function(b) { return !Value.eq(a,b); }; } var dcount = Elm.Signal.count(Elm.Signal.delay(t)(s)); diff --git a/core-js/Signal/Touch.js b/core-js/Signal/Touch.js index de8ead8..10e9aa8 100644 --- a/core-js/Signal/Touch.js +++ b/core-js/Signal/Touch.js @@ -1,3 +1,7 @@ +/*! Touch +This is an early version of the touch library. It will likely grow to +include gestures that would be useful for both games and web-pages. +!*/ Elm.Touch = function() { @@ -73,9 +77,25 @@ Elm.Touch = function() { return sig; } + /*[Touches]*/ + + /** touches :: Signal [{ x :: Int, y :: Int, id :: Int, x0 :: Int, y0 :: Int, t0 :: Time }] + A list of touches. Each ongoing touch is represented by a set of + coordinates and an identifier id that allows you to distinguish + between different touches. Each touch also contains the coordinates and + time of the initial contact (x0, y0, and t0) which helps compute more + complicated gestures. + **/ var touches = dependency(function(ts) { return Elm.JavaScript.castJSArrayToList(ts); }); + + /*[Gestures]*/ + + /** taps :: Signal { x :: Int, y :: Int } + The last position that was tapped. Default value is `{x=0,y=0}`. + Updates whenever the user taps the screen. + **/ var taps = function() { var sig = dependency(function(_) { return tap; }); sig.defaultNumberOfKids = 1; diff --git a/core-js/Signal/WebSocket.js b/core-js/Signal/WebSocket.js index 1127977..26e7fa3 100644 --- a/core-js/Signal/WebSocket.js +++ b/core-js/Signal/WebSocket.js @@ -1,36 +1,36 @@ Elm.WebSocket = function() { var JS = Elm.JavaScript; - /** send :: String -> Signal String -> Signal String + /** open :: String -> Signal String -> Signal String Create a web-socket. The first argument is the URL of the desired web-socket server. The input signal holds the outgoing messages, and the resulting signal contains the incoming ones. **/ - function send(url) { return function(outgoing) { + function open(url) { return function(outgoing) { var incoming = Elm.Signal.constant(["Nil"]); var ws = new window.WebSocket(JS.castStringToJSString(url)); var pending = []; - var open = false; + var ready = false; ws.onopen = function(e) { var len = pending.length; for (var i = 0; i < len; ++i) { ws.send(pending[i]); } - open = true; + ready = true; }; ws.onmessage = function(event) { Dispatcher.notify(incoming.id, JS.castJSStringToString(event.data)); }; - function sendMsg(msg) { + function send(msg) { var s = JS.castStringToJSString(msg); - open ? ws.send(s) : pending.push(s); + ready ? ws.send(s) : pending.push(s); } function take1(x) { return function(y) { return x; } } - return Elm.Signal.lift2(take1)(incoming)(Elm.Signal.lift(sendMsg)(outgoing)); + return Elm.Signal.lift2(take1)(incoming)(Elm.Signal.lift(send)(outgoing)); }; } - return {send:send}; + return {open:open}; }(); diff --git a/core-js/Signal/Window.js b/core-js/Signal/Window.js index c404cca..b592fd6 100644 --- a/core-js/Signal/Window.js +++ b/core-js/Signal/Window.js @@ -1,10 +1,26 @@ +/*! Window !*/ + Elm.Window = function() { + + /*[Dimensions]*/ + + /** dimensions :: Signal (Int,Int) + The current dimensions of the window (i.e. the area viewable to the + user, not including scroll bars). + **/ var dimensions = Elm.Signal.constant(Value.Tuple(window.innerWidth, window.innerHeight)); dimensions.defaultNumberOfKids = 2; + /** width :: Signal Int + The current width of the window. + **/ var width = Elm.Signal.lift(function(p){return p[1];})(dimensions); width.defaultNumberOfKids = 0; + + /** height :: Signal Int + The current height of the window. + **/ var height = Elm.Signal.lift(function(p){return p[2];})(dimensions); height.defaultNumberOfKids = 0;