about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-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
+]