Skip to content
Snippets Groups Projects
Commit abf397e3 authored by Johannes Kung's avatar Johannes Kung
Browse files

Merge branch '12-see-changes-when-running-cpu' into 'main'

can now toggle if all values or only clock count should be updated each tick

Closes #12

See merge request !7
parents 968dd133 743e412b
No related branches found
No related tags found
1 merge request!7can now toggle if all values or only clock count should be updated each tick
Pipeline #131483 passed
......@@ -116,6 +116,14 @@ class GUI(QMainWindow):
# Signal to tell gui when cpu has halted
self.cpu_tick_signal.connect(self.handleCpuTick)
# Used to set if all values in the gui should be updated each tick
# or only the clock counter
self.update_all_values = False
# Used to set the update delay
# Useful when watching the values being updated while running
self.update_delay = 0.00
# Used to lock some actions in ui when cpu is running in another thread
# Using the cpu's internal status directly could case problems
self.cpu_running = False
......@@ -207,9 +215,22 @@ class GUI(QMainWindow):
self.breakpoint_action.setStatusTip("Open breakpoint window.")
self.breakpoint_action.triggered.connect(self.openBreakpointWindow)
# Create 'update value' window button
self.update_value_action = QAction("Update values while running", self, checkable=True)
self.update_value_action.setChecked(False)
self.update_value_action.setStatusTip("Toggle value updates while running.")
self.update_value_action.triggered.connect(self.toggle_value_update_on_run)
# Create 'set delay' window button
self.set_delay_action = QAction("Set update delay", self)
self.set_delay_action.setStatusTip("Sets the delay between each update when the cpu is running.")
self.set_delay_action.triggered.connect(self.set_update_delay)
# Create Tools menu for tool actions actions
tools_menu = menu.addMenu("&Tools")
tools_menu.addAction(self.breakpoint_action)
tools_menu.addAction(self.update_value_action)
tools_menu.addAction(self.set_delay_action)
# Add run button on toolbar
arrow_icon = self.style().standardIcon(QStyle.SP_MediaPlay)
......@@ -434,9 +455,8 @@ class GUI(QMainWindow):
self.cpu_running = True
self.setDisabledWhenRunning(True)
self.cpu.unstop()
simulation_thread = RunThread(self.cpu, self.cpu_tick_signal, False, steps)
simulation_thread = RunThread(self.cpu, self.cpu_tick_signal, self.update_delay, False, steps)
self.threadpool.start(simulation_thread)
# self.updateCpuListeners()
def runToolBarButtonClick(self) -> None:
"""
......@@ -451,9 +471,8 @@ class GUI(QMainWindow):
self.cpu_running = True
self.setDisabledWhenRunning(True)
self.cpu.unstop()
simulation_thread = RunThread(self.cpu, self.cpu_tick_signal)
simulation_thread = RunThread(self.cpu, self.cpu_tick_signal, self.update_delay)
self.threadpool.start(simulation_thread)
self.updateCpuListeners()
@Slot(int)
def handleCpuTick(self, steps: int) -> None:
......@@ -465,11 +484,13 @@ class GUI(QMainWindow):
# Update cpu clock counter every tick
self.updateCpuClockCycle()
if self.update_all_values:
self.updateCpuListeners()
# If a breakpoint halted the program, inform the user
# Update other visuals and set the cpu to the correct state (not running)
if self.cpu.breakpoint_reached:
self.messageBox("Reached breakpoint: " + self.cpu.last_breakpoint.__str__())
self.updateCpuListeners()
# When the CPU is done we want to inform the user and update visuals
if self.cpu.should_halt():
......@@ -478,7 +499,6 @@ class GUI(QMainWindow):
# the message box after every small step
if steps > self.HALT_MESSAGE_THRESHOLD:
self.messageBox("The processor halted.")
self.updateCpuListeners()
# A signal of 0 steps signifies end of execution, i.e. the CPU has
# halted or run the specified amount of ticks
......@@ -486,13 +506,13 @@ class GUI(QMainWindow):
if steps == 0:
self.cpu_running = False
self.setDisabledWhenRunning(False)
self.updateCpuListeners()
def stopToolBarButtonClick(self) -> None:
"""
Tells the cpu to stop. It will then stop at an appropriate in its own thread.
"""
self.cpu.stop()
self.updateCpuListeners()
def folderSaveDialog(self) -> str:
"""
......@@ -757,6 +777,20 @@ class GUI(QMainWindow):
self.breakpoint_window = BreakpointWindow(self.cpu)
self.breakpoint_window.show()
def toggle_value_update_on_run(self):
"""
Toggles whether all values or only clock cycle is being updated each tick.
"""
self.update_all_values = not self.update_all_values
def set_update_delay(self):
"""
Sets the update delay for the visual updates while the cpu is running.
"""
delay, ok = QInputDialog.getDouble(self, "Input Dialog", "Enter a float value:", decimals=5)
if ok:
self.update_delay = delay
def showPortNamesBarButtonClick(self):
"""
Toggles showing port names in the graphics scene.
......
......@@ -2,8 +2,6 @@ import time
from qtpy.QtCore import QRunnable
CPU_TICK_DELAY = 0.0000001
class RunThread(QRunnable):
"""
This class is used to run the simulated cpu several ticks or continuously on
......@@ -15,25 +13,26 @@ class RunThread(QRunnable):
has halted.
"""
def __init__(self, cpu, signal, run_continuously=True, steps=0):
def __init__(self, cpu, signal, delay: float, run_continuously=True, steps=0):
super().__init__()
self.cpu = cpu
self.signal = signal
self.run_continuously = run_continuously
self.steps = steps
self.delay = delay
def run(self):
if self.run_continuously:
while not self.cpu.should_halt() and not self.cpu.is_stopped:
self.cpu.do_tick()
self.signal.emit(1)
time.sleep(CPU_TICK_DELAY)
time.sleep(self.delay)
else:
for _ in range(self.steps):
self.cpu.do_tick()
self.signal.emit(1)
time.sleep(CPU_TICK_DELAY)
time.sleep(self.delay)
# Signal end of execution as having run 0 ticks
self.signal.emit(0)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment