199 lines
6.2 KiB
Racket
199 lines
6.2 KiB
Racket
#lang scheme/gui
|
|
|
|
(define seed (abs (current-milliseconds)))
|
|
(random-seed seed)
|
|
|
|
(define use-nested? #t)
|
|
|
|
(error-print-context-length 100)
|
|
|
|
;; Don't paste before copying, because that interferes with replay
|
|
(define copied? #f)
|
|
(define copy-len 0)
|
|
|
|
(define (go pause x-pos)
|
|
(define orig-t (new text%))
|
|
|
|
(define frame
|
|
(new (class frame%
|
|
(define/augment (on-close) (exit))
|
|
(super-new))
|
|
[label "Test"]
|
|
[width 300]
|
|
[height 400]
|
|
[x x-pos]))
|
|
|
|
(define canvas
|
|
(new editor-canvas% [parent frame] [editor orig-t]))
|
|
|
|
(define _1 (send frame show #t))
|
|
|
|
(define (init t)
|
|
(send t set-max-undo-history 100))
|
|
(define _2 (init orig-t))
|
|
|
|
(define (random-elem v)
|
|
(vector-ref v (random (vector-length v))))
|
|
|
|
(define (random-string)
|
|
(random-elem '#("a" "x\ny\nz\n" "(define (f x)\n (+ x x))\n" "hello there" "" "\n")))
|
|
|
|
(define seqs (make-hasheq))
|
|
|
|
(define ts-length 64)
|
|
(define ts-pos 0)
|
|
(define ts (make-vector ts-length orig-t))
|
|
(define (add-t! t2)
|
|
(if (= ts-pos ts-length)
|
|
(let ([v ts])
|
|
(set! ts (make-vector ts-length orig-t))
|
|
(set! ts-pos 0)
|
|
(for ([t3 (in-vector v)])
|
|
(when (zero? (random 2))
|
|
(add-t! t3)))
|
|
(add-t! t2))
|
|
(begin
|
|
(vector-set! ts ts-pos t2)
|
|
(set! ts-pos (add1 ts-pos)))))
|
|
|
|
(define (set-copied?! t)
|
|
(let ([len (- (send t get-end-position)
|
|
(send t get-start-position))])
|
|
(if (zero? len)
|
|
#f
|
|
(begin
|
|
(set! copy-len len)
|
|
(set! copied? #t)
|
|
#t))))
|
|
|
|
(define (maybe-convert)
|
|
(when (zero? (random 4))
|
|
(let ([data (send the-clipboard get-clipboard-data "WXME" 0)])
|
|
(send the-clipboard set-clipboard-client
|
|
(new (class clipboard-client%
|
|
(inherit add-type)
|
|
(super-new)
|
|
(add-type "WXME")
|
|
(define/override (get-data format) data)))
|
|
0))))
|
|
|
|
(define actions
|
|
(vector
|
|
(lambda (t) (send t undo))
|
|
(lambda (t) (send t redo))
|
|
(lambda (t) (send t insert (random-string) (random (add1 (send t last-position)))))
|
|
(lambda (t) (send t insert "\t" (random (add1 (send t last-position)))))
|
|
(lambda (t)
|
|
(let ([pos (random (add1 (send t last-position)))])
|
|
(send t delete pos (random (max 1 (- (send t last-position) pos))))))
|
|
(lambda (t)
|
|
(send t begin-edit-sequence)
|
|
(hash-update! seqs t add1 0))
|
|
(lambda (t)
|
|
(let loop ()
|
|
(when (positive? (hash-ref seqs t 0))
|
|
(send t end-edit-sequence)
|
|
(hash-update! seqs t sub1)
|
|
(when (zero? (random 2))
|
|
(loop)))))
|
|
(lambda (t)
|
|
(let ([pos (random (add1 (send t last-position)))])
|
|
(send t set-position pos (random (max 1 (- (send t last-position) pos))))))
|
|
(lambda (t) (when (set-copied?! t) (send t copy) (maybe-convert)))
|
|
(lambda (t) (when (set-copied?! t) (send t cut) (maybe-convert)))
|
|
(lambda (t) (when copied?
|
|
(let ([s (send t get-start-position)]
|
|
[e (send t get-end-position)]
|
|
[l (send t last-position)])
|
|
(send t paste)
|
|
(when copy-len
|
|
(unless (= (send t last-position)
|
|
(+ (- l (- e s)) copy-len))
|
|
(error 'paste "length mismatch: [~s, ~s) in ~s + ~s ~s -> ~s"
|
|
s e l copy-len
|
|
(send the-clipboard get-clipboard-data "TEXT" 0)
|
|
(send t last-position)))))
|
|
(when (zero? (random 4))
|
|
(set! copy-len #f)
|
|
(send t paste-next))))
|
|
(lambda (t) (send t change-style (make-object style-delta% 'change-size (add1 (random 42)))))
|
|
(lambda (t) (send t change-style
|
|
(send (make-object style-delta%) set-delta-foreground (make-object color%
|
|
(random 256)
|
|
(random 256)
|
|
(random 256)))))
|
|
(lambda (t)
|
|
(when use-nested?
|
|
(let ([t2 (new text%)])
|
|
(add-t! t2)
|
|
(init t2)
|
|
(send t insert (make-object editor-snip% t2)))))
|
|
(lambda (t)
|
|
(send t set-max-width (if (zero? (random 2))
|
|
(+ 50.0 (/ (random 500) 10.0))
|
|
'none)))
|
|
(lambda (t) (yield (system-idle-evt)))
|
|
(lambda (t) (pause))
|
|
))
|
|
|
|
(send canvas focus)
|
|
|
|
(let loop ()
|
|
(let ([act (random-elem actions)]
|
|
[t (if (zero? (random 2))
|
|
orig-t
|
|
(random-elem ts))])
|
|
(printf "~s: ~s ~s\n" seed (eq-hash-code t) act)
|
|
(act t)
|
|
(loop))))
|
|
|
|
(define (run-one)
|
|
(go void 50))
|
|
|
|
(define (run-two-concurrent)
|
|
(define sema-one (make-semaphore))
|
|
(define sema-two (make-semaphore))
|
|
|
|
(define (make sema-this sema-other x-pos)
|
|
(parameterize ([current-eventspace (make-eventspace)])
|
|
(queue-callback
|
|
(lambda ()
|
|
(semaphore-wait sema-this)
|
|
(go (lambda ()
|
|
(semaphore-post sema-other)
|
|
(semaphore-wait sema-this))
|
|
x-pos)))
|
|
(current-eventspace)))
|
|
|
|
(define e1 (make sema-one sema-two 50))
|
|
(define e2 (make sema-two sema-one 350))
|
|
(semaphore-post sema-one)
|
|
(application-quit-handler (lambda args (exit)))
|
|
(yield never-evt))
|
|
|
|
(define (run-two)
|
|
(define one-box (box #f))
|
|
(define two-box (box #f))
|
|
(define (make box-this box-other x-pos)
|
|
(let/ec esc
|
|
(call-with-continuation-prompt
|
|
(lambda ()
|
|
(begin
|
|
(let/cc k
|
|
(set-box! box-this k)
|
|
(esc))
|
|
(go (lambda ()
|
|
(let/cc k
|
|
(set-box! box-this k)
|
|
((unbox box-other))))
|
|
x-pos))))))
|
|
|
|
(make one-box two-box 50)
|
|
(make two-box one-box 350)
|
|
(call-with-continuation-prompt
|
|
(lambda ()
|
|
((unbox one-box)))))
|
|
|
|
(run-two)
|
|
|