Skip to content

Commit

Permalink
[#18] Refine notfifying devices.
Browse files Browse the repository at this point in the history
  • Loading branch information
kosarev committed Jan 31, 2021
1 parent 2d0fcb5 commit 6128401
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 27 deletions.
24 changes: 19 additions & 5 deletions zx/_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,25 @@
import enum


class DeviceEvent(enum.Enum):
PAUSE_STATE_UPDATED = enum.auto()
QUANTUM_RUN = enum.auto()
SCREEN_UPDATED = enum.auto()
TAPE_STATE_UPDATED = enum.auto()
class DeviceEvent(object):
pass


class PauseStateUpdated(DeviceEvent):
pass


class QuantumRun(DeviceEvent):
pass


class ScreenUpdated(DeviceEvent):
def __init__(self, pixels):
self.pixels = pixels


class TapeStateUpdated(DeviceEvent):
pass


class Device(object):
Expand Down
17 changes: 8 additions & 9 deletions zx/_emulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
import time
from ._data import MachineSnapshot
from ._data import SoundFile
from ._device import DeviceEvent
from ._device import PauseStateUpdated
from ._device import QuantumRun
from ._device import ScreenUpdated
from ._device import TapeStateUpdated
from ._error import Error
from ._except import EmulatorException
from ._file import parse_file
Expand Down Expand Up @@ -85,14 +88,10 @@ def __init__(self, speed_factor=1.0, profile=None, devices=None):
def _is_paused(self):
return self.__is_paused_flag

def __notify(self, id, *args):
for device in self.__devices:
device._on_emulator_event(id, *args)

# TODO: Double-underscore or make public.
def _pause(self, is_paused=True):
self.__is_paused_flag = is_paused
self.__notify(DeviceEvent.PAUSE_STATE_UPDATED)
self.notify_devices(PauseStateUpdated())

# TODO: Double-underscore or make public.
def _toggle_pause(self):
Expand All @@ -115,7 +114,7 @@ def _is_tape_paused(self):

def __pause_tape(self, is_paused=True):
self._tape_player.pause(is_paused)
self.__notify(DeviceEvent.TAPE_STATE_UPDATED)
self.notify_devices(TapeStateUpdated())

def __unpause_tape(self):
self.__pause_tape(is_paused=False)
Expand Down Expand Up @@ -293,7 +292,7 @@ def __run_quantum(self, speed_factor=None):
creator_info = self.__playback_player.find_recording_info_chunk()

if True: # TODO
self.__notify(DeviceEvent.QUANTUM_RUN)
self.notify_devices(QuantumRun())

# TODO: For debug purposes.
'''
Expand Down Expand Up @@ -338,7 +337,7 @@ def __run_quantum(self, speed_factor=None):
self.render_screen()

pixels = self.get_frame_pixels()
self.__notify(DeviceEvent.SCREEN_UPDATED, pixels)
self.notify_devices(ScreenUpdated(pixels))

self._tape_player.skip_rest_of_frame()
self._emulation_time.advance(1 / 50)
Expand Down
29 changes: 16 additions & 13 deletions zx/_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
import cairo
import gi
from ._device import Device
from ._device import DeviceEvent
from ._device import PauseStateUpdated
from ._device import QuantumRun
from ._device import ScreenUpdated
from ._device import TapeStateUpdated
from ._error import USER_ERRORS
from ._error import verbalize_error
from ._except import EmulationExit
Expand Down Expand Up @@ -181,11 +184,11 @@ def __init__(self, emulator):
'PAUSE': self.emulator._toggle_pause,
}

self._EMULATOR_EVENT_HANDLERS = {
DeviceEvent.PAUSE_STATE_UPDATED: self._on_updated_pause_state,
DeviceEvent.QUANTUM_RUN: self._on_quantum_run,
DeviceEvent.SCREEN_UPDATED: self._on_updated_screen,
DeviceEvent.TAPE_STATE_UPDATED: self._on_updated_tape_state,
self._EVENT_HANDLERS = {
PauseStateUpdated: self._on_updated_pause_state,
QuantumRun: self._on_quantum_run,
ScreenUpdated: self._on_updated_screen,
TapeStateUpdated: self._on_updated_tape_state,
}

self._notification = Notification()
Expand Down Expand Up @@ -259,8 +262,8 @@ def _on_draw_area(self, widget, context):

self._screencast.on_draw(context.get_group_target())

def _on_updated_screen(self, pixels):
self.frame_data[:] = pixels
def _on_updated_screen(self, event):
self.frame_data[:] = event.pixels
self.area.queue_draw()

def _show_help(self):
Expand Down Expand Up @@ -368,24 +371,24 @@ def _on_window_state_event(self, widget, event):
state = event.new_window_state
self._is_fullscreen = bool(state & Gdk.WindowState.FULLSCREEN)

def _on_emulator_event(self, id, *args):
self._EMULATOR_EVENT_HANDLERS[id](*args)
def on_event(self, event):
self._EVENT_HANDLERS[type(event)](event)

def _on_updated_pause_state(self):
def _on_updated_pause_state(self, event):
if self.emulator._is_paused():
self._notification.set(draw_pause_notification,
self.emulator._emulation_time)
else:
self._notification.clear()

def _on_updated_tape_state(self):
def _on_updated_tape_state(self, event):
tape_paused = self.emulator._is_tape_paused()
draw = (draw_tape_pause_notification if tape_paused
else draw_tape_resume_notification)
tape_time = self.emulator._tape_player.get_time()
self._notification.set(draw, tape_time)

def _on_quantum_run(self):
def _on_quantum_run(self, event):
if self._queued_exception is not None:
e = self._queued_exception
self._queued_exception = None
Expand Down
4 changes: 4 additions & 0 deletions zx/_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,10 @@ def __exit__(self, type, value, tb):
def stop(self):
raise EmulationExit()

def notify_devices(self, event):
for device in self.devices:
device.on_event(event)

def set_breakpoints(self, addr, size):
self.mark_addrs(addr, size, self._BREAKPOINT_MARK)

Expand Down

0 comments on commit 6128401

Please sign in to comment.