53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
|
import asyncio
|
||
|
from traceback import format_exc
|
||
|
from .listener import Listener
|
||
|
from .timer import Timer
|
||
|
from . import utils
|
||
|
from .event import Event
|
||
|
|
||
|
event_queue=asyncio.Queue() #Contains Events. Everything in here must be an Event.
|
||
|
listeners=[] # These respond to events. They're executed by workers processing the event queue. They should all be Listeners
|
||
|
timers=[] # These just execute on a schedule. That schedule can be "as soon as it exits". Should all be Timers, which include the property of whether to wait for exit before starting the next call or not (rarely relevant, so defaults to "no" unless schedule is 0).
|
||
|
|
||
|
|
||
|
# Queue management
|
||
|
async def process_queue():
|
||
|
while True:
|
||
|
item=await event_queue.get()
|
||
|
asyncio.create_task(process_item(item))
|
||
|
|
||
|
async def process_item(item):
|
||
|
for listener in listeners:
|
||
|
terminate=False
|
||
|
if listener==item:
|
||
|
try: terminate=await listener(item)
|
||
|
except: utils.trace('explosions in',listener); format_exc()
|
||
|
if terminate: break
|
||
|
|
||
|
# Convenience functions for initialising.
|
||
|
def addlistener(match):
|
||
|
def __wrap__(funky):
|
||
|
listeners.append(Listener(match,funky))
|
||
|
return funky
|
||
|
return __wrap__
|
||
|
|
||
|
def addtimer(interval,start=None,block=None):
|
||
|
def __wrap__(funky):
|
||
|
a=Timer(funky,interval,block,start)
|
||
|
timers.append(a)
|
||
|
try: # Timers added after start will get run here, but timers added before start won't
|
||
|
asyncio.create_task(a.run())
|
||
|
except RuntimeError: pass
|
||
|
return funky
|
||
|
return __wrap__
|
||
|
|
||
|
def addevent(*args,**kwargs):
|
||
|
asyncio.create_task(event_queue.put(Event(*args,**kwargs)))
|
||
|
|
||
|
async def main():
|
||
|
# Any time that didn't get run before occurs here.
|
||
|
for timer in timers: asyncio.create_task(timer.run())
|
||
|
await process_queue()
|
||
|
|
||
|
def run():
|
||
|
asyncio.run(main())
|