SolverLog: Working solver start.

mesh
Pierre-Antoine Rouby 2023-06-19 16:48:38 +02:00
parent faffebe361
commit dd66faff45
3 changed files with 105 additions and 14 deletions

View File

@ -1,23 +1,28 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
import subprocess
from signal import SIGTERM, SIGSTOP, SIGCONT
from subprocess import Popen, PIPE, STDOUT, TimeoutExpired
from enum import Enum from enum import Enum
from Model.Except import NotImplementedMethodeError from Model.Except import NotImplementedMethodeError
class STATUS(Enum): class STATUS(Enum):
NOT_LAUNCHED = -1
STOPED = 0 STOPED = 0
RUNNING = 1 RUNNING = 1
FAILED = 2 FAILED = 2
CONF_ERROR = 3 CONF_ERROR = 3
KILLED = 4
PAUSED = 5
class AbstractSolver(object): class AbstractSolver(object):
def __init__(self, name): def __init__(self, name):
super(AbstractSolver, self).__init__() super(AbstractSolver, self).__init__()
self._current_process = None self._current_process = None
self._status = STATUS.STOPED self._status = STATUS.NOT_LAUNCHED
# Informations # Informations
self._type = "" self._type = ""
@ -32,6 +37,9 @@ class AbstractSolver(object):
self._cmd_solver = "" self._cmd_solver = ""
self._cmd_output = "" self._cmd_output = ""
self._process = None
self._output = None
def __str__(self): def __str__(self):
return f"{self._name} : {self._type} : {self._description}" return f"{self._name} : {self._type} : {self._description}"
@ -117,16 +125,79 @@ class AbstractSolver(object):
if self._cmd_solver == "": if self._cmd_solver == "":
return True return True
return False cmd = self._cmd_solver
cmd = cmd.replace("@path", self._path_solver).split()
def run_output_data_fomater(self, ): exe = cmd[0]
args = cmd[1:]
self._process.start(
exe, args,
)
self._process.readyRead.connect(self._data_ready)
return True
def run_output_data_fomater(self):
if self._cmd_output == "": if self._cmd_output == "":
return True return True
return False return False
def _data_ready(self):
s = self._process.readAll().data().decode()
if self._output is not None:
self._output.put(s)
def run(self, process, output_queue):
self._process = process
self._output = output_queue
if self.run_input_data_fomater():
if self.run_solver():
return self.run_output_data_fomater()
def kill(self): def kill(self):
if self._process is None:
return True
self._process.kill()
self._status = STATUS.KILLED
return True
def start(self):
if self._process is None:
return False return False
def readline(self): if self._status == STATUS.PAUSED:
return "" os.kill(self._process.pid(), SIGCONT)
self._status = STATUS.RUNNING
else:
self.run_solver()
return True
def pause(self):
if self._process is None:
return False
os.kill(self._process.pid(), SIGSTOP)
self._status = STATUS.PAUSED
return True
def stop(self):
if self._process is None:
return False
self._process.terminate()
self._status = STATUS.STOPED
return True
def wait(self):
if self._process is None:
return False
self._process.wait()
self._status = STATUS.STOPED
return True

View File

@ -12,6 +12,7 @@ class Mage(AbstractSolver):
self._cmd_solver = "@path @input -o @output" self._cmd_solver = "@path @input -o @output"
self._cmd_output = "" self._cmd_output = ""
@classmethod @classmethod
def default_parameters(cls): def default_parameters(cls):
lst = super(Mage, cls).default_parameters() lst = super(Mage, cls).default_parameters()
@ -44,6 +45,7 @@ class Mage(AbstractSolver):
return lst return lst
class Mage7(Mage): class Mage7(Mage):
def __init__(self, name): def __init__(self, name):
super(Mage7, self).__init__(name) super(Mage7, self).__init__(name)

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from queue import Queue
from tools import trace, timer from tools import trace, timer
from View.ASubWindow import ASubWindow, ASubMainWindow from View.ASubWindow import ASubWindow, ASubMainWindow
@ -12,7 +13,7 @@ from PyQt5.QtGui import (
from PyQt5.QtCore import ( from PyQt5.QtCore import (
Qt, QVariant, QAbstractTableModel, Qt, QVariant, QAbstractTableModel,
QCoreApplication, QModelIndex, pyqtSlot, QCoreApplication, QModelIndex, pyqtSlot,
QRect, QTimer, QRect, QTimer, QProcess,
) )
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
@ -20,6 +21,7 @@ from PyQt5.QtWidgets import (
QFileDialog, QTableView, QAbstractItemView, QFileDialog, QTableView, QAbstractItemView,
QUndoStack, QShortcut, QAction, QItemDelegate, QUndoStack, QShortcut, QAction, QItemDelegate,
QComboBox, QVBoxLayout, QHeaderView, QTabWidget, QComboBox, QVBoxLayout, QHeaderView, QTabWidget,
QTextEdit,
) )
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
@ -51,7 +53,6 @@ class SelectSolverWindow(ASubWindow, ListedSubWindow):
def setup_connections(self): def setup_connections(self):
self.find(QPushButton, "pushButton_run").clicked.connect(self.accept) self.find(QPushButton, "pushButton_run").clicked.connect(self.accept)
self.find(QPushButton, "pushButton_cancel").clicked.connect(self.reject) self.find(QPushButton, "pushButton_cancel").clicked.connect(self.reject)
@property @property
def solver(self): def solver(self):
return self._solver return self._solver
@ -77,6 +78,7 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
self._study = study self._study = study
self._config = config self._config = config
self._solver = solver self._solver = solver
self._process = QProcess(parent)
super(SolverLogWindow, self).__init__( super(SolverLogWindow, self).__init__(
name=self._title, ui="SolverLog", parent=parent name=self._title, ui="SolverLog", parent=parent
@ -88,6 +90,10 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
self.setup_connections() self.setup_connections()
self._alarm.start(500) self._alarm.start(500)
self._output = Queue()
self._log(f" *** Run solver {self._solver.name}")
self._solver.run(self._process, self._output)
def setup_action(self): def setup_action(self):
self.find(QAction, "action_start").setEnabled(False) self.find(QAction, "action_start").setEnabled(False)
@ -104,26 +110,38 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
self._alarm.timeout.connect(self.update) self._alarm.timeout.connect(self.update)
def _log(self, msg):
msg = msg.rsplit('\n')[0]
self.find(QTextEdit, "textEdit").append(msg)
def update(self): def update(self):
print("update") while self._output.qsize() != 0:
s = self._output.get()
print(s)
self._log(s)
def start(self): def start(self):
print("start") self._log(" *** Start")
self._solver.start()
self.find(QAction, "action_start").setEnabled(False) self.find(QAction, "action_start").setEnabled(False)
self.find(QAction, "action_pause").setEnabled(True) self.find(QAction, "action_pause").setEnabled(True)
self.find(QAction, "action_stop").setEnabled(True) self.find(QAction, "action_stop").setEnabled(True)
def pause(self): def pause(self):
print("pause") self._log(" *** Pause")
self._solver.pause()
self.find(QAction, "action_start").setEnabled(True) self.find(QAction, "action_start").setEnabled(True)
self.find(QAction, "action_pause").setEnabled(False) self.find(QAction, "action_pause").setEnabled(False)
self.find(QAction, "action_stop").setEnabled(True) self.find(QAction, "action_stop").setEnabled(True)
def stop(self): def stop(self):
print("stop") self._log(" *** Stop")
self._solver.kill()
self.find(QAction, "action_start").setEnabled(True) self.find(QAction, "action_start").setEnabled(True)
self.find(QAction, "action_pause").setEnabled(False) self.find(QAction, "action_pause").setEnabled(False)