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,55 +31,93 @@ class CustomSetting(BaseSetting): ...@@ -27,55 +31,93 @@ 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)}")
if force or self._current_value is None:
threading.Thread(target=fetch, daemon=True).start()
def _update_current_value(self, value):
print("aaaaaaaa" + value)
if self._current_value != value:
self._current_value = value
if self.widget:
self.widget.update_display()
def set_value(self, value): def set_value(self, value):
success = self._execute_set_command(value) def async_set():
if success: try:
self._current_value = value cmd = self._format_command(self.set_command, value)
self._update_widget() 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):
with subprocess.Popen( def async_execute():
cmd, with subprocess.Popen(
stdout=subprocess.PIPE, cmd,
stderr=subprocess.PIPE, stdout=subprocess.PIPE,
text=True, stderr=subprocess.PIPE,
shell=True, text=True,
bufsize=1 shell=True,
) as p: bufsize=1,
output = [] universal_newlines=True
) as p:
def process_line(line): output = []
line = line.strip()
if not line: def process_line(line):
return line = line.strip()
if line.startswith('CALLBACK:'): if not line:
self._handle_callback(line) return
elif line.startswith('NOTIFY:'):
self._handle_notify(line) if line.startswith('CALLBACK:'):
elif capture_output: self._handle_callback(line)
output.append(line) elif line.startswith('NOTIFY:'):
self._handle_notify(line)
while p.poll() is None: elif capture_output:
line = p.stdout.readline() output.append(line)
process_line(line)
while True:
for line in p.stdout.read().splitlines(): line = p.stdout.readline()
process_line(line) if not line and p.poll() is not None:
break
stderr = p.stderr.read().strip() if line:
GLib.idle_add(process_line, line)
if p.returncode != 0:
raise subprocess.CalledProcessError(p.returncode, cmd, stderr=stderr) if capture_output:
GLib.idle_add(lambda: self._process_command_output(''.join(output)))
return '\n'.join(output) if capture_output else ''
stderr = p.stderr.read()
if stderr:
GLib.idle_add(self.logger.error, f"Command error: {stderr}")
threading.Thread(target=async_execute, daemon=True).start()
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