diff --git a/mpf/platforms/virtual_pinball/virtual_pinball.py b/mpf/platforms/virtual_pinball/virtual_pinball.py index fcb6e233f..78cdae92e 100644 --- a/mpf/platforms/virtual_pinball/virtual_pinball.py +++ b/mpf/platforms/virtual_pinball/virtual_pinball.py @@ -1,14 +1,18 @@ """VPX platform.""" import asyncio -from typing import Dict, Optional +from typing import Dict, List, Optional import logging + +from mpf.devices.segment_display.segment_display_text import ColoredSegmentDisplayText +from mpf.platforms.interfaces.segment_display_platform_interface import SegmentDisplayPlatformInterface, FlashingType + from mpf.platforms.interfaces.driver_platform_interface import DriverPlatformInterface, PulseSettings, HoldSettings from mpf.platforms.interfaces.light_platform_interface import LightPlatformInterface from mpf.platforms.interfaces.switch_platform_interface import SwitchPlatformInterface from mpf.core.platform import LightsPlatform, SwitchPlatform, DriverPlatform, SwitchSettings, DriverSettings, \ - SwitchConfig, DriverConfig, RepulseSettings + SwitchConfig, DriverConfig, RepulseSettings, SegmentDisplayPlatform class VirtualPinballSwitch(SwitchPlatformInterface): @@ -62,12 +66,15 @@ def get_board_name(self): return "VPX" def is_successor_of(self, other): - """Not implemented.""" - raise AssertionError("Not implemented. Let us know if you need it.") + """Return true if the other light has the same number string plus the suffix '+1'.""" + return self.number == other.number + "+1" def get_successor_number(self): - """Not implemented.""" - raise AssertionError("Not implemented. Let us know if you need it.") + """Return the number with the suffix '+1'. + + As there is not real number format for virtual is this is all we can do here. + """ + return self.number + "+1" def __lt__(self, other): """Not implemented.""" @@ -117,11 +124,43 @@ def state(self) -> bool: return bool(self.clock.get_time() < self._state) -class VirtualPinballPlatform(LightsPlatform, SwitchPlatform, DriverPlatform): +class VirtualPinballSegmentDisplay(SegmentDisplayPlatformInterface): + + """Virtual segment display.""" + + __slots__ = ["_text", "flashing", "flash_mask", "machine"] + + def __init__(self, number, machine) -> None: + """Initialise virtual segment display.""" + super().__init__(number) + self.machine = machine + self._text = None + self.flashing = FlashingType.NO_FLASH + self.flash_mask = "" + + def set_text(self, text: ColoredSegmentDisplayText, flashing: FlashingType, flash_mask: str) -> None: + """Set text.""" + self._text = text + self.flashing = flashing + self.flash_mask = flash_mask + + @property + def text(self): + """Return text.""" + return self._text.convert_to_str() + + @property + def colors(self): + """Return colors.""" + return self._text.get_colors() + + +class VirtualPinballPlatform(LightsPlatform, SwitchPlatform, DriverPlatform, SegmentDisplayPlatform): """VPX platform.""" - __slots__ = ["_lights", "_switches", "_drivers", "_last_drivers", "_last_lights", "_started", "rules"] + __slots__ = ["_lights", "_switches", "_drivers", "_last_drivers", "_last_lights", + "_started", "rules", "_configured_segment_displays", "_last_segment_text"] def __init__(self, machine): """Initialize VPX platform.""" @@ -131,6 +170,8 @@ def __init__(self, machine): self._drivers = {} # type: Dict[str, VirtualPinballDriver] self._last_drivers = {} # type: Dict[str, bool] self._last_lights = {} # type: Dict[str, float] + self._configured_segment_displays = [] # type: List[VirtualPinballSegmentDisplay] + self._last_segment_text = {} # type: Dict[str, str] self._started = asyncio.Event() self.log = logging.getLogger("VPX Platform") self.log.debug("Configuring VPX hardware interface.") @@ -244,6 +285,18 @@ def _get_changed_brightness_lights_by_subtype(self, subtype): return changed_lamps + def _get_changed_segment_text(self): + """Return changed configured segment text since last call.""" + changed_segments = [] + for segment_display in self._configured_segment_displays: + text = segment_display.text + number = segment_display.number + if text != self._last_segment_text[number]: + changed_segments.append((number, text)) + self._last_segment_text[number] = text + + return changed_segments + def vpx_changed_lamps(self): """Return changed lamps since last call.""" return self._get_changed_lights_by_subtype("matrix") @@ -279,6 +332,10 @@ def vpx_set_mech(self, number, value): self.log.warning("Command \"set_mech\" unimplemented: %s %s", number, value) return True + def vpx_changed_segment_text(self): + """Return changed segment text since last call.""" + return self._get_changed_segment_text() + def configure_switch(self, number: str, config: SwitchConfig, platform_config: dict) -> "SwitchPlatformInterface": """Configure VPX switch.""" number = str(number) @@ -294,6 +351,11 @@ def configure_driver(self, config: DriverConfig, number: str, platform_settings: self._last_drivers[number] = False return driver + def validate_segment_display_section(self, segment_display, config): + """Validate segment display sections.""" + del segment_display + return config + def vpx_get_hardwarerules(self): """Return hardware rules.""" hardware_rules = [] @@ -384,3 +446,13 @@ def parse_light_number_to_channels(self, number: str, subtype: str): ] else: raise AssertionError("Unknown subtype {}".format(subtype)) + + async def configure_segment_display(self, number: str, display_size: int, + platform_settings) -> SegmentDisplayPlatformInterface: + """Configure segment display.""" + del platform_settings + del display_size + segment_display = VirtualPinballSegmentDisplay(number, self.machine) + self._configured_segment_displays.append(segment_display) + self._last_segment_text[number] = None + return segment_display