emmental/lib/bus.py

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