Source code for src.data_acquisition.sequencers.fixation_cross_screen_sequencer

from logging import Logger
from typing import Callable, Generic, Optional, TypeVar, cast

from ..event_manager import EventManager
from ..eventful_screen import EventfulScreen
from ..gui import Gui
from ..screens import FixationCrossScreen
from .screen_sequencer import ScreenSequencer
from .simple_screen_sequencer import SimpleScreenSequencer

T = TypeVar("T")


[docs] class FixationCrossScreenSequencer(SimpleScreenSequencer[T], Generic[T]):
[docs] def __init__( self, *, gui: Gui, subsequencer: ScreenSequencer[T], fixation_screen_event_manager: EventManager[T], screen_show_callback: Callable[[str], None] = lambda _: None, logger: Optional[Logger] = None, ) -> None: """ :param gui: :param subsequencer: A subsequencer that provides the screens to be shown after fixation crosses. :param fixation_screen_event_manager: An event manager that ends the fixation cross screen. """ super().__init__( gui=gui, screen_show_callback=screen_show_callback, logger=logger ) self._subsequencer = subsequencer self._fixation_screen_event_manager = fixation_screen_event_manager self._idx = 0 self._next_subsequencer_screen: Optional[EventfulScreen[T]] = None
def _get_next(self) -> EventfulScreen[T]: self._pass_previous_result_if_needed() self._get_next_subsequencer_screen_if_needed_or_raise_stop() is_at_fixation_cross = self._is_at_fixation_cross() self._idx += 1 if is_at_fixation_cross: fixation_cross_screen = FixationCrossScreen(gui=self._gui) return EventfulScreen( screen=fixation_cross_screen, event_manager=self._fixation_screen_event_manager.clone(), ) return cast(EventfulScreen[T], self._next_subsequencer_screen) def _pass_previous_result_if_needed(self) -> None: if self._should_pass_previous_result(): self._subsequencer.pass_previous_result(self._previous_result) def _should_pass_previous_result(self) -> bool: return self._was_first_element_gotten and self._is_at_fixation_cross() def _is_at_fixation_cross(self) -> bool: return self._idx % 2 == 0 def _get_next_subsequencer_screen_if_needed_or_raise_stop(self) -> None: if not self._was_first_element_gotten or self._is_at_fixation_cross(): try: self._next_subsequencer_screen = self._subsequencer.get_next() except StopIteration: raise StopIteration def reset(self) -> None: """ Resets the sequencer so that the next returned screen will be a fixation cross screen. Does not reset the subsequencer. """ self._idx -= 1