full support for Canvas, multiple Worlds

svn: r2712
This commit is contained in:
Matthias Felleisen 2006-04-19 03:23:59 +00:00
parent f0fe9a4d47
commit 3616a2a0a8
5 changed files with 164 additions and 208 deletions

View File

@ -1,13 +1,14 @@
#cs #cs
(module Canvas-native-methods mzscheme (module Canvas-native-methods mzscheme
(require (lib "draw.ss" "htdp") (require (lib "big-draw.ss" "htdp")
(lib "posn.ss" "lang") (lib "posn.ss" "lang")
(lib "class.ss") (lib "class.ss")
(lib "String.ss" "profj" "libs" "java" "lang") (lib "String.ss" "profj" "libs" "java" "lang")
(lib "Throwable.ss" "profj" "libs" "java" "lang") (lib "Throwable.ss" "profj" "libs" "java" "lang")
(lib "RuntimeException.ss" "profj" "libs" "java" "lang")) (lib "RuntimeException.ss" "profj" "libs" "java" "lang"))
;(require "Posn.ss")
(define void-or-true (void))
;raises a Java exception with the specified error message ;raises a Java exception with the specified error message
;raise-error: String -> void ;raise-error: String -> void
(define (raise-error message) (define (raise-error message)
@ -19,17 +20,17 @@
(define-syntax (wrap-start-check stx) (define-syntax (wrap-start-check stx)
(syntax-case stx () (syntax-case stx ()
[(_ body) [(_ body ...)
#'(with-handlers #'(with-handlers
((exn:fail? ((exn:fail?
(lambda (e) (lambda (e)
(raise-error (raise-error
(format "The method start(int,int) must be called on the canvas before using any drawing methods"))))) (format "The method show() must be called on the canvas before using any drawing methods [~s]" (exn-message e))))))
body)])) (begin (begin body ...) void-or-true))]))
(define-syntax (define/provide stx) (define-syntax (define/provide stx)
(syntax-case stx () (syntax-case stx ()
[(_ id val) #;[(_ id val)
(identifier? #'id) (identifier? #'id)
#'(begin #'(begin
(define id val) (define id val)
@ -42,17 +43,14 @@
(define Posn-x-get (dynamic-require '(lib "Posn.ss" "htdch" "idraw") 'Posn-x-get)) (define Posn-x-get (dynamic-require '(lib "Posn.ss" "htdch" "idraw") 'Posn-x-get))
(define Posn-y-get (dynamic-require '(lib "Posn.ss" "htdch" "idraw") 'Posn-y-get)) (define Posn-y-get (dynamic-require '(lib "Posn.ss" "htdch" "idraw") 'Posn-y-get))
(define (build-posn posnO) (define (build-posn posnO) (make-posn (Posn-x-get posnO) (Posn-y-get posnO)))
(make-posn (Posn-x-get posnO) (Posn-y-get posnO))) (define (color->symbol colorO) (string->symbol (to-lower-case (send colorO my-name))))
(define (color->symbol colorO)
(string->symbol (to-lower-case (send colorO my-name))))
;Raises an error if value less than or equal to 0 ;Raises an error if value less than or equal to 0
;check-arg: num string string -> boolean ;check-arg: num string string -> boolean
(define (check-arg value method argument) (define (check-arg value method argument)
(or (> value 0) (or (> value 0)
(raise-error (format "Method ~a expects an int greater than 0 for ~a argument, given ~a" (raise-error (format "Method ~a expects an int >= 0 for ~a argument, given ~a" method argument value))))
method argument value))))
(define (to-lower-case s) (define (to-lower-case s)
(letrec ((lower (letrec ((lower
@ -63,67 +61,69 @@
(lower (cdr s)))))))) (lower (cdr s))))))))
(list->string (lower (string->list s))))) (list->string (lower (string->list s)))))
(define/provide (start-int-int-native this accs gets privates x y) (define/provide (show-native this accs gets privates)
(and (check-arg x "start(int,int)" "first") ;; Kathy: it looks like I am working around a bug here.
(check-arg x "start(int,int)" "second") ;; I really wanted to write ([hash-table-get privates 'width] this)
(start x y) ;; but that didn't work at all. 'width is not a key for privates,
(void))) ;; even though it is a private field. Then I wanted to write
;; ([hash-table-get privates 'width] this), just like in World-native-methods.
;; That failed, too, with an arity error.
(define x (with-method ([g (this Canvas-width-get)]) (g '___)))
(define y (with-method ([g (this Canvas-height-get)]) (g '___)))
(start-and-export x y privates)
void-or-true)
(define/provide (stop-native this accs gets privates) (stop) (void)) (define/provide (close-native this accs gets privates)
(wrap-start-check ([hash-table-get privates '%stop])))
(define/provide (stop-native this accs gets privates)
(wrap-start-check ([hash-table-get privates '%end-of-time])))
(define/provide (copy-native this accs gets privates)
(wrap-start-check ([hash-table-get privates 'copy])))
(define/provide (drawCircle-idraw.Posn-int-idraw.Color-native this accs gets privates posn r c) (define/provide (drawCircle-idraw.Posn-int-idraw.Color-native this accs gets privates posn r c)
(wrap-start-check (wrap-start-check
(and (check-arg r "drawCircle(Posn, int, Color)" "second") (check-arg r "drawCircle(Posn, int, Color)" "second")
(draw-circle (build-posn posn) r (color->symbol c)) ([hash-table-get privates '%draw-circle] (build-posn posn) r (color->symbol c))))
(void))))
(define/provide (drawDisk-idraw.Posn-int-idraw.Color-native this accs gets privates posn r c) (define/provide (drawDisk-idraw.Posn-int-idraw.Color-native this accs gets privates posn r c)
(wrap-start-check (wrap-start-check
(and (check-arg r "drawDisk(Posn, int, Color)" "second") (check-arg r "drawDisk(Posn, int, Color)" "second")
(draw-solid-disk (build-posn posn) r (color->symbol c)) ([hash-table-get privates '%draw-solid-disk] (build-posn posn) r (color->symbol c))))
(void))))
(define/provide (drawRect-idraw.Posn-int-int-idraw.Color-native this accs gets privates posn w h c) (define/provide (drawRect-idraw.Posn-int-int-idraw.Color-native this accs gets privates posn w h c)
(wrap-start-check (wrap-start-check
(and (check-arg w "drawRect(Posn, int, int, Color)" "second") (check-arg w "drawRect(Posn, int, int, Color)" "second")
(check-arg h "drawRect(Posn, int, int, Color)" "third") (check-arg h "drawRect(Posn, int, int, Color)" "third")
(draw-solid-rect (build-posn posn) w h (color->symbol c)) ([hash-table-get privates '%draw-solid-rect] (build-posn posn) w h (color->symbol c))))
(void))))
(define/provide (drawLine-idraw.Posn-idraw.Posn-idraw.Color-native this accs gets privates p0 p1 c) (define/provide (drawLine-idraw.Posn-idraw.Posn-idraw.Color-native this accs gets privates p0 p1 c)
(wrap-start-check (wrap-start-check
(and (draw-solid-line (build-posn p0) (build-posn p1) (color->symbol c)) ([hash-table-get privates '%draw-solid-line] (build-posn p0) (build-posn p1) (color->symbol c))))
(void))))
(define/provide (drawString-idraw.Posn-java.lang.String-native this accs gets privates p s) (define/provide (drawString-idraw.Posn-java.lang.String-native this accs gets privates p s)
(define s* (send s get-mzscheme-string))
(wrap-start-check (wrap-start-check
(and ([hash-table-get privates '%draw-string] (build-posn p) s*)))
(draw-solid-string (build-posn p) (send s get-mzscheme-string))
(void))))
(define/provide (clearCircle-idraw.Posn-int-idraw.Color-native this accs gets privates p r c) (define/provide (clearCircle-idraw.Posn-int-idraw.Color-native this accs gets privates p r c)
(wrap-start-check (wrap-start-check
(and (check-arg r "clearCircle(Posn, int, Color)" "second") (check-arg r "clearCircle(Posn, int, Color)" "second")
(clear-circle (build-posn p) r (color->symbol c)) ([hash-table-get privates '%clear-circle] (build-posn p) r (color->symbol c))))
(void))))
(define/provide (clearDisk-idraw.Posn-int-idraw.Color-native this accs gets privates p r c) (define/provide (clearDisk-idraw.Posn-int-idraw.Color-native this accs gets privates p r c)
(wrap-start-check (wrap-start-check
(and (check-arg r "clearDisk(Posn, int, Color)" "second") (check-arg r "clearDisk(Posn, int, Color)" "second")
(clear-solid-disk (build-posn p) r (color->symbol c)) ([hash-table-get privates '%clear-solid-disk] (build-posn p) r (color->symbol c))))
(void))))
(define/provide (clearRect-idraw.Posn-int-int-idraw.Color-native this accs gets privates p w h c) (define/provide (clearRect-idraw.Posn-int-int-idraw.Color-native this accs gets privates p w h c)
(wrap-start-check (wrap-start-check
(and (check-arg w "clearRect(Posn, int, int, Color)" "second") (check-arg w "clearRect(Posn, int, int, Color)" "second")
(check-arg h "clearRect(Posn, int, int, Color)" "third") (check-arg h "clearRect(Posn, int, int, Color)" "third")
(clear-solid-rect (build-posn p) w h (color->symbol c)) ([hash-table-get privates '%clear-solid-rect] (build-posn p) w h (color->symbol c))))
(void))))
(define/provide (clearLine-idraw.Posn-idraw.Posn-idraw.Color-native this accs gets privates p0 p1 c) (define/provide (clearLine-idraw.Posn-idraw.Posn-idraw.Color-native this accs gets privates p0 p1 c)
(wrap-start-check (wrap-start-check
(and ([hash-table-get privates '%clear-solid-line] (build-posn p0) (build-posn p1) (color->symbol c))))
(clear-solid-line (build-posn p0) (build-posn p1) (color->symbol c)) )
(void))))
)

View File

@ -1,26 +1,32 @@
package idraw; package idraw;
public class Canvas { public class Canvas {
private int width = 0;
private int height = 0;
public native void start(int width, int height); public Canvas(int width, int height) {
this.width = width;
public native void stop(); this.height = height;
}
public native void drawCircle(Posn p, int r, Color c);
// these two are cheats:
public native void drawDisk(Posn p, int r, Color c); public native void copy();
public native void stop();
public native void drawRect(Posn p, int width, int height, Color c); // I need to figure out how to accomplish these two things, especially stop,
// directly at the Scheme level w/o going thru the Java layer.
public native void drawLine(Posn p0, Posn p1, Color c); // BUG: this is actually a bug in ProfessorJ. Making these protected should
// work just fine. Indeed, leaving off the access control qualifier should
public native void drawString(Posn p, String s); // work, too. (That's package protected.)
public native void clearCircle(Posn p, int r, Color c); public native void show();
public native void close();
public native void clearDisk(Posn p, int r, Color c); public native void drawCircle(Posn p, int r, Color c);
public native void drawDisk(Posn p, int r, Color c);
public native void clearRect(Posn p, int width, int height, Color c); public native void drawRect(Posn p, int width, int height, Color c);
public native void drawLine(Posn p0, Posn p1, Color c);
public native void clearLine(Posn p0, Posn p1, Color c); public native void drawString(Posn p, String s);
public native void clearCircle(Posn p, int r, Color c);
public native void clearDisk(Posn p, int r, Color c);
public native void clearRect(Posn p, int width, int height, Color c);
public native void clearLine(Posn p0, Posn p1, Color c);
} }

View File

@ -1,125 +1,10 @@
#cs #cs
(module World-native-methods mzscheme (module World-native-methods mzscheme
(require (lib "draw.ss" "htdp") (require "support.scm" (lib "unitsig.ss"))
(lib "posn.ss" "lang")
(lib "class.ss")
(lib "String.ss" "profj" "libs" "java" "lang")
(lib "Throwable.ss" "profj" "libs""java""lang")
(lib "RuntimeException.ss" "profj" "libs" "java" "lang"))
;(require "Posn.ss")
;raises a Java exception with the specified error message (provide endOfTime-native endOfWorld-native bigBangO-double-native)
;raise-error: String -> void
(define (raise-error message) (define void-or-true void)
(raise (define (world-return w) w)
(create-java-exception RuntimeException message
(lambda (exn str)
(send exn RuntimeException-constructor-java.lang.String str))
(current-continuation-marks))))
(define-syntax (define/provide stx) (define-values/invoke-unit/sig world-native^ world-native@ #f support^))
(syntax-case stx ()
[(_ id val)
(identifier? #'id)
#'(begin
(define id val)
(provide id))]
[(_ (id . formals) . rest)
#'(begin
(define (id . formals) . rest)
(provide id))]))
(define Posn-x-get (dynamic-require '(lib "Posn.ss" "htdch" "idraw") 'Posn-x-get))
(define Posn-y-get (dynamic-require '(lib "Posn.ss" "htdch" "idraw") 'Posn-y-get))
(define (build-posn posnO)
(make-posn (Posn-x-get posnO) (Posn-y-get posnO)))
(define (color->symbol colorO)
(string->symbol (to-lower-case (send colorO my-name))))
(define (to-lower-case s)
(letrec ((lower
(lambda (s)
(cond
((null? s) s)
(else (cons (char-downcase (car s))
(lower (cdr s))))))))
(list->string (lower (string->list s)))))
#|
(define/provide (start-int-int-native this accs gets privates x y)
(start x y))
(define/provide (stop-native this accs gets privates) (stop))
(define/provide (drawCircle-draw.Posn-int-draw.Color-native this accs gets privates posn r c)
(draw-circle (build-posn posn) r (color->symbol c)))
(define/provide (drawDisk-draw.Posn-int-draw.Color-native this accs gets privates posn r c)
(draw-solid-disk (build-posn posn) r (color->symbol c)))
(define/provide (drawRect-draw.Posn-int-int-draw.Color-native this accs gets privates posn w h c)
(draw-solid-rect (build-posn posn) w h (color->symbol c)))
(define/provide (drawLine-draw.Posn-draw.Posn-draw.Color-native this accs gets privates p0 p1 c)
(draw-solid-line (build-posn p0) (build-posn p1) (color->symbol c)))
(define/provide (drawString-draw.Posn-java.lang.String-native this accs gets privates p s)
(draw-solid-string (build-posn p) (send s get-mzscheme-string)))
(define/provide (clearCircle-draw.Posn-int-draw.Color-native this accs gets privates p r c)
(clear-circle (build-posn p) r (color->symbol c)))
(define/provide (clearDisk-draw.Posn-int-draw.Color-native this accs gets privates p r c)
(clear-solid-disk (build-posn p) r (color->symbol c)))
(define/provide (clearRect-draw.Posn-int-int-draw.Color-native this accs gets privates p w h c)
(clear-solid-rect (build-posn p) w h (color->symbol c)))
(define/provide (clearLine-draw.Posn-draw.Posn-draw.Color-native this accs gets privates p0 p1 c)
(clear-solid-line (build-posn p0) (build-posn p1) (color->symbol c)))
(define/provide (sleepForAWhile-int-native this accs gets privates s)
(sleep-for-a-while s))
|#
(define/provide (bigBang-int-int-double-native this accs gets privates width height i)
(define theCanvas ((hash-table-get accs 'theCanvas) this))
(unless (> width 0)
(raise-error
(format "The method bigBang(int,int,double) expected first argument to be greather than 0, given ~a" width)))
(unless (> height 0)
(raise-error
(format "The method bigBang(int,int,double) expected second argument to be greater than 0, given ~a" height)))
(unless (>= i 0)
(raise-error
(format "The method bigBang(int,int,double) expected third argument to be 0 or greater, given ~a" i)))
(send theCanvas start-int-int width height)
(big-bang i this)
(on-tick-event
(lambda (world)
(send world erase)
(send world onTick)
(send world draw)
world))
(on-key-event
(lambda (ke world)
(send world erase)
(send world onKeyEvent-java.lang.String (make-java-string (keyevent->string ke)))
(send world draw)
world))
(void))
;; (union Char Symbol) -> String
(define (keyevent->string ke)
(if (char? ke) (string ke) (symbol->string ke)))
(define/provide (endOfTime-native this accs gets privates)
(end-of-time)
this)
(define/provide (endOfWorld-native this accs gets privates)
(end-of-time)
this)
)

View File

@ -2,19 +2,33 @@ package idraw;
public abstract class World { public abstract class World {
public Canvas theCanvas = new Canvas(); public Canvas theCanvas;
public native void bigBang(int width, int height, double s); public void bigBang(int width, int height, double s) {
if (width <= 0)
public native World endOfTime(); Util.error("The method bigBang(int,int,double) expects " +
"the first argument to be greather than 0, given "
+ width);
if (height <= 0)
Util.error("The method bigBang(int,int,double) expects " +
"the second argument to be greather than 0, given "
+ height);
if (s <= 0)
Util.error("The method bigBang(int,int,double) expects " +
"the third argument to be greather than 0, given "
+ s);
theCanvas = new Canvas(width,height);
bigBangO(s);
}
public native World endOfWorld(); private native void bigBangO(double s);
public abstract void onTick(); // --------------------------------------------------------
public abstract void onKeyEvent(String ke); public native World endOfTime();
public native World endOfWorld();
public abstract void draw(); public abstract void onTick();
public abstract void onKeyEvent(String ke);
public abstract void erase(); public abstract void draw();
public abstract void erase();
} }

View File

@ -0,0 +1,51 @@
(module support mzscheme
(require (lib "draw.ss" "htdp")
(lib "posn.ss" "lang")
(lib "class.ss")
(lib "unit.ss") (lib "unitsig.ss")
(lib "String.ss" "profj" "libs" "java" "lang"))
#;(lib "Throwable.ss" "profj" "libs""java""lang")
#;(lib "RuntimeException.ss" "profj" "libs" "java" "lang")
(provide world-native@ world-native^ support^)
(define-signature world-native^ (endOfTime-native endOfWorld-native bigBangO-double-native))
(define-signature support^ (world-return void-or-true))
(define world-native@
(unit/sig world-native^
(import support^)
(define (bigBangO-double-native this accs gets privates i)
(define theCanvas ((hash-table-get accs 'theCanvas) this))
(define width (with-method ([g (theCanvas Canvas-width-get)]) (g '___)))
(define height (with-method ([g (theCanvas Canvas-height-get)]) (g '___)))
;; call only *after* start
(define (on-event world th)
(begin-draw-sequence)
(send theCanvas copy)
(send world erase)
(th)
(send world draw)
(end-draw-sequence)
world)
(send theCanvas show)
(big-bang i this)
(on-tick-event
(lambda (world)
(on-event world (lambda () (send world onTick)))))
(on-key-event
(lambda (ke world)
(define ke* (make-java-string (if (char? ke) (string ke) (symbol->string ke))))
(on-event world (lambda () (send world onKeyEvent-java.lang.String ke*)))))
(void-or-true))
(define (endOfTime-native this accs gets privates)
(define theCanvas ((hash-table-get accs 'theCanvas) this))
(send theCanvas stop)
(world-return this))
(define (endOfWorld-native this accs gets privates)
(define theCanvas ((hash-table-get accs 'theCanvas) this))
(send theCanvas stop)
(world-return this))))
)