From 469f63f74d4ee65db5288e4b69e1dd784eac0bf3 Mon Sep 17 00:00:00 2001
From: yufanyufan <yufanyufan@gmail.com>
Date: Tue, 21 Jul 2020 01:19:25 -0700
Subject: [PATCH] New DGUS UI var / definition syntax (#18718)

---
 Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp   |  4 ++++
 Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h     | 17 +++++++++++++++++
 .../extui/lib/dgus/origin/DGUSDisplayDef.cpp    |  7 +++++--
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp
index fec06290b4..c79d7e027e 100644
--- a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp
+++ b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp
@@ -107,6 +107,10 @@ void DGUSDisplay::WriteVariable(uint16_t adr, uint8_t value) {
   WriteVariable(adr, static_cast<const void*>(&value), sizeof(uint8_t));
 }
 
+void DGUSDisplay::WriteVariable(uint16_t adr, int8_t value) {
+  WriteVariable(adr, static_cast<const void*>(&value), sizeof(int8_t));
+}
+
 void DGUSDisplay::WriteVariable(uint16_t adr, long value) {
     union { long l; char lb[4]; } endian;
     char tmp[4];
diff --git a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h
index 54d68eacd2..7f63579888 100644
--- a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h
+++ b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h
@@ -57,8 +57,21 @@ public:
   static void WriteVariable(uint16_t adr, int16_t value);
   static void WriteVariable(uint16_t adr, uint16_t value);
   static void WriteVariable(uint16_t adr, uint8_t value);
+  static void WriteVariable(uint16_t adr, int8_t value);
   static void WriteVariable(uint16_t adr, long value);
 
+  // Utility functions for bridging ui_api and dbus
+  template<typename T, float(*Getter)(const T), T selector, typename WireType=uint16_t>
+  static void SetVariable(DGUS_VP_Variable &var) {
+    WriteVariable(var.VP, (WireType)Getter(selector));
+  }
+
+  template<typename T, void(*Setter)(const float V, const T), T selector>
+  static void GetVariable(DGUS_VP_Variable &var, void *val_ptr) {
+    uint16_t newvalue = swap16(*(uint16_t*)val_ptr);
+    Setter(newvalue, selector);
+  }
+
   // Until now I did not need to actively read from the display. That's why there is no ReadVariable
   // (I extensively use the auto upload of the display)
 
@@ -83,11 +96,15 @@ private:
   static void WritePGM(const char str[], uint8_t len);
   static void ProcessRx();
 
+  static inline uint16_t swap16(const uint16_t value) { return (value & 0xffU) << 8U | (value >> 8U); }
   static rx_datagram_state_t rx_datagram_state;
   static uint8_t rx_datagram_len;
   static bool Initialized, no_reentrance;
 };
 
+#define GET_VARIABLE(f, t, V...) (&DGUSDisplay::GetVariable<decltype(t), f, t, ##V>)
+#define SET_VARIABLE(f, t, V...) (&DGUSDisplay::SetVariable<decltype(t), f, t, ##V>)
+
 extern DGUSDisplay dgusdisplay;
 
 // compile-time x^y
diff --git a/Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.cpp
index 73ee1a62d3..616ff04d7c 100644
--- a/Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.cpp
+++ b/Marlin/src/lcd/extui/lib/dgus/origin/DGUSDisplayDef.cpp
@@ -35,10 +35,12 @@
 #include "../../../../../module/planner.h"
 
 #include "../../../../ultralcd.h"
+#include "../../../ui_api.h"
 
 #if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
   uint16_t distanceToMove = 10;
 #endif
+using namespace ExtUI;
 
 const uint16_t VPList_Boot[] PROGMEM = {
   VP_MARLIN_VERSION,
@@ -190,8 +192,9 @@ const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
 
   // Temperature Data
   #if HOTENDS >= 1
-    VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<0>),
-    VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, ScreenHandler.HandleTemperatureChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay),
+    VPHELPER(VP_T_E0_Is, nullptr, nullptr, SET_VARIABLE(getActualTemp_celsius, E0, long)),
+    VPHELPER(VP_T_E0_Set, nullptr, GET_VARIABLE(setTargetTemp_celsius, E0),
+                                   SET_VARIABLE(getTargetTemp_celsius, E0)),
     VPHELPER(VP_Flowrate_E0, nullptr, ScreenHandler.HandleFlowRateChanged, &ScreenHandler.DGUSLCD_SendWordValueToDisplay),
     VPHELPER(VP_EPos, &destination.e, nullptr, ScreenHandler.DGUSLCD_SendFloatAsLongValueToDisplay<2>),
     VPHELPER(VP_MOVE_E0, nullptr, &ScreenHandler.HandleManualExtrude, nullptr),