From e3bc88120e071eac8fabb5b02d7b509488d563e2 Mon Sep 17 00:00:00 2001 From: Trygve Aaberge Date: Mon, 24 Oct 2022 21:08:02 +0200 Subject: Split into multiple files --- slack/task.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 slack/task.py (limited to 'slack/task.py') diff --git a/slack/task.py b/slack/task.py new file mode 100644 index 0000000..e976866 --- /dev/null +++ b/slack/task.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +from typing import Any, Awaitable, Coroutine, Generator, Tuple, TypeVar +from uuid import uuid4 + +import globals +import weechat + +T = TypeVar("T") + + +class Future(Awaitable[T]): + def __init__(self): + self.id = str(uuid4()) + + def __await__(self) -> Generator[Future[T], T, T]: + return (yield self) + + +class FutureProcess(Future[Tuple[str, int, str, str]]): + pass + + +class FutureTimer(Future[Tuple[int]]): + pass + + +class Task(Future[T]): + def __init__(self, coroutine: Coroutine[Future[Any], Any, T], final: bool): + super().__init__() + self.coroutine = coroutine + self.final = final + + +def weechat_task_cb(data: str, *args: Any) -> int: + task = globals.active_tasks.pop(data) + task_runner(task, args) + return weechat.WEECHAT_RC_OK + + +def task_runner(task: Task[Any], response: Any): + while True: + try: + future = task.coroutine.send(response) + if future.id in globals.active_responses: + response = globals.active_responses.pop(future.id) + else: + if future.id in globals.active_tasks: + raise Exception( + f"future.id in active_tasks, {future.id}, {globals.active_tasks}" + ) + globals.active_tasks[future.id] = task + break + except StopIteration as e: + if task.id in globals.active_tasks: + task = globals.active_tasks.pop(task.id) + response = e.value + else: + if task.id in globals.active_responses: + raise Exception( # pylint: disable=raise-missing-from + f"task.id in active_responses, {task.id}, {globals.active_responses}" + ) + if not task.final: + globals.active_responses[task.id] = e.value + break + + +def create_task( + coroutine: Coroutine[Future[Any], Any, T], final: bool = False +) -> Task[T]: + task = Task(coroutine, final) + task_runner(task, None) + return task + + +async def sleep(milliseconds: int): + future = FutureTimer() + weechat.hook_timer(milliseconds, 0, 1, weechat_task_cb.__name__, future.id) + return await future -- cgit