Esempio n. 1
0
class ClockedLink(object):
    """Support for implementing an EventLink which runs on an internal clock."""
    def __init__(self, *args, clock_start=0.0, **kwargs):
        """Initialize members."""
        super().__init__(*args, **kwargs)
        self.clock = Clock(time=clock_start)
        self.next_clock_request_timer = TimeoutTimer(clock=self.clock)

    # Public interface

    def update_clock(self, time):
        """Update the clock of the link and do any necessary processing."""
        # print('{}: updating clock to {}!'.format(self, time))
        self.to_receive(LinkClockTime(time, instance=self))
        self.send(LinkClockTime(time, instance=self))

    @property
    def next_clock_request(self):
        """Determine the next requested clock update."""
        if not self.next_clock_request_timer.running:
            return None
        return LinkClockRequest(self.next_clock_request_timer.timeout_time,
                                context={'time': self.clock.time},
                                instance=self)

    # Internal methods for implementers

    def make_timer(self, delay):
        """Make a timer on the processor clock."""
        return TimeoutTimer(timeout=delay, clock=self.clock)

    def get_clock_time(self, event):
        """Extract any provided clock time from the event."""
        if isinstance(event, LinkClockTime):
            return event.clock_time
        return None  # No clock time provided

    def update_clock_time(self, event):
        """Return the new clock time, updated with any clock time in the event."""
        clock_time = self.get_clock_time(event)
        if clock_time is None:
            return
        # print('Updating clock to: {}'.format(clock_time))
        self.clock.update(clock_time)
        if self.next_clock_request_timer.timed_out:
            self.next_clock_request_timer.reset_and_stop()

    def make_clock_request(self, time, context={}, previous=None):
        """Return a LinkClockRequest if time is different from the last request."""
        if (self.next_clock_request_timer.running and math.isclose(
                self.next_clock_request_timer.timeout_time, time)):
            return None
        self.next_clock_request_timer.start(timeout=time - self.clock.time)
        return LinkClockRequest(time,
                                context={
                                    'time': self.clock.time,
                                    **context
                                },
                                instance=self,
                                previous=previous)
Esempio n. 2
0
 def __init__(self, ping_name=b'ping', pong_name=b'pong'):
     """Initialize members."""
     self.ping_name = ping_name
     self.pong_name = pong_name
     self.ping_counter = 0
     self.active = False
     super().__init__()
     self.pong_timer = TimeoutTimer(clock=self.clock)
Esempio n. 3
0
 def __init__(
     self, timer=None, event_type='events', time_unit='second',
     report_interval=None, logger_name='Counter', logger_indentation=0
 ):
     """Initialize members."""
     if timer is None:
         timer = TimeoutTimer()
     self.timer = timer
     self.count = 0
     self.event_type = event_type
     self.report_interval = report_interval
     self.time_unit = time_unit
     self.logger = IndentedLogger(logging.getLogger(logger_name), {
         'class': self.__class__.__qualname__,
         'indentation': logger_indentation
     })
Esempio n. 4
0
class PingPongHandler(EndpointHandler, ClockedLink):
    """Handler for playing ping-pong in the background."""

    def __init__(self, ping_name=b'ping', pong_name=b'pong'):
        """Initialize members."""
        self.ping_name = ping_name
        self.pong_name = pong_name
        self.ping_counter = 0
        self.active = False
        super().__init__()
        self.pong_timer = TimeoutTimer(clock=self.clock)

    def make_ping(self):
        """Make a ping."""
        self.ping_counter += 1
        logger.info('Ping-pong sending ping {}'.format(self.ping_counter))
        return (self.ping_name, self.ping_counter)

    # Implement DataUnitLink

    def on_internal_data(self, parse_result, event):
        """Implement DataUnitLink.on_internal_data."""
        self.update_clock_time(event)
        if self.pong_timer.timed_out:
            self.pong_timer.reset_and_stop()
            self.directly_to_send_data(self.make_ping())

    # Implement EndpointHandler

    def match_receiver(self, endpoint_name):
        """Implement EndpointHandler.match_receiver."""
        return endpoint_name == self.pong_name

    def on_receiver_event(self, endpoint_name, data, source_event):
        """Implement EndpointHandler.on_receiver_event."""
        if endpoint_name == self.pong_name:
            logger.info('Ping-pong received pong {}'.format(data))
            self.pong_timer.start()
            clock_request = self.make_clock_request(self.pong_timer.timeout_time)
            if clock_request is not None:
                yield clock_request

    def on_sender_event(self, send_data):
        """Implement EndpointHandler.on_sender_event."""
        if send_data:
            logger.info('Starting ping-pong with interval of {} sec!'.format(send_data))
            self.pong_timer.timeout = send_data
            yield self.make_ping()
        else:
            logger.info('Stopping ping-pong.')
            self.pong_timer.reset_and_stop()
Esempio n. 5
0
 def make_timer(self, timeout=None):
     """Make a timer on the clock."""
     if timeout is None:
         timeout = self.send_timeout
     return TimeoutTimer(timeout=timeout, clock=self.clock)
Esempio n. 6
0
def test_timer_external():
    """Test externally-clocked timer functionality."""
    timer = TimeoutTimer(timeout=0.2, clock=Clock(time=0.0))
    assert timer.timeout_time is None
    assert timer.elapsed is None
    assert_timer_stopped(timer)

    # Basic test
    timer.clock.update(1.0)
    timer.start()
    assert repr(timer) == 'TimeoutTimer(running from 1.0, timeout=0.2)'
    assert timer.timeout_time == 1.2
    timer.clock.update(1.1)
    assert_timer_halfway(timer)
    timer.clock.update(1.2)
    assert_timer_finished(timer)
    timer.clock.update(1.3)
    assert_timer_finished(timer)
    timer.clock.update(0.0)
    timer.reset()
    timer.clock.update(0.1)
    assert_timer_halfway(timer)
    timer.clock.update(0.2)
    assert_timer_finished(timer)

    # Shared-clock test
    timer.clock.update(1.0)
    timer.reset()
    timer_slow = TimeoutTimer(timeout=0.4, clock=timer.clock)
    timer_slow.start()
    timer.clock.update(1.1)
    assert_timer_halfway(timer)
    timer.clock.update(1.2)
    assert_timer_finished(timer)
    assert_timer_halfway(timer_slow)
    timer.clock.update(1.4)
    assert_timer_finished(timer)
    assert_timer_finished(timer_slow)
Esempio n. 7
0
def test_timer_realtime():
    """Test real-time timer functionality."""
    timer = TimeoutTimer(timeout=0.2)
    assert timer.timeout_time is None
    assert timer.elapsed is None
    timer.enabled = True
    assert timer.elapsed is None  # no start time was set due to invalid state change
    timer.enabled = False
    assert_timer_stopped(timer)

    # Basic test
    timer.start()
    assert_timer_running_realtime(timer)

    # Stop-and-start test
    timer.reset_and_stop()
    assert_timer_stopped(timer)
    timer.reset()
    assert_timer_stopped(timer)
    timer.start()
    assert_timer_running_realtime(timer)

    # Reset test
    timer.reset()
    assert_timer_running_realtime(timer)
    timer.reset()
    assert_timer_running_realtime(timer)

    # Start test
    timer.start(timeout=0.1)
    assert_timer_running_realtime(timer)
    timer.reset()
    assert_timer_running_realtime(timer)
    timer.start()
    assert_timer_running_realtime(timer)

    # Externally-clocked mode-switching test
    timer.clock.reset(0.0)
    timer.start(timeout=0.2)
    timer.clock.update(0.1)
    assert_timer_halfway(timer)
    timer.clock.update(0.2)
    assert_timer_finished(timer)
Esempio n. 8
0
 def make_timer(self):
     """Make a timer on the clock."""
     return TimeoutTimer(timeout=self.delay, clock=self.clock)
Esempio n. 9
0
 def make_timer(self, delay):
     """Make a timer on the processor clock."""
     return TimeoutTimer(timeout=delay, clock=self.clock)
Esempio n. 10
0
 def __init__(self, *args, clock_start=0.0, **kwargs):
     """Initialize members."""
     super().__init__(*args, **kwargs)
     self.clock = Clock(time=clock_start)
     self.next_clock_request_timer = TimeoutTimer(clock=self.clock)