Going beyond the world / universe
I thought I would try a simple GUI application using the world / universal mutation approach, but am trying to implement the world / universe project myself.
I have my little sketch below, but I quickly came to the conclusion that while I could use the training package, I don't know how to implement the training function myself.
I guess I should be using continuations, but that doesn't sound like the approach in the universe.rkt source.
I could always just add the program to the canvas class (since it played the same slides before as before), but I really want to get an idea of how to implement the "world / universe" style of program control.
;;;;----
#lang racket/gui
; simple drawing program
; mousedown starts recording a list of points
; mousechanged starts recording a new list
; paint callback paints the list of lists as lines.
(define diagramframe (new frame% [label "paint"] [width 300]
[height 300] [x 1000][y 300]))
;(define lines '(((0 . 0) (0 . 300) (250 . 250) (150 . 176))))
(define lines '(((0 . 0) (0 . 300) (250 . 250) (150 . 176))
((10 . 4) (280 . 10))))
(define paintcanvas%
(class canvas%
(init-field mouse-event-callback)
(super-new)
(define dc (send this get-dc))
(define/override (on-event mouse-event)
(mouse-event-callback mouse-event))))
(define (paint-cb c dc)
(for-each (λ (line) (send dc draw-lines line)) lines))
(define (me-cb mouse-event)
(let ((x (send mouse-event get-x))
(y (send mouse-event get-y)))
(when (and (send mouse-event get-left-down)
(send mouse-event moving?))
(if (send mouse-event button-changed?)
; if true append as new list
'()
; if false append existing list
'()))))
(define Paintcanvas (new paintcanvas%
[parent diagramframe]
[paint-callback paint-cb]
[mouse-event-callback me-cb]))
(define (main world)
(when world (main (??? world)))
(send diagramframe show #t))
(main lines)
(send diagramframe show #t)
;;-----
source to share
This is how I will do it.
Note that the GUI event loop is driven by the main program. Use timer events for on-tick implementation.
#lang racket/gui
;;;
;;; WORLD
;;;
(define-struct world (lines))
(define the-world (make-world '((0 . 0) (0 . 300) (250 . 250) (150 . 176) (10 . 4) (280 . 10))))
;;;
;;; USER LAND
;;;
(define (on-mouse-event world event)
(if (and (send event get-left-down)
(send event moving?)
#; (send event button-changed?))
(let ((x (send event get-x))
(y (send event get-y)))
(make-world (cons (cons x y) (world-lines world))))
world))
(define (on-paint world dc)
(send dc draw-lines
(map pair->point (world-lines world))))
(define (pair->point p)
(make-object point% (car p) (cdr p)))
;;;
;;; SYSTEM
;;;
(define user:on-paint on-paint)
(define diagramframe (new frame% [label "paint"] [width 300] [height 300] [x 1000][y 300]))
(define paintcanvas%
(class canvas%
(inherit get-dc refresh)
(super-new)
(define/override (on-paint)
(send (get-dc) suspend-flush)
(user:on-paint the-world (get-dc))
(send (get-dc) resume-flush))
(define/override (on-event mouse-event)
(let* ([old-world the-world]
[new-world (on-mouse-event the-world mouse-event)])
(if (eq? old-world new-world)
(super on-event mouse-event)
(begin
(set! the-world new-world)
(refresh)))))))
(define paintcanvas (new paintcanvas% [parent diagramframe]))
(send diagramframe show #t)
source to share