diff options
author | Trygve Aaberge <trygveaa@gmail.com> | 2022-10-24 21:08:02 +0200 |
---|---|---|
committer | Trygve Aaberge <trygveaa@gmail.com> | 2024-02-18 11:32:52 +0100 |
commit | e3bc88120e071eac8fabb5b02d7b509488d563e2 (patch) | |
tree | f4f7195d629e4beb2e146624575d5f9302e0ab2d /slack/task.py | |
parent | e6796bbf07a5c8ecdc3411f583814be28f163807 (diff) | |
download | wee-slack-e3bc88120e071eac8fabb5b02d7b509488d563e2.tar.gz |
Split into multiple files
Diffstat (limited to 'slack/task.py')
-rw-r--r-- | slack/task.py | 79 |
1 files changed, 79 insertions, 0 deletions
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 |