1"""This module runs continuous updates for R, such as redrawing graphs when
2the plot window is resized. Use the start() and stop() functions to turn
3updates on and off.
4
5"""
6from rpy2.rinterface import process_revents
7import time
8import warnings
9import threading
10
11
12class _EventProcessorThread(threading.Thread):
13    """ Call rinterface.process_revents(), pausing
14    for at least EventProcessor.interval between calls. """
15    _continue = True
16
17    def run(self):
18        while self._continue:
19            process_revents()
20            time.sleep(EventProcessor.interval)
21
22class EventProcessor(object):
23    """ Processor for R events (Singleton class) """
24    interval = 0.2
25    daemon_thread = True
26    name_thread = 'rpy2_process_revents'
27    _thread = None
28    _instance = None
29
30    def __new__(cls):
31        if cls._instance is None:
32            cls._instance = object.__new__(cls)
33        return cls._instance
34
35    def start(self):
36        """ start the event processor """
37        if (self._thread is not None) and (self._thread.is_alive()):
38            raise warnings.warn("Processing of R events already started.")
39        else:
40            self._thread = _EventProcessorThread(name = self.name_thread)
41            self._thread.setDaemon(self.daemon_thread)
42            self._thread.start()
43
44    def stop(self):
45        """ stop the event processor """
46        self._thread._continue = False
47        self._thread.join()
48
49    thread = property(lambda self: self._thread,
50                      None, None, "Thread that processes the events.")
51
52def start():
53    """ Start the threaded processing of R events. """
54    EventProcessor().start()
55
56def stop():
57    """ Stop the threaded processing of R events. """
58    EventProcessor().stop()
59
60