Source code for iterm2.future

import logging
import _synchronouscb as synchronouscb

"""0-argument callbacks that get invoked just before blocking."""
_idle_observers = []

[docs]def add_idle_observer(observer): """Adds an idle observer callback. Will be run just before blocking the main thread.""" _idle_observers.append(observer)
[docs]class Future(synchronouscb.SynchronousCallback): """Represents a value that will become available later. As this is a subclass of SynchronousCallback, invoke callback() when the future is resolved. Clients call get() when they're ready to block for a value. Also has some bells and whistles. When you create a future you can define a transform function that will modify the value. You can add a "watch" function that gets called asynchronously when the value becomes available. """ def __init__(self, transform=None): """Initializes a new future. transform: If not None, the transform function runs immediately when the value becomes available. It takes one argument, the original response. It returns a transformed response, which is returned by get(). """ synchronouscb.SynchronousCallback.__init__(self) if transform is None: self.transform = lambda x: x else: self.transform = transform self.transformed_response = None self.watches = []
[docs] def get(self): """Returns the existing transformed response if available. Otherwise, waits until it is available and then returns it.""" if self.transformed_response is None: logging.debug("Waiting on future") self.wait() logging.debug("REALIZING %s" % str(self)) self.transformed_response = self.transform(self.response) assert self.transformed_response is not None self._invoke_watches(self.transformed_response) return self.transformed_response
[docs] def watch(self, callback): """Adds a watch callback to the future. The callback will be invoked when the transformed response becomes available. """ if self.watches is not None: logging.debug("Add watch to %s", str(self)) self.watches.append(callback) else: logging.debug("Immediately run callback for watch for %s" % str(self)) callback(self.get())
[docs] def wait(self): """Blocks until a value is available. Has the side effect of telling idle observers that we're about to block. """ self.idle_spin() synchronouscb.SynchronousCallback.wait(self)
[docs] def idle_spin(self): """Call this before blocking while idle in the main thread.""" logging.debug("Running idle observers") for o in _idle_observers: o()
[docs] def realized(self): return self.response is not None
def _invoke_watches(self, response): watches = self.watches self.watches = None for watch in watches: watch(response)