about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-05-09 10:56:44 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-05-09 11:03:25 -0700
commitf8c0ef3e201883566a788eb03c627f94680ba2c3 (patch)
tree41d4103cead5efd471ef58815ce74f86b227dafb
parent9e5ceacd74dce8d4ce971b7bfd9c7c74f28e51c6 (diff)
downloadmu-f8c0ef3e201883566a788eb03c627f94680ba2c3.tar.gz
1315 - chessboard now working interactively
I tried to bring too much into this commit, and paid the price with some
debugging effort. Still havent't tried to enable line buffering, but
I'll take a snapshot.

Some tests are failing because of the huge hack in the scheduler.

For a while I thought there was a bug in termbox because I kept seeing
segfaults and valgrind complained about out-of-bounds access. But that
was just subsidiary threads trying to print to the screen after I'd
returned to console mode.

Maybe I should add a test for send-keys-to-channel. Or just use a fake
keyboard rather than a channel.

And *then* there's the fact that the interaction is molasses slow.
Slower than the arc version even though the tests run so much faster.
And what's with the long pauses in printing strings to screen?
-rw-r--r--038scheduler.cc6
-rw-r--r--070display.cc3
-rw-r--r--074keyboard.mu15
-rw-r--r--chessboard.mu70
4 files changed, 91 insertions, 3 deletions
diff --git a/038scheduler.cc b/038scheduler.cc
index 00d37371..99c5484f 100644
--- a/038scheduler.cc
+++ b/038scheduler.cc
@@ -64,6 +64,12 @@ void run(recipe_number r) {
 bool all_routines_done() {
   for (index_t i = 0; i < Routines.size(); ++i) {
 //?     cout << "routine " << i << ' ' << Routines.at(i)->state << '\n'; //? 1
+    // Ugly hack: temporarily assume that the first routine spawns helpers.
+    // When the first routine completes we can terminate.
+    // Biggest user of routines right now is tests. When the main test routine
+    // completes the test can terminate.
+    // XXX: We need a better story for when channels close.
+    if (Routines.at(i)->id == 1 && Routines.at(i)->state == COMPLETED) return true;
     if (Routines.at(i)->state == RUNNING) {
       return false;
     }
diff --git a/070display.cc b/070display.cc
index b4e354f8..b62cda37 100644
--- a/070display.cc
+++ b/070display.cc
@@ -187,8 +187,9 @@ case READ_KEY_FROM_KEYBOARD: {
   int event_type = tb_peek_event(&event, 5/*ms*/);
   long long int result = 0;
   long long int found = false;
+//?   cerr << event_type << '\n'; //? 1
   if (event_type == TB_EVENT_KEY) {
-    result = event.ch;
+    result = event.key ? event.key : event.ch;
     found = true;
   }
   products.resize(2);
diff --git a/074keyboard.mu b/074keyboard.mu
index 9cea3d1f..d79d20f6 100644
--- a/074keyboard.mu
+++ b/074keyboard.mu
@@ -51,3 +51,18 @@ recipe wait-for-key [
   c:character <- wait-for-key-from-keyboard
   reply c:character, x:address:keyboard/same-as-ingredient:0
 ]
+
+recipe send-keys-to-channel [
+  default-space:address:array:location <- new location:type, 30:literal
+  keyboard:address <- next-ingredient
+  chan:address:channel <- next-ingredient
+  screen:address <- next-ingredient
+  {
+    c:character <- read-key keyboard:address
+    loop-unless c:character
+    print-character screen:address, c:character
+    chan:address:channel <- write chan:address:channel, c:character
+    # todo: eof
+    loop
+  }
+]
diff --git a/chessboard.mu b/chessboard.mu
index 5ee36086..856d3b2b 100644
--- a/chessboard.mu
+++ b/chessboard.mu
@@ -173,7 +173,7 @@ recipe read-move [
   x:address:integer/deref <- read-file stdin:address:channel
   x:address:integer <- get-address result:address:move/deref, to-rank:offset
   x:address:integer/deref <- read-rank stdin:address:channel
-  expect-from-channel stdin:address:channel, 10:literal  # newline
+  expect-from-channel stdin:address:channel, 13:literal  # newline
   reply result:address:move
 ]
 
@@ -309,7 +309,7 @@ F read-move-blocking: routine failed to pause after rank 'a2-a']
     assert 4:boolean/waiting?, [
 F read-move-blocking: routine failed to pause after file 'a2-a4']
     # press 'newline'
-    1:address:channel <- write 1:address:channel, 10:literal  # newline
+    1:address:channel <- write 1:address:channel, 13:literal  # newline
     restart 2:integer/routine
     # 'read-move' now completes
     wait-for-routine 2:integer
@@ -465,3 +465,69 @@ scenario making-a-move [
     .                              .
   ]
 ]
+
+# Use this to debug asynchronous keyboard processing.
+#? recipe main [
+#?   default-space:address:array:location <- new location:type, 30:literal
+#?   switch-to-display
+#?   stdin:address:channel <- init-channel 10:literal/capacity
+#?   start-running send-keys-to-channel:recipe, 0:literal/keyboard, stdin:address:channel, 0:literal/screen
+#?   c:character, stdin:address:channel <- read stdin:address:channel
+#?   return-to-console
+#? ]
+
+#? recipe main [
+#?   default-space:address:array:location <- new location:type, 30:literal
+#?   switch-to-display
+#?   {
+#?     c:character, found:boolean <- read-key-from-keyboard
+#?     $print found:boolean, [
+#? ]
+#?     loop-unless found:boolean
+#?   }
+#? #?   return-to-console
+#?   $print c:character
+#? ]
+
+# todo:
+#   problem with buffering
+#   some way of closing channels
+recipe chessboard [
+  default-space:address:array:location <- new location:type, 30:literal
+  board:address:array:address:array:character <- initial-position
+  switch-to-display
+  # hook up stdin
+  stdin:address:channel <- init-channel 10:literal/capacity
+  start-running send-keys-to-channel:recipe, 0:literal/keyboard, stdin:address:channel, 0:literal/screen
+#?   # buffer stdin
+#?   buffered-stdin:address:channel <- init-channel 10:literal/capacity
+#?   start-running buffer-lines:recipe, stdin:address:channel, buffered-stdin:address:channel
+  {
+    msg:address:array:character <- new [Stupid text-mode chessboard. White pieces in uppercase; black pieces in lowercase. No checking for legal moves.
+  ]
+    print-string 0:literal/screen, msg:address:array:character
+    cursor-to-next-line 0:literal/screen
+    print-board 0:literal/screen, board:address:array:address:array:character
+    cursor-to-next-line 0:literal/screen
+    msg:address:array:character <- new [Type in your move as <from square>-<to square>. For example: 'a2-a4'. Then press <enter>.
+]
+    print-string 0:literal/screen, msg:address:array:character
+    cursor-to-next-line 0:literal/screen
+    msg:address:array:character <- new [Hit 'q' to exit.
+]
+    print-string 0:literal/screen, msg:address:array:character
+    cursor-to-next-line 0:literal/screen
+    msg:address:array:character <- new [move: ]
+    print-string 0:literal/screen, msg:address:array:character
+    m:address:move <- read-move stdin:address:channel
+    break-unless m:address:move
+    board:address:array:address:array:character <- make-move board:address:array:address:array:character, m:address:move
+    clear-screen 0:literal/screen
+    loop
+  }
+  return-to-console
+]
+
+recipe main [
+  chessboard
+]