shithub: orca

Download patch

ref: e34c9f027a536d1cdb216ab88f4b4a16789a16e8
parent: 09697c50bf8815cffdca16508f87b751ad7d7ce4
author: cancel <cancel@cancel.fm>
date: Mon Dec 3 04:40:49 EST 2018

Add predictive remarking for tui visualization

--- a/tui_main.c
+++ b/tui_main.c
@@ -442,17 +442,42 @@
     }
   }
 
+  Field scratch_field;
+  field_init(&scratch_field);
+
   Tui_cursor tui_cursor;
   tui_cursor_init(&tui_cursor);
   Usz tick_num = 0;
   Usz ruler_spacing_y = 8;
   Usz ruler_spacing_x = 8;
+  bool needs_remarking = true;
   for (;;) {
     int term_height = getmaxy(stdscr);
     int term_width = getmaxx(stdscr);
     assert(term_height >= 0 && term_width >= 0);
-    (void)term_height;
-    (void)term_width;
+    // We can predictavely step the next simulation tick and then use the
+    // resulting markmap buffer for better UI visualization. If we don't do
+    // this, after loading a fresh file or after the user performs some edit
+    // (or even after a regular simulation step), the new glyph buffer won't
+    // have had phase 0 of the simulation run, which means the ports and other
+    // flags won't be set on the markmap buffer, so the colors for disabled
+    // cells, ports, etc. won't be set.
+    //
+    // We can just perform a simulation step using the current state, keep the
+    // markmap buffer that it produces, then roll back the glyph buffer to
+    // where it was before. This should produce results similar to having
+    // specialized UI code that looks at each glyph and figures out the ports,
+    // etc.
+    if (needs_remarking) {
+      field_resize_raw_if_necessary(&scratch_field, field.height, field.width);
+      field_copy_subrect(&field, &scratch_field, 0, 0, 0, 0, field.height,
+                         field.width);
+      orca_run(field.buffer, markmap_r.buffer, field.height, field.width,
+               tick_num, &bank);
+      field_copy_subrect(&scratch_field, &field, 0, 0, 0, 0, field.height,
+                         field.width);
+      needs_remarking = false;
+    }
     draw_field(stdscr, term_height, term_width, 0, 0, field.buffer,
                markmap_r.buffer, field.height, field.width, ruler_spacing_y,
                ruler_spacing_x);
@@ -503,6 +528,7 @@
     case AND_CTRL('u'):
       if (undo_history_count(&undo_hist) > 0) {
         undo_history_pop(&undo_hist, &field, &tick_num);
+        needs_remarking = true;
       }
       break;
     case '[':
@@ -526,6 +552,7 @@
       orca_run(field.buffer, markmap_r.buffer, field.height, field.width,
                tick_num, &bank);
       ++tick_num;
+      needs_remarking = true;
       break;
     default:
       if (key >= '!' && key <= '~') {
@@ -532,6 +559,11 @@
         undo_history_push(&undo_hist, &field, tick_num);
         gbuffer_poke(field.buffer, field.height, field.width, tui_cursor.y,
                      tui_cursor.x, (char)key);
+        // Indicate we want the next simulation step to be run predictavely, so
+        // that we can use the reulsting mark buffer for UI visualization. This
+        // is "expensive", so it could be skipped for non-interactive input in
+        // situations where max throughput is necessary.
+        needs_remarking = true;
       }
       break;
     }
@@ -545,6 +577,7 @@
   markmap_reusable_deinit(&markmap_r);
   bank_deinit(&bank);
   field_deinit(&field);
+  field_deinit(&scratch_field);
   undo_history_deinit(&undo_hist);
   return 0;
 }