From 63cbfc49a005f01c0cf22f720e60385aceeb1dff Mon Sep 17 00:00:00 2001
From: Oscar Gustafsson <oscar.gustafsson@gmail.com>
Date: Thu, 18 May 2023 17:23:50 +0200
Subject: [PATCH] Add menu entry for port access statistics

---
 b_asic/scheduler_gui/main_window.py    | 50 +++++++++++++++++++++-----
 b_asic/scheduler_gui/main_window.ui    | 12 +++++++
 b_asic/scheduler_gui/ui_main_window.py | 14 ++++++--
 3 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/b_asic/scheduler_gui/main_window.py b/b_asic/scheduler_gui/main_window.py
index 5f729f36..4233cd17 100644
--- a/b_asic/scheduler_gui/main_window.py
+++ b/b_asic/scheduler_gui/main_window.py
@@ -123,6 +123,8 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         self._show_incorrect_execution_time = True
         self._show_port_numbers = True
         self._execution_time_for_variables = None
+        self._ports_accesses_for_storage = None
+
         # Recent files
         self._max_recent_files = 4
         self._recent_files_actions: List[QAction] = []
@@ -164,9 +166,9 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         self.action_view_variables.triggered.connect(
             self._show_execution_times_for_variables
         )
-        # self.action_view_port_accesses.triggered.connect(
-        #     self._show_ports_accesses_for_storage
-        # )
+        self.action_view_port_accesses.triggered.connect(
+            self._show_ports_accesses_for_storage
+        )
         self.actionZoom_to_fit.setIcon(get_icon('zoom-to-fit'))
         self.actionZoom_to_fit.triggered.connect(self._zoom_to_fit)
         self.actionToggle_full_screen.setIcon(get_icon('full-screen'))
@@ -415,6 +417,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
             self.update_statusbar("Closed schedule")
             self._toggle_file_loaded(False)
             self.action_view_variables.setEnabled(False)
+            self.action_view_port_accesses.setEnabled(False)
             self.menu_view_execution_times.setEnabled(False)
 
     @Slot()
@@ -620,6 +623,10 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
                 settings.setValue("scheduler/hide_exit_dialog", checkbox.isChecked())
             self._write_settings()
             log.info(f"Exit: {os.path.basename(__file__)}")
+            if self._ports_accesses_for_storage:
+                self._ports_accesses_for_storage.close()
+            if self._execution_time_for_variables:
+                self._execution_time_for_variables.close()
             event.accept()
         else:
             event.ignore()
@@ -661,6 +668,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         self.info_table_fill_schedule(self._schedule)
         self._update_operation_types()
         self.action_view_variables.setEnabled(True)
+        self.action_view_port_accesses.setEnabled(True)
         self.update_statusbar(self.tr("Schedule loaded successfully"))
 
     def _redraw_all(self) -> None:
@@ -845,21 +853,45 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
 
     def _show_execution_times_for_variables(self):
         self._execution_time_for_variables = MPLWindow("Execution times for variables")
-        self._schedule.get_memory_variables().plot(
-            self._execution_time_for_variables.axes, allow_excessive_lifetimes=True
+        self._execution_time_for_variables.finished.connect(
+            self._execution_times_for_variables_closed
         )
+        self._update_execution_times_for_variables()
         self._execution_time_for_variables.show()
 
+    def _update_execution_times_for_variables(self):
+        if self._execution_time_for_variables:
+            self._execution_time_for_variables.axes.clear()
+            self._schedule.get_memory_variables().plot(
+                self._execution_time_for_variables.axes, allow_excessive_lifetimes=True
+            )
+
+    @Slot()
+    def _execution_times_for_variables_closed(self):
+        self._execution_time_for_variables = None
+
     def _show_ports_accesses_for_storage(self):
         self._ports_accesses_for_storage = MPLWindow(
             "Port accesses for storage", subplots=(3, 1)
         )
-        mem_vars = self._schedule.get_memory_variables()
-        _, mem_vars = mem_vars.split_on_length()
-
-        mem_vars.plot_port_accesses(self._ports_accesses_for_storage.axes)
+        self._ports_accesses_for_storage.finished.connect(
+            self._ports_accesses_for_storage_closed
+        )
+        self._update_ports_accesses_for_storage()
         self._ports_accesses_for_storage.show()
 
+    def _update_ports_accesses_for_storage(self) -> None:
+        if self._ports_accesses_for_storage:
+            for ax in self._ports_accesses_for_storage.axes:
+                ax.clear()
+            mem_vars = self._schedule.get_memory_variables()
+            _, mem_vars = mem_vars.split_on_length()
+            mem_vars.plot_port_accesses(self._ports_accesses_for_storage.axes)
+
+    @Slot()
+    def _ports_accesses_for_storage_closed(self) -> None:
+        self._ports_accesses_for_storage = None
+
     def _update_recent_file_list(self):
         settings = QSettings()
 
diff --git a/b_asic/scheduler_gui/main_window.ui b/b_asic/scheduler_gui/main_window.ui
index 8f0dab65..beff9307 100644
--- a/b_asic/scheduler_gui/main_window.ui
+++ b/b_asic/scheduler_gui/main_window.ui
@@ -244,6 +244,7 @@
     <addaction name="separator"/>
     <addaction name="actionPlot_schedule"/>
     <addaction name="action_view_variables"/>
+    <addaction name="action_view_port_accesses"/>
     <addaction name="menu_view_execution_times"/>
     <addaction name="separator"/>
     <addaction name="actionZoom_to_fit"/>
@@ -464,6 +465,17 @@
     <string>View all variables</string>
    </property>
   </action>
+  <action name="action_view_port_accesses">
+   <property name="text">
+    <string>View port access statistics</string>
+   </property>
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="toolTip">
+    <string>View port access statistics for storage</string>
+   </property>
+  </action>
   <action name="actionUndo">
    <property name="enabled">
     <bool>false</bool>
diff --git a/b_asic/scheduler_gui/ui_main_window.py b/b_asic/scheduler_gui/ui_main_window.py
index 15e768a0..4a48600a 100644
--- a/b_asic/scheduler_gui/ui_main_window.py
+++ b/b_asic/scheduler_gui/ui_main_window.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 # Form implementation generated from reading ui file '.\main_window.ui'
 #
 # Created by: PyQt5 UI code generator 5.15.7
@@ -11,7 +9,7 @@
 from qtpy import QtCore, QtGui, QtWidgets
 
 
-class Ui_MainWindow(object):
+class Ui_MainWindow:
     def setupUi(self, MainWindow):
         MainWindow.setObjectName("MainWindow")
         MainWindow.resize(800, 600)
@@ -209,6 +207,9 @@ class Ui_MainWindow(object):
         self.action_view_variables = QtWidgets.QAction(MainWindow)
         self.action_view_variables.setEnabled(False)
         self.action_view_variables.setObjectName("action_view_variables")
+        self.action_view_port_accesses = QtWidgets.QAction(MainWindow)
+        self.action_view_port_accesses.setEnabled(False)
+        self.action_view_port_accesses.setObjectName("action_view_port_accesses")
         self.actionUndo = QtWidgets.QAction(MainWindow)
         self.actionUndo.setEnabled(False)
         self.actionUndo.setObjectName("actionUndo")
@@ -267,6 +268,7 @@ class Ui_MainWindow(object):
         self.menuView.addSeparator()
         self.menuView.addAction(self.actionPlot_schedule)
         self.menuView.addAction(self.action_view_variables)
+        self.menuView.addAction(self.action_view_port_accesses)
         self.menuView.addAction(self.menu_view_execution_times.menuAction())
         self.menuView.addSeparator()
         self.menuView.addAction(self.actionZoom_to_fit)
@@ -370,6 +372,12 @@ class Ui_MainWindow(object):
         self.action_view_variables.setToolTip(
             _translate("MainWindow", "View all variables")
         )
+        self.action_view_port_accesses.setText(
+            _translate("MainWindow", "View port access statistics")
+        )
+        self.action_view_port_accesses.setToolTip(
+            _translate("MainWindow", "View port access statistics for storage")
+        )
         self.actionUndo.setText(_translate("MainWindow", "Undo"))
         self.actionUndo.setShortcut(_translate("MainWindow", "Ctrl+Z"))
         self.actionRedo.setText(_translate("MainWindow", "Redo"))
-- 
GitLab