mirror of https://gitlab.com/pamhyr/pamhyr2
SolverLog: Working solver start.
parent
faffebe361
commit
dd66faff45
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue