From 00ba053c90ebbe6d430a48912bc3e00c8a1041c8 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <thinkyhead@users.noreply.github.com>
Date: Thu, 13 Feb 2020 23:39:27 -0600
Subject: [PATCH] Clean up host actions code (#16856)

---
 Marlin/src/feature/host_actions.cpp | 98 ++++++++++++++++-------------
 Marlin/src/feature/host_actions.h   | 10 +--
 Marlin/src/feature/pause.cpp        | 41 +++++-------
 Marlin/src/feature/pause.h          | 17 ++---
 Marlin/src/feature/runout.cpp       |  6 +-
 Marlin/src/gcode/host/M876.cpp      |  2 +
 6 files changed, 86 insertions(+), 88 deletions(-)

diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp
index 3633a7b75f..c9e87a6237 100644
--- a/Marlin/src/feature/host_actions.cpp
+++ b/Marlin/src/feature/host_actions.cpp
@@ -84,70 +84,78 @@ void host_action(const char * const pstr, const bool eol) {
     if (eol) SERIAL_EOL();
   }
 
-  void host_action_prompt_plus(const char * const ptype, const char * const pstr, const bool eol=true) {
+  void host_action_prompt_plus(const char * const ptype, const char * const pstr, const char extra_char='\0') {
     host_action_prompt(ptype, false);
     SERIAL_CHAR(' ');
     serialprintPGM(pstr);
-    if (eol) SERIAL_EOL();
+    if (extra_char != '\0') SERIAL_CHAR(extra_char);
+    SERIAL_EOL();
+  }
+  void host_action_prompt_begin(const PromptReason reason, const char * const pstr, const char extra_char/*='\0'*/) {
+    host_action_prompt_end();
+    host_prompt_reason = reason;
+    host_action_prompt_plus(PSTR("begin"), pstr, extra_char);
   }
-  void host_action_prompt_begin(const char * const pstr, const bool eol/*=true*/) { host_action_prompt_plus(PSTR("begin"), pstr, eol); }
   void host_action_prompt_button(const char * const pstr) { host_action_prompt_plus(PSTR("button"), pstr); }
   void host_action_prompt_end() { host_action_prompt(PSTR("end")); }
   void host_action_prompt_show() { host_action_prompt(PSTR("show")); }
-  void host_prompt_do(const PromptReason reason, const char * const pstr, const char * const pbtn/*=nullptr*/) {
-    host_prompt_reason = reason;
-    host_action_prompt_end();
-    host_action_prompt_begin(pstr);
-    if (pbtn) host_action_prompt_button(pbtn);
+  void host_prompt_do(const PromptReason reason, const char * const pstr, const char * const btn1/*=nullptr*/, const char * const btn2/*=nullptr*/) {
+    host_action_prompt_begin(reason, pstr);
+    if (btn1) host_action_prompt_button(btn1);
+    if (btn2) host_action_prompt_button(btn2);
     host_action_prompt_show();
   }
 
-  inline void say_m876_response(const char * const pstr) {
-    SERIAL_ECHOPGM("M876 Responding PROMPT_");
-    serialprintPGM(pstr);
-    SERIAL_EOL();
+  void filament_load_host_prompt() {
+    const bool disable_to_continue = (false
+      #if HAS_FILAMENT_SENSOR
+        || runout.filament_ran_out
+      #endif
+    );
+    host_prompt_do(PROMPT_FILAMENT_RUNOUT, PSTR("Paused"), PSTR("PurgeMore"),
+      disable_to_continue ? PSTR("DisableRunout") : CONTINUE_STR
+    );
   }
 
+  //
+  // Handle responses from the host, such as:
+  //  - Filament runout responses: Purge More, Continue
+  //  - General "Continue" response
+  //  - Resume Print response
+  //  - Dismissal of info
+  //
   void host_response_handler(const uint8_t response) {
     #ifdef DEBUG_HOST_ACTIONS
-      SERIAL_ECHOLNPAIR("M876 Handle Reason: ", host_prompt_reason);
-      SERIAL_ECHOLNPAIR("M876 Handle Response: ", response);
+      static const char m876_prefix[] PROGMEM = "M876 Handle Re";
+      serialprintPGM(m876_prefix); SERIAL_ECHOLNPAIR("ason: ", host_prompt_reason);
+      serialprintPGM(m876_prefix); SERIAL_ECHOLNPAIR("sponse: ", response);
     #endif
     const char *msg = PSTR("UNKNOWN STATE");
     const PromptReason hpr = host_prompt_reason;
-    host_prompt_reason = PROMPT_NOT_DEFINED;
+    host_prompt_reason = PROMPT_NOT_DEFINED;  // Reset now ahead of logic
     switch (hpr) {
       case PROMPT_FILAMENT_RUNOUT:
         msg = PSTR("FILAMENT_RUNOUT");
-        if (response == 0) {
-          #if ENABLED(ADVANCED_PAUSE_FEATURE)
-            pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE;
-          #endif
-          host_action_prompt_end();   // Close current prompt
-          host_action_prompt_begin(PSTR("Paused"));
-          host_action_prompt_button(PSTR("Purge More"));
-          if (false
-            #if HAS_FILAMENT_SENSOR
-              || runout.filament_ran_out
+        switch (response) {
+
+          case 0: // "Purge More" button
+            #if HAS_LCD_MENU && ENABLED(ADVANCED_PAUSE_FEATURE)
+              pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE;  // Simulate menu selection (menu exits, doesn't extrude more)
             #endif
-          )
-            host_action_prompt_button(PSTR("DisableRunout"));
-          else {
-            host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
-            host_action_prompt_button(CONTINUE_STR);
-          }
-          host_action_prompt_show();
-        }
-        else if (response == 1) {
-          #if HAS_FILAMENT_SENSOR
-            if (runout.filament_ran_out) {
-              runout.enabled = false;
-              runout.reset();
-            }
-          #endif
-          #if ENABLED(ADVANCED_PAUSE_FEATURE)
-            pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT;
-          #endif
+            filament_load_host_prompt();                          // Initiate another host prompt. (NOTE: The loop in load_filament may also do this!)
+            break;
+
+          case 1: // "Continue" / "Disable Runout" button
+            #if HAS_LCD_MENU && ENABLED(ADVANCED_PAUSE_FEATURE)
+              pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT;  // Simulate menu selection
+            #endif
+            #if HAS_FILAMENT_SENSOR
+              if (runout.filament_ran_out) {                      // Disable a triggered sensor
+                runout.enabled = false;
+                runout.reset();
+              }
+            #endif
+            break;
         }
         break;
       case PROMPT_USER_CONTINUE:
@@ -168,7 +176,9 @@ void host_action(const char * const pstr, const bool eol) {
         break;
       default: break;
     }
-    say_m876_response(msg);
+    SERIAL_ECHOPGM("M876 Responding PROMPT_");
+    serialprintPGM(msg);
+    SERIAL_EOL();
   }
 
 #endif // HOST_PROMPT_SUPPORT
diff --git a/Marlin/src/feature/host_actions.h b/Marlin/src/feature/host_actions.h
index 939f0be2de..d90a21b1f1 100644
--- a/Marlin/src/feature/host_actions.h
+++ b/Marlin/src/feature/host_actions.h
@@ -61,13 +61,15 @@ void host_action(const char * const pstr, const bool eol=true);
 
   void host_response_handler(const uint8_t response);
   void host_action_notify(const char * const message);
-  void host_action_prompt_begin(const char * const pstr, const bool eol=true);
+  void host_action_prompt_begin(const PromptReason reason, const char * const pstr, const char extra_char='\0');
   void host_action_prompt_button(const char * const pstr);
   void host_action_prompt_end();
   void host_action_prompt_show();
-  void host_prompt_do(const PromptReason type, const char * const pstr, const char * const pbtn=nullptr);
-  inline void host_prompt_open(const PromptReason reason, const char * const pstr, const char * const pbtn=nullptr) {
-    if (host_prompt_reason == PROMPT_NOT_DEFINED) host_prompt_do(reason, pstr, pbtn);
+  void host_prompt_do(const PromptReason reason, const char * const pstr, const char * const btn1=nullptr, const char * const btn2=nullptr);
+  inline void host_prompt_open(const PromptReason reason, const char * const pstr, const char * const btn1=nullptr, const char * const btn2=nullptr) {
+    if (host_prompt_reason == PROMPT_NOT_DEFINED) host_prompt_do(reason, pstr, btn1, btn2);
   }
 
+  void filament_load_host_prompt();
+
 #endif
diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp
index 0bf8fe4b98..5a7cde2046 100644
--- a/Marlin/src/feature/pause.cpp
+++ b/Marlin/src/feature/pause.cpp
@@ -67,9 +67,10 @@
 
 static xyze_pos_t resume_position;
 
-PauseMode pause_mode = PAUSE_MODE_PAUSE_PRINT;
-
-PauseMenuResponse pause_menu_response;
+#if HAS_LCD_MENU
+  PauseMenuResponse pause_menu_response;
+  PauseMode pause_mode = PAUSE_MODE_PAUSE_PRINT;
+#endif
 
 fil_change_settings_t fc_settings[EXTRUDERS];
 
@@ -85,7 +86,11 @@ fil_change_settings_t fc_settings[EXTRUDERS];
 
 #if HAS_BUZZER
   static void filament_change_beep(const int8_t max_beep_count, const bool init=false) {
-    if (pause_mode == PAUSE_MODE_PAUSE_PRINT) return;
+
+    #if HAS_LCD_MENU
+      if (pause_mode == PAUSE_MODE_PAUSE_PRINT) return;
+    #endif
+
     static millis_t next_buzz = 0;
     static int8_t runout_beep = 0;
 
@@ -186,11 +191,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
           + active_extruder
         #endif
       ;
-      host_prompt_reason = PROMPT_USER_CONTINUE;
-      host_action_prompt_end();
-      host_action_prompt_begin(PSTR("Load Filament T"), false);
-      SERIAL_CHAR(tool);
-      SERIAL_EOL();
+      host_action_prompt_begin(PROMPT_USER_CONTINUE, PSTR("Load Filament T"), tool);
       host_action_prompt_button(CONTINUE_STR);
       host_action_prompt_show();
     #endif
@@ -247,10 +248,10 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
 
     wait_for_user = true;
     #if ENABLED(HOST_PROMPT_SUPPORT)
-      host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purge Running..."), CONTINUE_STR);
+      host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purging..."), CONTINUE_STR);
     #endif
     #if ENABLED(EXTENSIBLE_UI)
-      ExtUI::onUserConfirmRequired_P(PSTR("Filament Purge Running..."));
+      ExtUI::onUserConfirmRequired_P(PSTR("Filament Purging..."));
     #endif
     for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count)
       do_pause_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
@@ -269,27 +270,13 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
         do_pause_e_move(purge_length, ADVANCED_PAUSE_PURGE_FEEDRATE);
       }
 
-      // Show "Purge More" / "Resume" menu and wait for reply
       #if ENABLED(HOST_PROMPT_SUPPORT)
-        host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
-        host_action_prompt_end();   // Close current prompt
-        host_action_prompt_begin(PSTR("Paused"));
-        host_action_prompt_button(PSTR("PurgeMore"));
-        if (false
-          #if HAS_FILAMENT_SENSOR
-            || runout.filament_ran_out
-          #endif
-        )
-          host_action_prompt_button(PSTR("DisableRunout"));
-        else {
-          host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
-          host_action_prompt_button(CONTINUE_STR);
-        }
-        host_action_prompt_show();
+        filament_load_host_prompt();  // Initiate another host prompt. (NOTE: host_response_handler may also do this!)
       #endif
 
       #if HAS_LCD_MENU
         if (show_lcd) {
+          // Show "Purge More" / "Resume" menu and wait for reply
           KEEPALIVE_STATE(PAUSED_FOR_USER);
           wait_for_user = false;
           lcd_pause_show_message(PAUSE_MESSAGE_OPTION);
diff --git a/Marlin/src/feature/pause.h b/Marlin/src/feature/pause.h
index f88dd349c5..5ac67a565c 100644
--- a/Marlin/src/feature/pause.h
+++ b/Marlin/src/feature/pause.h
@@ -59,14 +59,15 @@ enum PauseMessage : char {
   PAUSE_MESSAGE_HEATING
 };
 
-enum PauseMenuResponse : char {
-  PAUSE_RESPONSE_WAIT_FOR,
-  PAUSE_RESPONSE_EXTRUDE_MORE,
-  PAUSE_RESPONSE_RESUME_PRINT
-};
-
-extern PauseMode pause_mode;
-extern PauseMenuResponse pause_menu_response;
+#if HAS_LCD_MENU
+  enum PauseMenuResponse : char {
+    PAUSE_RESPONSE_WAIT_FOR,
+    PAUSE_RESPONSE_EXTRUDE_MORE,
+    PAUSE_RESPONSE_RESUME_PRINT
+  };
+  extern PauseMenuResponse pause_menu_response;
+  extern PauseMode pause_mode;
+#endif
 
 extern fil_change_settings_t fc_settings[EXTRUDERS];
 
diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp
index 3acda2f7a2..3cf81303dd 100644
--- a/Marlin/src/feature/runout.cpp
+++ b/Marlin/src/feature/runout.cpp
@@ -92,11 +92,7 @@ void event_filament_runout() {
 
   //action:out_of_filament
   #if ENABLED(HOST_PROMPT_SUPPORT)
-    host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
-    host_action_prompt_end();
-    host_action_prompt_begin(PSTR("FilamentRunout T"), false);
-    SERIAL_CHAR(tool);
-    SERIAL_EOL();
+    host_action_prompt_begin(PROMPT_FILAMENT_RUNOUT, PSTR("FilamentRunout T"), tool);
     host_action_prompt_show();
   #endif
 
diff --git a/Marlin/src/gcode/host/M876.cpp b/Marlin/src/gcode/host/M876.cpp
index 8e83185e02..fe0ca1541a 100644
--- a/Marlin/src/gcode/host/M876.cpp
+++ b/Marlin/src/gcode/host/M876.cpp
@@ -31,7 +31,9 @@
  * M876: Handle Prompt Response
  */
 void GcodeSuite::M876() {
+
   if (parser.seenval('S')) host_response_handler((uint8_t)parser.value_int());
+
 }
 
 #endif // HOST_PROMPT_SUPPORT && !EMERGENCY_PARSER