git » jacl.git » commit 0d04338

muuuuch faster repl

author Alan Dipert
2019-12-28 06:39:11 UTC
committer Alan Dipert
2019-12-28 06:39:11 UTC
parent 1a2983ec86bb28ef7228cb8df2e490aaab4007cb

muuuuch faster repl

repl-client/jacl +4 -0
repl-client/jacl-client.R +62 -14

diff --git a/repl-client/jacl b/repl-client/jacl
new file mode 100755
index 0000000..2541455
--- /dev/null
+++ b/repl-client/jacl
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+DIR="$(dirname $(readlink -f "$0"))"
+$DIR/jacl-client.R
diff --git a/repl-client/jacl-client.R b/repl-client/jacl-client.R
index 8554237..122cfe2 100755
--- a/repl-client/jacl-client.R
+++ b/repl-client/jacl-client.R
@@ -1,18 +1,16 @@
 #!/usr/bin/env Rscript
 
+library(R6)
 library(chromote)
 library(jsonlite)
 
-muffle <- function(expr) {
-  sink("/dev/null")
-  tryCatch({
-    force(expr)
-    invisible()
-  }, finally = sink())
+invisibly <- function(expr) {
+  force(expr)
+  invisible()
 }
 
 # TODO figure out how to use Log instead of deprecated Console
-muffle({
+invisibly({
   b <- ChromoteSession$new()
   b$Page$navigate("file:///home/alan/github/alandipert/jacl/index.html")
   b$Console$messageAdded(function (msg) { 
@@ -22,13 +20,63 @@ muffle({
   b$Console$enable()
 })
 
+BufferedInput <- R6::R6Class("BufferedInput",
+  public = list(
+    initialize = function(f, callback, window_ms) {
+      private$fd <- file(f, "rb", blocking = FALSE)
+      private$callback <- callback
+      private$window_ms <- window_ms
+      read_chunk <- function() {
+        # TODO select() on stdin here would be cool
+        chars <- rawToChar(readBin(private$fd, "raw", 8192))
+        if (nchar(chars)) {
+          if (!is.null(private$scheduled)) private$scheduled()
+          private$chunk <- paste0(private$chunk, chars)
+          private$schedule()
+        }
+        later::later(read_chunk, 0.01, loop = private$child_loop)
+      }
+      read_chunk()
+    },
+    run = function() {
+      while(TRUE) {
+        later::run_now(Inf, loop = private$child_loop)
+      }
+    }
+  ),
+  private = list(
+    window_ms = 50,
+    schedule = function() {
+      private$scheduled <- later::later(function() {
+        private$callback(private$chunk)
+        private$chunk <- character(0)
+      }, delay = private$window_ms/1000, loop = private$child_loop)
+    },
+    chunk = character(0),
+    scheduled = NULL,
+    callback = NULL,
+    fd = NULL,
+    child_loop = later::create_loop(autorun = FALSE)
+  )
+)
+
 cat('> ')
-f <- file("stdin")
-open(f, blocking = TRUE)
-while(isOpen(f)) {
-  ch <- readChar(f, 1)
-  json_str <- toJSON(ch, auto_unbox = TRUE)
-  code <- paste0('replInputStream.write(', json_str, ')')
+bi <- BufferedInput$new("stdin", function(chunk) {
+  json_str <- toJSON(chunk, auto_unbox = TRUE)
+  code <- paste0('replInputStream.writeEach(', json_str, ')')
   b$Runtime$evaluate(code)
-}
+}, 10)
+bi$run()
 
+#cat('> ')
+#f <- file("stdin", "rb", blocking = FALSE)
+#
+#while (isOpen(f)) {
+#  str <- rawToChar(readBin(f, "raw", 8192))
+#  cat("str=", str, "\n")
+#  #char <- rawToChar(readBin(f, "raw", 1))
+#  #cat("char=",char,"\n")
+#  #json_str <- toJSON(char, auto_unbox = TRUE)
+#  #code <- paste0('replInputStream.writeEach(', json_str, ')')
+#  #b$Runtime$evaluate(code)
+#}
\ No newline at end of file