| f | import asyncio | f | import asyncio |
| | | |
| class Loop: | | class Loop: |
| n | _funcs = [] | n | funcs = [] |
| _steps = [] | | wrappers = [] |
| _evt = None | | ready = None |
| _launched = False | | started = False |
| _halt = False | | stop = False |
| _count = 0 | | total = 0 |
| | | |
| n | def __call__(self, fn): | n | def __call__(self, func): |
| Loop._funcs.append(fn) | | Loop.funcs.append(func) |
| Loop._count = len(Loop._funcs) | | Loop.total = len(Loop.funcs) |
| | | |
| n | async def outer(*a, **kw): | n | async def wrapper(*args, **kwargs): |
| if Loop._evt is None: | | if Loop.ready is None: |
| Loop._evt = asyncio.Event() | | Loop.ready = asyncio.Event() |
| | | |
| n | async def runner(): | n | async def step(): |
| while True: | | while True: |
| n | if Loop._halt: | n | if Loop.stop: |
| return None | | return None |
| n | out = await fn(*a, **kw) | n | r = await func(*args, **kwargs) |
| if out is None: | | if r is None: |
| Loop._halt = True | | Loop.stop = True |
| return None | | return None |
| n | return out | n | return r |
| Loop._steps.append(runner) | | Loop.wrappers.append(step) |
| if len(Loop._steps) == Loop._count: | | if len(Loop.wrappers) == Loop.total: |
| Loop._evt.set() | | Loop.ready.set() |
| await Loop._evt.wait() | | await Loop.ready.wait() |
| if not Loop._launched: | | if not Loop.started: |
| Loop._launched = True | | Loop.started = True |
| await Loop._cycle() | | await Loop._run() |
| return None | | return None |
| n | return outer | n | return wrapper |
| | | |
| @staticmethod | | @staticmethod |
| n | async def _cycle(): | n | async def _run(): |
| seq = Loop._steps | | steps = Loop.wrappers |
| while True: | | while True: |
| t | for r in seq: | t | for s in steps: |
| val = await r() | | r = await s() |
| if val is None: | | if r is None: |
| return | | return |