examples/open-loop-graphical.ss
#lang scheme/gui

(require (planet williams/simulation/simulation-with-graphics))
(require (planet williams/science/random-distributions))

(define attendant #f)

(define (generator n)
  (do ((i 0 (+ 1 i)))
      ((= i n) (void))
    (wait (random-exponential 4.0))
    (schedule now (customer i))))

(define-process (customer i)
  (with-resource (attendant)
    (wait/work (random-flat 2.0 10.0))))

(define (run-simulation n1 n2)
  (parameterize
      ((current-output-port (open-output-text-editor text)))
    (with-new-simulation-environment
     ;; Initialize graphics
     (begin-busy-cursor)
     (send run-button enable #f)
     (send gauge set-range n1)
     ;; Start open loop simulation
     (let ((k (make-variable 0))
           (max-attendants (make-variable)))
       (tally (variable-statistics max-attendants))
       (tally (variable-history max-attendants))
       (monitor after (set-variable-value! k v)
                (send gauge set-value v))
       (send gauge set-value 0)
       (do ((i 0 (+ i 1)))
           ((= i n1) (void))
         (with-new-simulation-environment
          (set! attendant (make-resource +inf.0))
          (schedule (at 0.0) (generator n2))
          (start-simulation)
          (set-variable-value!
           max-attendants
           (variable-maximum (resource-satisfied-variable-n attendant)))
          (send text erase)
          (printf "Number of experiments = ~a~n"
                  (variable-n max-attendants))
          (printf "Minimum maximum attendants = ~a~n"
                  (variable-minimum max-attendants))
          (printf "Maximum maximum attendants = ~a~n"
                  (variable-maximum max-attendants))
          (set-variable-value! k i)))
       (printf "Mean maximum attendants = ~a~n"
               (variable-mean max-attendants))
       (printf "Variance maximum attendants = ~a~n"
               (variable-variance max-attendants))
       (write-special (history-plot (variable-history max-attendants)
                                    "Maximum Attendants")))
     ;; Finalize graphics
     (send run-button enable #t)
     (end-busy-cursor))))

;;; Simulation graphics

(define frame (instantiate frame% ("Graphical Open Loop Example")
                (x 0) (y 0)))
(define n1-slider (instantiate slider% ("Number of runs" 1 1000 frame)
                    (init-value 100)
                    (style '(horizontal vertical-label))))
(define n2-slider (instantiate slider% ("Number of customers per run" 1 1000 frame)
                    (init-value 100)
                    (style '(horizontal vertical-label))))
                                
(define canvas (instantiate editor-canvas% (frame)
                 (min-width 500)
                 (min-height 400)
                 (style '(no-hscroll no-vscroll))))
(define text (instantiate text% ()))
(send canvas set-editor text)

(define gauge (instantiate gauge% ("Progress" 100 frame)))

(define run-button (instantiate button%
                     ("&Run" frame (lambda (b e)
                                     (run-simulation
                                      (send n1-slider get-value)
                                      (send n2-slider get-value))))))

(send frame show #t)