60 lines
1.7 KiB
Python
60 lines
1.7 KiB
Python
# Copyright 2021 (c) Anna Schumaker.
|
|
from . import publisher
|
|
import threading
|
|
from gi.repository import GLib
|
|
|
|
Start = publisher.Publisher()
|
|
RETRY = GLib.SOURCE_CONTINUE
|
|
|
|
class Bus:
|
|
def __init__(self, milliseconds):
|
|
self.timeout = milliseconds
|
|
self.timeout_id = None
|
|
self.passengers = [ ]
|
|
self.lock = threading.Lock()
|
|
|
|
def __do_board(self, func, *args):
|
|
with self.lock:
|
|
if (func, args) not in self.passengers:
|
|
self.passengers.append( (func, args) )
|
|
if self.timeout_id == None:
|
|
self.timeout_id = GLib.timeout_add(self.timeout, self.run)
|
|
return True
|
|
return False
|
|
|
|
def board(self, func, *args):
|
|
if self.__do_board(func, *args):
|
|
Start.publish(self)
|
|
|
|
def clear(self):
|
|
with self.lock:
|
|
if self.timeout_id:
|
|
GLib.source_remove(self.timeout_id)
|
|
self.timeout_id = None
|
|
self.passengers.clear()
|
|
|
|
def complete(self):
|
|
with self.lock:
|
|
for (func, args) in self.passengers:
|
|
func(*args)
|
|
|
|
GLib.source_remove(self.timeout_id)
|
|
self.timeout_id = None
|
|
self.passengers.clear()
|
|
|
|
def running(self):
|
|
with self.lock:
|
|
return self.timeout_id != None
|
|
|
|
def run(self):
|
|
with self.lock:
|
|
(func, args) = self.passengers[0]
|
|
if func(*args) == RETRY:
|
|
return GLib.SOURCE_CONTINUE
|
|
|
|
self.passengers.pop(0)
|
|
if len(self.passengers) == 0:
|
|
self.timeout_id = None
|
|
return GLib.SOURCE_REMOVE
|
|
return GLib.SOURCE_CONTINUE
|