Skip to content

Instantly share code, notes, and snippets.

@Bogdanp
Created January 14, 2023 18:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bogdanp/4afd76f1e96ce4cad126a989e4e1512b to your computer and use it in GitHub Desktop.
Save Bogdanp/4afd76f1e96ce4cad126a989e4e1512b to your computer and use it in GitHub Desktop.
#lang racket/base
(require racket/class
(prefix-in gui: racket/gui)
racket/gui/easy
racket/gui/easy/operator)
(define console%
(class* object% (view<%>)
(init-field @text)
(super-new)
(define/public (dependencies)
(list @text))
(define/public (create parent)
(define editor
(new (class gui:text%
(super-new)
(define allow-change? #f)
(define/public (begin-allow-change)
(set! allow-change? #t))
(define/public (end-allow-change)
(set! allow-change? #f))
(define/augment (can-delete? _start _len)
allow-change?)
(define/augment (can-insert? _start _len)
allow-change?))))
(send editor begin-allow-change)
(send editor insert (obs-peek @text) 0)
(send editor end-allow-change)
(new gui:editor-canvas%
[parent parent]
[editor editor]))
(define/public (update v dep val)
(case/dep dep
[@text
(define editor
(send v get-editor))
(send editor begin-edit-sequence)
(send editor begin-allow-change)
(send editor erase)
(send editor insert val)
(send editor end-allow-change)
(send editor scroll-to-position (string-length val) #f 'same 'end)
(send editor end-edit-sequence)]))
(define/public (destroy _v)
(void))))
(define (console @text)
(new console%
[@text @text]))
(module+ main
(define/obs @text
"Beginning of text.")
(thread
(lambda ()
(let loop ()
(@text . <~ . (λ (t)
(string-append t (format "~nThe time is now: ~a" (current-seconds)))))
(sleep 1)
(loop))))
(render
(window
#:size '(400 300)
(console @text))))
#lang racket/base
(require racket/class
(prefix-in gui: racket/gui)
racket/gui/easy
racket/gui/easy/operator
(only-in racket/gui/easy/private/view context-mixin)
racket/list
racket/string)
(define max-buffer-size
100)
(define max-text-size
10240)
(define console%
(class* object% (view<%>)
(init-field @buffer)
(super-new)
(define/public (dependencies)
(list @buffer))
(define/public (create parent)
(define editor
(new (class gui:text%
(super-new)
(define allow-change? #f)
(define/public (begin-allow-change)
(set! allow-change? #t))
(define/public (end-allow-change)
(set! allow-change? #f))
(define/augment (can-delete? _start _len)
allow-change?)
(define/augment (can-insert? _start _len)
allow-change?))))
(define buffer
(obs-peek @buffer))
(send editor begin-allow-change)
(send editor insert (string-join (reverse buffer)) 0)
(send editor end-allow-change)
(define canvas
(new (context-mixin gui:editor-canvas%)
[parent parent]
[editor editor]))
(begin0 canvas
(send canvas set-context 'buffer buffer)))
(define/public (update v dep val)
(case/dep dep
[@buffer
(define old
(send v get-context 'buffer))
(define todo
(reverse
(for/list ([chunk (in-list val)])
#:break (and (not (null? old)) (eq? chunk (car old)))
chunk)))
(unless (null? todo)
(define editor
(send v get-editor))
(send editor begin-edit-sequence)
(send editor begin-allow-change)
(send editor set-position (send editor last-position))
(for ([chunk (in-list todo)])
(send editor insert chunk))
(define last-pos
(send editor last-position))
(send editor scroll-to-position last-pos #f 'same 'end)
(when (> last-pos max-text-size)
(send editor delete 0 (quotient max-text-size 2)))
(send editor end-allow-change)
(send editor end-edit-sequence)
(send v set-context 'buffer val))]))
(define/public (destroy v)
(send v clear-context))))
(define (console @buffer)
(new console%
[@buffer @buffer]))
(module+ main
(define/obs @buffer
(list "Beginning of text."))
(thread
(lambda ()
(let loop ()
(@buffer . <~ . (λ (buffer)
(define next-buffer
(cons (format "~nThe time is now: ~a" (current-seconds)) buffer))
(if (> (length next-buffer) max-buffer-size)
(take next-buffer max-buffer-size)
next-buffer)))
(sleep 1)
(loop))))
(render
(window
#:size '(400 300)
(console @buffer))))
@Bogdanp
Copy link
Author

Bogdanp commented Jan 16, 2023

Most likely it would be, but for small values of max-buffer-size I think the difference will be negligible either way.

@otherjoel
Copy link

Most likely it would be, but for small values of max-buffer-size I think the difference will be negligible either way.

Realized I could answer that on my own, I found my method was consistently slower, and deleted my comment hoping maybe you hadn't seen it yet (haha). I think it's because my method does a lot more allocation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment