where-ami-

This commit is contained in:
Danny Yoo 2011-08-29 11:28:51 -04:00
parent 9bc49e7262
commit d4ff2ecaa7
6 changed files with 202 additions and 3 deletions

View File

@ -79,6 +79,10 @@ functions. One difference introduced by the web is the web page
itself: because the page itself is a source of state, it too will be
passed to callbacks.
The world-updating callbacks may optionally take an @tech{event} object, which
provides additional information about the event that triggered the callback.
This library presents a functional version of the DOM in the form of a
@emph{view}.
@ -92,9 +96,30 @@ Provide an initial view for the big-bang.}
@defproc[(stop-when [stop? ([w world] [dom view] -> boolean)]) big-bang-handler]{
Tells @racket[big-bang] the predicate for termination.
}
@defproc[(on-tick [tick-f ([w world] [v view] -> world)]) big-bang-handler]{
@defproc[(on-tick [tick-f ([w world] [v view] [e event]? -> world)]) big-bang-handler]{
Tells @racket[big-bang] to update the world during clock ticks.
}
@defproc[(on-mock-location-change [location-f ([w world] [v view] [e event]? -> world)]) big-bang-handler]{
Tells @racket[big-bang] to update the world during simulated movement.
During the extent of a big-bang, a form widget will appear in the
@tt{document.body} to allow you to manually send location-changing
events.
}
@defproc[(on-location-change [location-f ([w world] [v view] [e event]? -> world)]) big-bang-handler]{
Tells @racket[big-bang] to update when the location changes, as
received by the
@link["http://dev.w3.org/geo/api/spec-source.html"]{Geolocation API}.
}
@defproc[(to-draw [draw-f ([w world] [v view] -> view)]) big-bang-handler]{
Tells @racket[big-bang] how to update the rendering of the world.
}
@ -133,7 +158,7 @@ Get the textual content at the focus.
@defproc[(update-view-text [v view] [s string]) view]{
Update the textual content at the focus.}
@defproc[(view-bind [v view] [type string] [world-updater ([w world] [v view] -> world)]) view]{
@defproc[(view-bind [v view] [type string] [world-updater ([w world] [v view] [e event]? -> world)]) view]{
Attach a world-updating event to the focus.
Common event types include @racket["click"], @racket["trigger"],
@ -169,6 +194,9 @@ Add the dom node @racket[d] as the last child of the focused node.}
@subsection{Events}
An @deftech{event} is a collection of name-value pairs.

View File

@ -20,6 +20,12 @@
;; clock tick handler
on-tick
;; location changes
on-mock-location-change
;; location changes (for real!)
on-location-change
;; draw and update the view
to-draw

View File

@ -657,6 +657,91 @@
};
var MockLocationEventSource = function() {
this.elt = undefined;
};
MockLocationEventSource.prototype = plt.baselib.heir(EventSource.prototype);
MockLocationEventSource.prototype.onStart = function(fireEvent) {
var mockLocationSetter = document.createElement("div");
var latInput = document.createElement("input");
latInput.type = "text";
var latOutput = document.createElement("input");
latOutput.type = "text";
var submitButton = document.createElement("input");
submitButton.type = "button";
submitButton.value = "send lat/lng";
submitButton.onclick = function() {
fireEvent(undefined,
{ latitude : plt.baselib.numbers.makeFloat(latInput.value),
longitude : plt.baselib.numbers.makeFloat(latOutput.value) });
return false;
};
mockLocationSetter.style.border = "1pt solid black";
mockLocationSetter.appendChild(
document.createTextNode("mock location setter"));
mockLocationSetter.appendChild(latInput);
mockLocationSetter.appendChild(latOutput);
mockLocationSetter.appendChild(submitButton);
document.body.appendChild(mockLocationSetter);
this.elt = mockLocationSetter;
};
MockLocationEventSource.prototype.onStop = function() {
if (this.elt !== undefined) {
document.body.removeChild(mockLocationSetter);
this.elt = undefined;
};
};
// This version really does use the geolocation object.
var LocationEventSource = function() {
this.id = undefined;
};
LocationEventSource.prototype = plt.baselib.heir(EventSource.prototype);
LocationEventSource.prototype.onStart = function(fireEvent) {
var success = function(position) {
fireEvent(undefined,
{ latitude : plt.baselib.numbers.makeFloat(position.coords.latitude),
longitude: plt.baselib.numbers.makeFloat(position.coords.longitude) };
};
var fail = function(err) {
// Quiet failure
}
if (!!navigator.geolocation) {
this.id = navigator.geolocation.watchPosition(success, fail);
}
};
LocationEventSource.prototype.onStop = function() {
if (this.id !== undefined) {
navigator.geolocation.clearWatch(this.id);
this.id = undefined;
};
};
// DomElementSource: string (U DOM string) -> EventSource
// A DomEventSource allows DOM elements to send events over to
// web-world.
@ -1273,5 +1358,28 @@
EXPORTS['on-location-change'] = makePrimitiveProcedure(
'on-location-change',
1,
function(MACHINE) {
var onChange = wrapFunction(checkProcedure(MACHINE, 'on-location-change', 0));
return new EventHandler('on-location-change',
new LocationEventSource(),
onChange);
});
EXPORTS['on-mock-location-change'] = makePrimitiveProcedure(
'on-mock-location-change',
1,
function(MACHINE) {
var onChange = wrapFunction(checkProcedure(MACHINE, 'on-mock-location-change', 0));
return new EventHandler('on-mock-location-change',
new MockLocationEventSource(),
onChange);
});
//////////////////////////////////////////////////////////////////////
}());

View File

@ -1,6 +1,10 @@
#lang racket/base
(provide big-bang initial-view stop-when on-tick to-draw
(provide big-bang initial-view stop-when
on-tick
on-location-change on-mock-location-change
to-draw
->view
view-focus
view-left view-right view-up view-down
@ -33,6 +37,22 @@
[(f delay)
(error 'on-tick "Please run in JavaScript context.")]))
(define on-location-change
(case-lambda [(f)
(error 'on-location-change "Please run in JavaScript context.")]
[(f delay)
(error 'on-location-change "Please run in JavaScript context.")]))
(define on-mock-location-change
(case-lambda [(f)
(error 'on-mock-location-change "Please run in JavaScript context.")]
[(f delay)
(error 'on-mock-location-change "Please run in JavaScript context.")]))
(define (to-draw w)
(error 'to-draw "Please run in JavaScript context."))

View File

@ -0,0 +1,9 @@
<html>
<head><title>Where in the world am I?</title></head>
<body>
<p>
I am at: <span id="real-location"/>.
The mock location says: <span id="mock-location"/>.
</p>
</body>
</html>

View File

@ -0,0 +1,28 @@
#lang planet dyoo/whalesong
(require (planet dyoo/whalesong/web-world)
(planet dyoo/whalesong/resource))
(define-resource index.html)
(define-struct coord (lat lng))
(define-struct world (real mock))
(define (location-change world dom evt)
world)
(define (mock-location-change world dom evt)
world)
(define (draw world dom)
dom)
(big-bang (make-world 'unknown 'unknown)
(initial-view index.html)
(to-draw draw)
(on-location-change location-change)
(on-mock-location-change mock-location-change))