diff --git a/image/private/js-impl.js b/image/private/js-impl.js index d06d1b6..f0499fb 100644 --- a/image/private/js-impl.js +++ b/image/private/js-impl.js @@ -305,8 +305,8 @@ EXPORTS['bitmap/url'] = MACHINE, new Error(plt.baselib.format.format( "unable to load ~a: ~a", - url, - e.message))); + [url, + e.message]))); }); } rawImage.src = url.toString(); diff --git a/resource/compile-time.rkt b/resource/compile-time.rkt index 04fa17c..24151a9 100644 --- a/resource/compile-time.rkt +++ b/resource/compile-time.rkt @@ -2,6 +2,7 @@ ;; Macros for recording the definition of resources in a program. (require (for-syntax racket/base racket/path + racket/port syntax/parse "munge-path.rkt" "record.rkt")) @@ -16,7 +17,7 @@ (define-syntax (define-resource stx) (syntax-parse stx [(_ name:id) - (with-syntax ([path (symbol->string #'name)]) + (with-syntax ([path (symbol->string (syntax-e #'name))]) (syntax/loc stx (define-resource name path)))] [(_ name:id path:str) @@ -25,9 +26,12 @@ (or (current-load-relative-directory) (current-directory)) (syntax-e #'path)))] - [munged-path (munge-path normal-path)]) + [munged-path (munge-path normal-path)] + [content (call-with-input-file normal-path port->bytes)]) + (printf "Read ~s\n" content) (with-syntax ([normal-path normal-path] - [munged-path munged-path]) + [munged-path munged-path] + [content content]) (syntax/loc stx (begin @@ -40,4 +44,4 @@ (record-resource resolved-module-path normal-path munged-path))) ;; Run time code - (define name (resource normal-path munged-path))))))])) + (define name (resource normal-path munged-path content))))))])) diff --git a/resource/record.rkt b/resource/record.rkt index 95c4856..0c817f5 100644 --- a/resource/record.rkt +++ b/resource/record.rkt @@ -6,7 +6,7 @@ ;; Needs to be prefabricated -(struct resource (path key) #:prefab) +(struct resource (path key content) #:prefab) (define records (make-hash)) @@ -18,5 +18,6 @@ ;; record-javascript-implementation!: path path a-resource-path -> void (define (record-resource a-module-path a-resource-path a-key) (hash-set! records a-module-path - (cons (resource a-resource-path a-key) + (cons (resource a-resource-path a-key (call-with-input-file a-resource-path + port->bytes)) (hash-ref records a-module-path '())))) diff --git a/resource/structs.rkt b/resource/structs.rkt index a536140..856c936 100644 --- a/resource/structs.rkt +++ b/resource/structs.rkt @@ -3,4 +3,4 @@ (provide (all-defined-out)) ;; Needs to be prefabricated -(struct resource (path key) #:prefab) +(struct resource (path key content) #:prefab) diff --git a/web-world/examples/hello/hello.rkt b/web-world/examples/hello/hello.rkt index efb3c88..062d9a6 100644 --- a/web-world/examples/hello/hello.rkt +++ b/web-world/examples/hello/hello.rkt @@ -1,8 +1,19 @@ #lang planet dyoo/whalesong (require (planet dyoo/whalesong/web-world) - (planet dyoo/whalesong/resource)) + (planet dyoo/whalesong/resource) + (planet dyoo/whalesong/resource/structs)) -(define-resource index.html "index.html") +(define-resource index.html) -(big-bang "don't care" - (initial-view index.html)) + +(printf "I see the path is: ~s\n" + (resource-path index.html)) + +(printf "I see the key is: ~s\n" + (resource-key index.html)) + +(printf "I see the content is: ~s\n" + (resource-content index.html)) + +;; (big-bang "don't care" +;; (initial-view index.html)) diff --git a/web-world/impl.rkt b/web-world/impl.rkt index 65aeb30..ca85f20 100644 --- a/web-world/impl.rkt +++ b/web-world/impl.rkt @@ -1,5 +1,10 @@ #lang s-exp "../lang/js/js.rkt" + +;; Make sure the resource library is loaded. +(require "../resource.rkt") + + (declare-implementation #:racket "racket-impl.rkt" #:javascript ("js-impl.js") diff --git a/web-world/js-impl.js b/web-world/js-impl.js index 4f90f9a..540128c 100644 --- a/web-world/js-impl.js +++ b/web-world/js-impl.js @@ -5,6 +5,100 @@ var PAUSE = plt.runtime.PAUSE; +var resourceStructType = + MACHINE.modules['whalesong/resource/structs.rkt'].namespace['struct:resource']; + + + +// A View represents a functional representation of the DOM tree. +var View = function(top, focused, eventHandlers, pendingActions) { + // top: dom node + this.top = top; + this.focused = focused; + this.eventHandlers = eventHandlers; + this.pendingActions = pendingActions; +}; + +View.prototype.updateFocused = function(focused) { + return new View(this.top, focused, eventHandlers, pendingActions); +}; + + +var isView = plt.baselib.makeClassPredicate(View); +var isResource = resourceStructType.predicate; + + +var resourcePath = function(r) { return resourceStructType.accessor(r, 0); }; +var resourceKey = function(r) { return resourceStructType.accessor(r, 1); }; +var resourceContent = function(r) { return resourceStructType.accessor(r, 2); }; + + +var checkResource = plt.baselib.check.makeCheckArgumentType( + isResource, 'resource'); +var checkResourceOrView = plt.baselib.check.makeCheckArgumentType( + function(x) { return isView(x) || isResource(x); }, + 'resource or view'); +var checkView = plt.baselib.check.makeCheckArgumentType( + isView, 'view'); + + + +// coerseToView: (U resource View) -> View +var coerseToView = function(x, onSuccess, onFail) { + if (isView(x)) { + return onSuccess(x); + } else if (isResource(x)) { + console.log(resourcePath(x), resourceKey(x), resourceContent(x).toString()); + $.ajax({ + url: "res/" + resourceKey(x), + dataType : "html", + success: function(data, textStatus, jqXHR) { + console.log("data is: ", data); + return onSuccess(new View(data, [], [], [])); + }, + error: function(jqXHR, textStatus, errorThrown) { + return onFail(new Error(errorThrown)); + }}); + } else { + return onFail(new Error("Unable to coerse to view")); + } +}; + + + + +var WorldHandler = function(args) { + this.args = args; +}; + + +var InitialViewHandler = function(args, view) { + WorldHandler.call(this, args); + // view: View + this.view = view; +}; + +InitialViewHandler.prototype = plt.baselib.heir(WorldHandler.prototype); + + + +var StopWhenHandler = function(args, stopWhen) { + WorldHandler.call(this, args); + // stopWhen: Racket procedure (World -> boolean) + this.stopWhen = stopWhen; +}; + +StopWhenHandler.prototype = plt.baselib.heir(WorldHandler.prototype); + + + + + + + +////////////////////////////////////////////////////////////////////// + + EXPORTS['big-bang'] = makeClosure( 'big-bang', plt.baselib.arity.makeArityAtLeast(1), @@ -13,31 +107,68 @@ EXPORTS['big-bang'] = makeClosure( PAUSE(function(restart) { + // FILL ME IN - - - restart(function(MACHINE) { - MACHINE.argcount = oldArgcount; - finalizeClosureCall(MACHINE, "ok"); - })}); + var onRestart = function() { + restart(function(MACHINE) { + MACHINE.argcount = oldArgcount; + finalizeClosureCall(MACHINE, "ok"); + }); + }; + }); }); - -EXPORTS['initial-view'] = makePrimitiveProcedure( +EXPORTS['initial-view'] = makeClosure( 'initial-view', 1, function(MACHINE) { - return undefined; + var resourceOrView = checkResourceOrView(MACHINE, 'initial-view', 0);; + var oldArgcount = MACHINE.argcount; + PAUSE(function(restart) { + coerseToView(resourceOrView, + function(v) { + restart(function(MACHINE) { + finalizeClosureCall(MACHINE, + new InitialViewHandler( + { onStart : function(MACHINE, k) {k()}, + onPause : function(MACHINE, k) {k()}, + onResume : function(MACHINE, k) {k()}, + onStop : function(MACHINE, k) {k()} + }, + v)); + }); + }, + function(exn) { + plt.baselib.exceptions.raise( + MACHINE, + new Error(plt.baselib.format.format( + "unable to translate resource to view: ~a", + [exn.message]))); + }); + }); }); + EXPORTS['stop-when'] = makePrimitiveProcedure( 'stop-when', 1, function(MACHINE) { + var stopWhen = checkProcedure(MACHINE, 'stop-when', 0); + return new StopWhenHandler( + { onStart : function(MACHINE, k) {k()}, + onPause : function(MACHINE, k) {k()}, + onResume : function(MACHINE, k) {k()}, + onStop : function(MACHINE, k) {k()} + }, + stopWhen + ); return undefined; }); + + + //////////////////////////////////////////////////////////////////////