From 4ed135518b42d7d428bd432d50d3e8f9dcd259ed Mon Sep 17 00:00:00 2001
From: atse <atse@m-labs.hk>
Date: Fri, 2 Aug 2024 13:01:30 +0800
Subject: [PATCH] ctrl_panel: Use new locking mechanism from Kirdy

---
 pytec/pytec/gui/view/ctrl_panel.py | 88 ++++++++++++------------------
 1 file changed, 34 insertions(+), 54 deletions(-)

diff --git a/pytec/pytec/gui/view/ctrl_panel.py b/pytec/pytec/gui/view/ctrl_panel.py
index a742cd3..9d41c62 100644
--- a/pytec/pytec/gui/view/ctrl_panel.py
+++ b/pytec/pytec/gui/view/ctrl_panel.py
@@ -30,6 +30,11 @@ class CtrlPanel(QObject):
         self.trees_ui = trees_ui
         self.NUM_CHANNELS = len(trees_ui)
 
+        def _set_value_with_lock(self, value):
+            if not self.opts.get("lock"):
+                self.setValue(value)
+        Parameter.set_value_with_lock = _set_value_with_lock
+
         self.params = [
             Parameter.create(
                 name=f"Thermostat Channel {ch} Parameters",
@@ -47,7 +52,6 @@ class CtrlPanel(QObject):
             set_tree_label_tips(tree)
 
         for ch, param in enumerate(self.params):
-            self.params[ch].setValue = self._setValue
             param.sigTreeStateChanged.connect(sigTreeStateChanged_handle)
 
             for handle in sigActivated_handles[ch]:
@@ -74,32 +78,6 @@ class CtrlPanel(QObject):
                 font.setBold(True)
                 item.setFont(0, font)
 
-    def _setValue(self, value, blockSignal=None):
-        """
-        Implement 'lock' mechanism for Parameter Type
-
-        Modified from the source
-        """
-        try:
-            if blockSignal is not None:
-                self.sigValueChanged.disconnect(blockSignal)
-            value = self._interpretValue(value)
-            if fn.eq(self.opts["value"], value):
-                return value
-
-            if "lock" in self.opts.keys():
-                if self.opts["lock"]:
-                    return value
-            self.opts["value"] = value
-            self.sigValueChanged.emit(
-                self, value
-            )  # value might change after signal is received by tree item
-        finally:
-            if blockSignal is not None:
-                self.sigValueChanged.connect(blockSignal)
-
-        return self.opts["value"]
-
     def change_params_title(self, channel, path, title):
         self.params[channel].child(*path).setOpts(title=title)
 
@@ -108,57 +86,59 @@ class CtrlPanel(QObject):
         for settings in pid_settings:
             channel = settings["channel"]
             with QSignalBlocker(self.params[channel]):
-                self.params[channel].child("pid", "kp").setValue(
+                self.params[channel].child("pid", "kp").set_value_with_lock(
                     settings["parameters"]["kp"]
                 )
-                self.params[channel].child("pid", "ki").setValue(
+                self.params[channel].child("pid", "ki").set_value_with_lock(
                     settings["parameters"]["ki"]
                 )
-                self.params[channel].child("pid", "kd").setValue(
+                self.params[channel].child("pid", "kd").set_value_with_lock(
                     settings["parameters"]["kd"]
                 )
                 self.params[channel].child(
                     "pid", "pid_output_clamping", "output_min"
-                ).setValue(settings["parameters"]["output_min"])
+                ).set_value_with_lock(settings["parameters"]["output_min"])
                 self.params[channel].child(
                     "pid", "pid_output_clamping", "output_max"
-                ).setValue(settings["parameters"]["output_max"])
+                ).set_value_with_lock(settings["parameters"]["output_max"])
                 self.params[channel].child(
                     "output", "control_method", "target"
-                ).setValue(settings["target"])
+                ).set_value_with_lock(settings["target"])
 
     @pyqtSlot("QVariantList")
     def update_report(self, report_data):
         for settings in report_data:
             channel = settings["channel"]
             with QSignalBlocker(self.params[channel]):
-                self.params[channel].child("output", "control_method").setValue(
+                self.params[channel].child(
+                    "output", "control_method"
+                ).set_value_with_lock(
                     "temperature_pid" if settings["pid_engaged"] else "constant_current"
                 )
                 self.params[channel].child(
                     "output", "control_method", "i_set"
-                ).setValue(settings["i_set"])
+                ).set_value_with_lock(settings["i_set"])
                 if settings["temperature"] is not None:
-                    self.params[channel].child("readings", "temperature").setValue(
-                        settings["temperature"]
-                    )
+                    self.params[channel].child(
+                        "readings", "temperature"
+                    ).set_value_with_lock(settings["temperature"])
                     if settings["tec_i"] is not None:
-                        self.params[channel].child("readings", "tec_i").setValue(
-                            settings["tec_i"]
-                        )
+                        self.params[channel].child(
+                            "readings", "tec_i"
+                        ).set_value_with_lock(settings["tec_i"])
 
     @pyqtSlot("QVariantList")
     def update_thermistor(self, sh_data):
         for sh_param in sh_data:
             channel = sh_param["channel"]
             with QSignalBlocker(self.params[channel]):
-                self.params[channel].child("thermistor", "t0").setValue(
+                self.params[channel].child("thermistor", "t0").set_value_with_lock(
                     sh_param["params"]["t0"] - 273.15
                 )
-                self.params[channel].child("thermistor", "r0").setValue(
+                self.params[channel].child("thermistor", "r0").set_value_with_lock(
                     sh_param["params"]["r0"]
                 )
-                self.params[channel].child("thermistor", "b").setValue(
+                self.params[channel].child("thermistor", "b").set_value_with_lock(
                     sh_param["params"]["b"]
                 )
 
@@ -169,15 +149,15 @@ class CtrlPanel(QObject):
         for pwm_params in pwm_data:
             channel = pwm_params["channel"]
             with QSignalBlocker(self.params[channel]):
-                self.params[channel].child("output", "limits", "max_v").setValue(
-                    pwm_params["max_v"]["value"]
-                )
-                self.params[channel].child("output", "limits", "max_i_pos").setValue(
-                    pwm_params["max_i_pos"]["value"]
-                )
-                self.params[channel].child("output", "limits", "max_i_neg").setValue(
-                    pwm_params["max_i_neg"]["value"]
-                )
+                self.params[channel].child(
+                    "output", "limits", "max_v"
+                ).set_value_with_lock(pwm_params["max_v"]["value"])
+                self.params[channel].child(
+                    "output", "limits", "max_i_pos"
+                ).set_value_with_lock(pwm_params["max_i_pos"]["value"])
+                self.params[channel].child(
+                    "output", "limits", "max_i_neg"
+                ).set_value_with_lock(pwm_params["max_i_neg"]["value"])
 
             for limit in "max_i_pos", "max_i_neg", "max_v":
                 if pwm_params[limit]["value"] == 0.0:
@@ -189,6 +169,6 @@ class CtrlPanel(QObject):
         for postfilter_params in postfilter_data:
             channel = postfilter_params["channel"]
             with QSignalBlocker(self.params[channel]):
-                self.params[channel].child("thermistor", "rate").setValue(
+                self.params[channel].child("thermistor", "rate").set_value_with_lock(
                     postfilter_params["rate"]
                 )