borgend/dreamtime.py

changeset 111
c3bc27cf5ece
parent 106
a7bdc239ef62
child 113
6993964140bd
equal deleted inserted replaced
110:a79409c72565 111:c3bc27cf5ece
213 # 213 #
214 214
215 class SleepHandler(Foundation.NSObject): 215 class SleepHandler(Foundation.NSObject):
216 """ Handle wake/sleep notifications """ 216 """ Handle wake/sleep notifications """
217 217
218 # We need to use the actual time.time() to monitor sleep, as
219 # time.monotonic() many not run during sleep. But time.time()
220 # may encounter adjustments, so we also use time.monotonic() to
221 # monitor wake periods.
222
218 def init(self): 223 def init(self):
219 self.__sleeptime=None 224 self.__sleeptime=None
220 self.__slept=0 225 self.__dreamtime_last_sleep=0
221 self.__epoch=time.monotonic() 226 self.__monotonic_last_wakeup=time.monotonic()
227 self.__slept=0 # Only used to store the statistic
222 self.__lock=threading.Lock() 228 self.__lock=threading.Lock()
223 self.__callbacks=weakref.WeakKeyDictionary() 229 self.__callbacks=weakref.WeakKeyDictionary()
224 230
225 return self 231 return self
226 232
227 @protect_noreturn 233 @protect_noreturn
228 def handleSleepNotification_(self, aNotification): 234 def handleSleepNotification_(self, aNotification):
229 logger.info("System going to sleep") 235 logger.info("System going to sleep")
230 now=time.monotonic()
231 with self.__lock: 236 with self.__lock:
232 self.__sleeptime=now 237 self.__sleeptime=time.time()
238 now_m=time.monotonic()
239 self.__dreamtime_last_sleep=(self.__dreamtime_last_sleep+now_m
240 -self.__monotonic_last_wakeup)
233 callbacks=self.__callbacks.copy() 241 callbacks=self.__callbacks.copy()
234 do_callbacks(callbacks, False) 242 do_callbacks(callbacks, False)
235 243
236 @protect_noreturn 244 @protect_noreturn
237 def handleWakeNotification_(self, aNotification): 245 def handleWakeNotification_(self, aNotification):
238 logger.info("System waking up from sleep") 246 logger.info("System waking up from sleep")
239 now=time.monotonic()
240 with self.__lock: 247 with self.__lock:
241 if self.__sleeptime: 248 if self.__sleeptime:
249 self.__monotonic_last_wakeup=time.monotonic()
250 now=time.time()
242 slept=max(0, now-self.__sleeptime) 251 slept=max(0, now-self.__sleeptime)
243 logger.info("Slept %f seconds" % slept) 252 logger.info("Slept %f seconds" % slept)
244 self.__slept=self.__slept+slept 253 self.__slept=self.__slept+slept
245 self.__sleeptime=None 254 self.__sleeptime=None
246 callbacks=self.__callbacks.copy() 255 callbacks=self.__callbacks.copy()
247 do_callbacks(callbacks, True) 256 do_callbacks(callbacks, True)
248 257
249 # Return dreamtime 258 # Return dreamtime
250 def dreamtime_sleeping(self, snapshot=Snapshot()): 259 def dreamtime_sleeping(self, snapshot=Snapshot()):
251 sleeping=False
252 with self.__lock: 260 with self.__lock:
253 # macOS "sleep" signals / status are complete bollocks: at least 261 # macOS "sleep" signals / status are complete bollocks: at least
254 # when plugged in, the system is actually sometimes running all 262 # when plugged in, the system is actually sometimes running all
255 # night with the lid closed and sleepNotification delivered. 263 # night with the lid closed and sleepNotification delivered.
256 # Therefore, we need our timers to work in a sane manner when 264 # Therefore, we need our timers to work in a sane manner when
257 # we should be sleeping! 265 # we should be sleeping!
258 if self.__sleeptime is not None: 266 if self.__sleeptime is not None:
259 now_monotonic=self.__sleeptime
260 sleeping=True 267 sleeping=True
268 now_dreamtime=self.__dreamtime_last_sleep
261 else: 269 else:
262 now_monotonic=snapshot.monotonic() 270 sleeping=False
263 now_dreamtime=max(0, now_monotonic-self.__epoch-self.__slept) 271 now=snapshot.monotonic()
272 now_dreamtime=(self.__dreamtime_last_sleep
273 +now-self.__monotonic_last_wakeup);
264 return now_dreamtime, sleeping 274 return now_dreamtime, sleeping
265 275
266 # Weirdo (Py)ObjC naming to stop it form choking up 276 # Weirdo (Py)ObjC naming to stop it form choking up
267 def addForObj_aCallback_(self, obj, callback): 277 def addForObj_aCallback_(self, obj, callback):
268 with self.__lock: 278 with self.__lock:

mercurial