Commit 7a4ec7e2 authored by Roman Alifanov's avatar Roman Alifanov

set and get moved to a separated thread

parent 38cbb2ba
from gi.repository import GLib
from .base import BaseSetting from .base import BaseSetting
from .widgets import WidgetFactory from .widgets import WidgetFactory
import threading
import logging import logging
import subprocess import subprocess
import ast import ast
...@@ -16,6 +19,7 @@ class CustomSetting(BaseSetting): ...@@ -16,6 +19,7 @@ class CustomSetting(BaseSetting):
self.set_command = setting_data.get('set_command') self.set_command = setting_data.get('set_command')
super().__init__(setting_data, module) super().__init__(setting_data, module)
self._async_fetch_value()
def create_row(self): def create_row(self):
try: try:
...@@ -27,28 +31,58 @@ class CustomSetting(BaseSetting): ...@@ -27,28 +31,58 @@ class CustomSetting(BaseSetting):
self.logger.error(f"Error creating row: {str(e)}") self.logger.error(f"Error creating row: {str(e)}")
return None return None
def get_value(self): def _async_fetch_value(self, force=False):
if self._current_value is None: def fetch():
self._current_value = self._execute_get_command() try:
return self._current_value new_value = self._execute_get_command()
if force or new_value != self._current_value:
GLib.idle_add(self._update_current_value, new_value)
except Exception as e:
self.logger.error(f"Error fetching value: {str(e)}")
def set_value(self, value): if force or self._current_value is None:
success = self._execute_set_command(value) threading.Thread(target=fetch, daemon=True).start()
if success:
def _update_current_value(self, value):
print("aaaaaaaa" + value)
if self._current_value != value:
self._current_value = value self._current_value = value
self._update_widget() if self.widget:
self.widget.update_display()
def set_value(self, value):
def async_set():
try:
cmd = self._format_command(self.set_command, value)
self._execute_command(cmd, capture_output=False)
GLib.idle_add(self._async_fetch_value, True)
except Exception as e:
self.logger.error(f"Set value error: {str(e)}")
threading.Thread(target=async_set, daemon=True).start()
def get_range(self): def get_range(self):
return self._execute_get_range_command() if not self.get_range_command:
return None
try:
cmd = self._format_command(self.get_range_command)
output = subprocess.check_output(cmd, shell=True, text=True).strip()
return ast.literal_eval(output)
except subprocess.CalledProcessError as e:
self.logger.error(f"Get range command failed: {e.stderr}")
return None
def _execute_command(self, cmd, capture_output=True): def _execute_command(self, cmd, capture_output=True):
def async_execute():
with subprocess.Popen( with subprocess.Popen(
cmd, cmd,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
text=True, text=True,
shell=True, shell=True,
bufsize=1 bufsize=1,
universal_newlines=True
) as p: ) as p:
output = [] output = []
...@@ -56,6 +90,7 @@ class CustomSetting(BaseSetting): ...@@ -56,6 +90,7 @@ class CustomSetting(BaseSetting):
line = line.strip() line = line.strip()
if not line: if not line:
return return
if line.startswith('CALLBACK:'): if line.startswith('CALLBACK:'):
self._handle_callback(line) self._handle_callback(line)
elif line.startswith('NOTIFY:'): elif line.startswith('NOTIFY:'):
...@@ -63,19 +98,26 @@ class CustomSetting(BaseSetting): ...@@ -63,19 +98,26 @@ class CustomSetting(BaseSetting):
elif capture_output: elif capture_output:
output.append(line) output.append(line)
while p.poll() is None: while True:
line = p.stdout.readline() line = p.stdout.readline()
process_line(line) if not line and p.poll() is not None:
break
if line:
GLib.idle_add(process_line, line)
for line in p.stdout.read().splitlines(): if capture_output:
process_line(line) GLib.idle_add(lambda: self._process_command_output(''.join(output)))
stderr = p.stderr.read().strip() stderr = p.stderr.read()
if stderr:
GLib.idle_add(self.logger.error, f"Command error: {stderr}")
if p.returncode != 0: threading.Thread(target=async_execute, daemon=True).start()
raise subprocess.CalledProcessError(p.returncode, cmd, stderr=stderr)
return '\n'.join(output) if capture_output else '' def _process_command_output(self, output):
self._current_value = output.strip()
if self.widget:
self.widget.update_display()
def _execute_get_command(self): def _execute_get_command(self):
if not self.get_command: if not self.get_command:
...@@ -152,10 +194,12 @@ class CustomSetting(BaseSetting): ...@@ -152,10 +194,12 @@ class CustomSetting(BaseSetting):
@property @property
def current_value(self): def current_value(self):
return self.get_value() return self._current_value
def _get_backend_value(self): def _get_backend_value(self, force=False):
return self.get_value() if force:
self._async_fetch_value(force=True)
return self._current_value
def _set_backend_value(self, value): def _set_backend_value(self, value):
self.set_value(value) self.set_value(value)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment