shithub: orca

Download patch

ref: 986f16350cf520801a8371738d63241d471eb396
parent: d8f97553af219cd3b4767cb94fbb284b73a12aef
author: cancel <cancel@cancel.fm>
date: Mon Nov 26 09:22:53 EST 2018

Change to use all 3 phases, expand with macro

--- a/sim.c
+++ b/sim.c
@@ -109,6 +109,18 @@
   mbuffer_poke_relative_flags_or(mbuffer, height, width, y, x, _delta_y,       \
                                  _delta_x, Mark_flag_lock)
 
+#define PORT_LOCKED Mark_flag_lock
+#define PORT_UNLOCKED Mark_flag_none
+#define PORT_HASTE Mark_flag_haste_input
+
+#define OPER_PORT_INPUT(_delta_y, _delta_x, _flags)                            \
+  mbuffer_poke_relative_flags_or(mbuffer, height, width, y, x, _delta_y,       \
+                                 _delta_x, Mark_flag_input | _flags)
+
+#define OPER_PORT_OUTPUT(_delta_y, _delta_x, _flags)                           \
+  mbuffer_poke_relative_flags_or(mbuffer, height, width, y, x, _delta_y,       \
+                                 _delta_x, Mark_flag_output | _flags)
+
 #define OPER_MOVE_OR_EXPLODE(_delta_y, _delta_x)                               \
   oper_move_relative_or_explode(gbuffer, mbuffer, height, width,               \
                                 This_oper_char, y, x, _delta_y, _delta_x)
@@ -162,6 +174,9 @@
 OPER_DEFINE_LOWERCASE_DIRECTIONAL(west, 0, -1)
 
 OPER_PHASE_0(add)
+  OPER_PORT_INPUT(0, 1, PORT_LOCKED);
+  OPER_PORT_INPUT(0, 2, PORT_LOCKED);
+  OPER_PORT_OUTPUT(1, 0, PORT_LOCKED);
 OPER_END
 OPER_PHASE_1(add)
 OPER_END
@@ -204,52 +219,52 @@
 
 //////// Run simulation
 
-static void sim_phase_0(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width) {
-  for (Usz iy = 0; iy < height; ++iy) {
-    Glyph* glyph_row = gbuf + iy * width;
-    for (Usz ix = 0; ix < width; ++ix) {
-      Glyph c = glyph_row[ix];
-      if (c == '.')
-        continue;
-      if (mbuffer_peek(mbuf, height, width, iy, ix) &
-          (Mark_flag_lock | Mark_flag_sleep))
-        continue;
-      switch (c) {
-#define X(_oper_name, _oper_char)                                              \
+#define SIM_EXPAND_PHASE_0(_oper_name, _oper_char)                             \
   case _oper_char:                                                             \
     oper_phase0_##_oper_name(gbuf, mbuf, height, width, iy, ix);               \
     break;
-        ORCA_OPERATORS(X)
-#undef X
-      }
-    }
-  }
-}
+#define SIM_EXPAND_PHASE_1(_oper_name, _oper_char)                             \
+  case _oper_char:                                                             \
+    oper_phase1_##_oper_name(gbuf, mbuf, height, width, iy, ix);               \
+    break;
+#define SIM_EXPAND_PHASE_2(_oper_name, _oper_char)                             \
+  case _oper_char:                                                             \
+    oper_phase2_##_oper_name(gbuf, mbuf, height, width, iy, ix);               \
+    break;
 
-static void sim_phase_1(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width) {
+static void sim_phase_0(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width) {
   for (Usz iy = 0; iy < height; ++iy) {
     Glyph* glyph_row = gbuf + iy * width;
     for (Usz ix = 0; ix < width; ++ix) {
       Glyph c = glyph_row[ix];
-      if (c == '.')
-        continue;
-      if (mbuffer_peek(mbuf, height, width, iy, ix) &
-          (Mark_flag_lock | Mark_flag_sleep))
-        continue;
-      switch (c) {
-#define X(_oper_name, _oper_char)                                              \
-  case _oper_char:                                                             \
-    oper_phase1_##_oper_name(gbuf, mbuf, height, width, iy, ix);               \
-    break;
-        ORCA_OPERATORS(X)
-#undef X
-      }
+      switch (c) { ORCA_OPERATORS(SIM_EXPAND_PHASE_0) }
     }
   }
 }
 
+#define SIM_MUTATING_PHASE(_n)                                                 \
+  static void sim_phase_##_n(Gbuffer gbuf, Mbuffer mbuf, Usz height,           \
+                             Usz width) {                                      \
+    for (Usz iy = 0; iy < height; ++iy) {                                      \
+      Glyph* glyph_row = gbuf + iy * width;                                    \
+      for (Usz ix = 0; ix < width; ++ix) {                                     \
+        Glyph c = glyph_row[ix];                                               \
+        if (c == '.')                                                          \
+          continue;                                                            \
+        if (mbuffer_peek(mbuf, height, width, iy, ix) &                        \
+            (Mark_flag_lock | Mark_flag_sleep))                                \
+          continue;                                                            \
+        switch (c) { ORCA_OPERATORS(SIM_EXPAND_PHASE_##_n) }                   \
+      }                                                                        \
+    }                                                                          \
+  }
+
+SIM_MUTATING_PHASE(1)
+SIM_MUTATING_PHASE(2)
+
 void orca_run(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width) {
   mbuffer_clear(mbuf, height, width);
   sim_phase_0(gbuf, mbuf, height, width);
   sim_phase_1(gbuf, mbuf, height, width);
+  sim_phase_2(gbuf, mbuf, height, width);
 }