dreamtime.py

changeset 80
a409242121d5
parent 79
b075b3db3044
child 81
7bcd715f19e3
--- a/dreamtime.py	Sun Jan 28 11:38:01 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-#
-# Wake/sleep detection for scheduling adjustments
-#
-
-import Foundation
-import AppKit
-import platform
-import time
-import threading
-import weakref
-import datetime
-import loggers
-
-logger=loggers.get(__name__)
-
-_dreamtime_monitor=None
-
-#
-# Support classes for dealing with different times
-#
-
-# Return difference (delay) of "dreamtime" to monotonic time
-def dreamtime_difference():
-    if _dreamtime_monitor:
-        return _dreamtime_monitor.diff()
-    else:
-        return time.monotonic()
-
-# Return "dreamtime"
-def dreamtime():
-    return max(0, time.monotonic()-dreamtime_difference())
-
-class Time:
-    def realtime(self):
-        raise NotImplementedError
-
-    def monotonic(self):
-        raise NotImplementedError
-
-    @staticmethod
-    def _now():
-        raise NotImplementedError
-
-    @classmethod
-    def now(cls):
-        return cls(cls._now())
-
-    @classmethod
-    def from_realtime(cls, realtime):
-        return cls(realtime-time.time()+cls._now())
-
-    @classmethod
-    def from_monotonic(cls, monotonic):
-        return cls(monotonic-time.monotonic()+cls._now())
-
-    @classmethod
-    def after(cls, seconds):
-        return cls(cls._now()+seconds)
-
-    def datetime(self):
-        return datetime.datetime.fromtimestamp(self.realtime())
-
-    def seconds_to(self):
-        return self._value-self._now()
-
-    def __lt__(self, other):
-        return self.monotonic() < other.monotonic()
-
-    def __gt__(self, other):
-        return self.monotonic() > other.monotonic()
-
-    def __le__(self, other):
-        return self.monotonic() <= other.monotonic()
-
-    def __ge__(self, other):
-        return self.monotonic() >= other.monotonic()
-
-    def __eq__(self, other):
-        return self.monotonic() == other.realtime()
-
-class RealTime(Time):
-    def __init__(self, when):
-        self._value=when
-
-    def realtime(self):
-        return self._value
-
-    def monotonic(self):
-        return self._value+(time.monotonic()-time.time())
-
-    @staticmethod
-    def _now():
-        return time.time()
-
-class MonotonicTime(Time):
-    def __init__(self, when):
-        self._value=when
-
-    def realtime(self):
-        return self._value+(time.time()-time.monotonic())
-
-    def monotonic(self):
-        return self._value
-
-    @staticmethod
-    def _now():
-        return time.monotonic()
-
-class DreamTime(Time):
-    def __init__(self, when):
-        self._value=when
-
-    def realtime(self):
-        return self._value+(time.time()-dreamtime())
-
-    # Important: monotonic is "static" within a wakeup period
-    # and does not need to call time.monotonic(), as it gets compared
-    # to a specific time.monotonic() realisation
-    def monotonic(self):
-        return self._value+dreamtime_difference()
-
-    @staticmethod
-    def _now():
-        return dreamtime()
-
-#
-# Wake up / sleep handling
-#
-
-class SleepHandler(Foundation.NSObject):
-    """ Handle wake/sleep notifications """
-
-    def init(self):
-        self.__sleeptime=None
-        self.__slept=0
-        self.__epoch=time.monotonic()
-        self.__lock=threading.Lock()
-        self.__callbacks=weakref.WeakKeyDictionary()
-
-        return self
-
-    def handleSleepNotification_(self, aNotification):
-        logger.info("System going to sleep")
-        now=time.monotonic()
-        with self.__lock:
-            self.__sleeptime=now
-
-    def handleWakeNotification_(self, aNotification):
-        logger.info("System waking up from sleep")
-        try:
-            now=time.monotonic()
-            with self.__lock:
-                if self.__sleeptime:
-                    slept=max(0, now-self.__sleeptime)
-                    logger.info("Slept %f seconds" % slept)
-                    self.__slept=self.__slept+slept
-                    self.__sleeptime=None
-                callbacks=self.__callbacks.copy()
-        except:
-            logger.exception("Bug in wakeup handler")
-
-        for callback in callbacks.values():
-            try:
-                callback()
-            except Exception:
-                logger.exception("Error in wake notification callback")
-
-    # Return difference to time.monotonic()
-    def diff(self):
-        with self.__lock:
-            diff=self.__epoch+self.__slept
-        return diff
-
-    # Weirdo (Py)ObjC naming to stop it form choking up
-    def addForObj_aCallback_(self, obj, callback):
-        with self.__lock:
-            self.__callbacks[obj]=callback
-
-# obj is to use a a key in a weak key dictionary
-def add_callback(obj, callback):
-    global _dreamtime_monitor
-
-    monitor=_dreamtime_monitor
-    if not monitor:
-        raise Exception("Dreamtime monitor not started")
-    else:
-        monitor.addForObj_aCallback_(obj, callback)
-
-def start_monitoring():
-    global _dreamtime_monitor
-
-    if platform.system()=='Darwin':
-        logger.debug("Starting to monitor system sleep")
-        workspace = AppKit.NSWorkspace.sharedWorkspace()
-        notification_center = workspace.notificationCenter()
-        _dreamtime_monitor = SleepHandler.new()
-
-        notification_center.addObserver_selector_name_object_(
-            _dreamtime_monitor,
-            "handleSleepNotification:",
-            AppKit.NSWorkspaceWillSleepNotification,
-            None)
-
-        notification_center.addObserver_selector_name_object_(
-            _dreamtime_monitor,
-            "handleWakeNotification:",
-            AppKit.NSWorkspaceDidWakeNotification,
-            None)
-    else:
-        logger.warning(("No system sleep monitor implemented for '%s'"
-                       % platform.system()))
-

mercurial