Fixed signal tree and added progress bar in besim
This commit is contained in:
@@ -15,6 +15,14 @@ from bedit_gui.views.simulation_window import SimulationWindow
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
def _signal_tree_parts(signal: str) -> list[str]:
|
||||
if signal.startswith("der(") and signal.endswith(")"):
|
||||
parts = signal[4:-1].split(".")
|
||||
if len(parts) > 1:
|
||||
return [*parts[:-1], f"der({parts[-1]})"]
|
||||
return signal.split(".")
|
||||
|
||||
|
||||
class SimulationPlotController(QObject):
|
||||
def __init__(self, window: SimulationWindow, files: SimulationFileController) -> None:
|
||||
super().__init__(window)
|
||||
@@ -129,7 +137,7 @@ class SimulationPlotController(QObject):
|
||||
nodes: dict[tuple[str, ...], QTreeWidgetItem] = {}
|
||||
for signal in signals:
|
||||
parent = tree.invisibleRootItem()
|
||||
parts = signal.split(".")
|
||||
parts = _signal_tree_parts(signal)
|
||||
for depth, part in enumerate(parts, start=1):
|
||||
path = tuple(parts[:depth])
|
||||
item = nodes.get(path)
|
||||
|
||||
@@ -24,6 +24,7 @@ class SimulationRunController(QObject):
|
||||
run_completed = Signal(object)
|
||||
run_cancelled = Signal()
|
||||
run_failed = Signal(object)
|
||||
run_progress = Signal(int)
|
||||
simulation_state_changed = Signal()
|
||||
|
||||
def __init__(self, window: SimulationWindow, files: SimulationFileController, session_factory: SessionFactory = _create_session) -> None:
|
||||
@@ -34,6 +35,7 @@ class SimulationRunController(QObject):
|
||||
self.session: SimulationSession | None = None
|
||||
self._running = False
|
||||
self._reset_pending = False
|
||||
self.window.ui.progressBar.setValue(0)
|
||||
|
||||
window.ui.actionRun_Simulation.triggered.connect(self.start)
|
||||
window.ui.actionStop_Simulation.triggered.connect(self.stop)
|
||||
@@ -42,6 +44,7 @@ class SimulationRunController(QObject):
|
||||
self.run_completed.connect(self._completed)
|
||||
self.run_cancelled.connect(self._cancelled)
|
||||
self.run_failed.connect(self._failed)
|
||||
self.run_progress.connect(self.window.ui.progressBar.setValue)
|
||||
self._load_session()
|
||||
|
||||
@property
|
||||
@@ -54,6 +57,7 @@ class SimulationRunController(QObject):
|
||||
start_time = self.session.settings.start_time
|
||||
stop_time = self.session.current_end_time + self.session.settings.duration
|
||||
self._running = True
|
||||
self.window.ui.progressBar.setValue(0)
|
||||
self._update_actions()
|
||||
logger.info("Starting simulation from %s to %s", start_time, stop_time)
|
||||
Thread(target=self._run_worker, args=(self.session,), name="besim-run", daemon=True).start()
|
||||
@@ -78,13 +82,14 @@ class SimulationRunController(QObject):
|
||||
if self.session is None:
|
||||
return
|
||||
self.session.reset()
|
||||
self.window.ui.progressBar.setValue(0)
|
||||
self._store_session_state()
|
||||
logger.info("Reset simulation to start time %s", self.session.current_end_time)
|
||||
self._update_actions()
|
||||
|
||||
def _run_worker(self, session: SimulationSession) -> None:
|
||||
try:
|
||||
result = asyncio.run(session.run_next())
|
||||
result = asyncio.run(self._run_with_progress(session))
|
||||
except SimulationCancelledError:
|
||||
self.run_cancelled.emit()
|
||||
except (OSError, RuntimeError, TypeError, ValueError) as exc:
|
||||
@@ -92,9 +97,21 @@ class SimulationRunController(QObject):
|
||||
else:
|
||||
self.run_completed.emit(result)
|
||||
|
||||
async def _run_with_progress(self, session: SimulationSession) -> SimulationResult:
|
||||
task = asyncio.create_task(session.run_next())
|
||||
last_progress = -1
|
||||
while not task.done():
|
||||
progress = min(session.get_progress(), 99)
|
||||
if progress != last_progress:
|
||||
self.run_progress.emit(progress)
|
||||
last_progress = progress
|
||||
await asyncio.sleep(0.1)
|
||||
return await task
|
||||
|
||||
def _completed(self, result: SimulationResult) -> None:
|
||||
self._running = False
|
||||
self._store_session_state()
|
||||
self.window.ui.progressBar.setValue(100)
|
||||
logger.info("Simulation completed at time %s", self.session.current_end_time if self.session is not None else "unknown")
|
||||
if result.process_output.strip():
|
||||
logger.info("Simulation output:\n%s", result.process_output.strip())
|
||||
@@ -122,6 +139,7 @@ class SimulationRunController(QObject):
|
||||
root = self.files.root
|
||||
compiled = self.files.compiled_model
|
||||
self._reset_pending = False
|
||||
self.window.ui.progressBar.setValue(0)
|
||||
if root is None or compiled is None:
|
||||
self.session = None
|
||||
else:
|
||||
|
||||
@@ -27,6 +27,13 @@
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
@@ -35,7 +42,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>22</height>
|
||||
<height>19</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
|
||||
@@ -45,6 +45,9 @@ class SimulationSession:
|
||||
def is_running(self) -> bool:
|
||||
return self._simulation.is_running
|
||||
|
||||
def get_progress(self) -> int:
|
||||
return self._simulation.get_progress()
|
||||
|
||||
async def run_next(self) -> SimulationResult:
|
||||
start_time = self.settings.start_time
|
||||
stop_time = self.current_end_time + self.settings.duration
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"file_format_version": 1,
|
||||
"root_type": "simulation_root",
|
||||
"format_version": 1,
|
||||
"source_document": "/home/joppe/Projects/BEdit/untitled.bedit.json",
|
||||
"source_document": "untitled.bedit.json",
|
||||
"source_document_id": "3b6780c7-488b-471e-a784-392db7632090",
|
||||
"component": "50e6ef97-f686-4400-bc01-e5a352e8cc22",
|
||||
"component_path": "some_bondgraph",
|
||||
|
||||
Reference in New Issue
Block a user