diff --git a/frank/module/decorators/classes.py b/frank/module/decorators/classes.py index 3e93be1..3239893 100644 --- a/frank/module/decorators/classes.py +++ b/frank/module/decorators/classes.py @@ -4,6 +4,13 @@ from __future__ import annotations # Built-in imports import re +import asyncio + +# Typing imports +from typing import TYPE_CHECKING +if TYPE_CHECKING: + # Built-in imports + from typing import Union class Simple: @@ -95,11 +102,31 @@ class RegexCommand(Command): class Daemon(Simple): """ - Represents a daemon. Currently, it's only used as its own type, but writing - it this way allows us to easily expand upon its functionality later. + Represents a daemon aka a background process. """ - pass + def __init__(self, func: callable, interval: Union[int, float] = 0): + """ + Args + func: function to wrap + interval: time between calls of the function; if < 0, the function + is assumed to contain its own infinite loop, allowing for + fine-grained control of the daemon, if desired + """ + + super().__init__(func) + self.interval = interval + + # If an interval > 0 is given, it wraps the function inside an infinite + # loop with the desired delay + if interval > 0: + async def loop(self, *args, **kwargs): + while True: + func(self, *args, **kwargs) + + await asyncio.sleep(interval) + + self.func = loop class Default(Simple): diff --git a/frank/module/decorators/functions.py b/frank/module/decorators/functions.py index 205cd87..130bcd0 100644 --- a/frank/module/decorators/functions.py +++ b/frank/module/decorators/functions.py @@ -1,7 +1,16 @@ # =====IMPORTS===== +# Future imports +from __future__ import annotations + # Own imports from .classes import Command, RegexCommand, Daemon, Default +# Typing imports +from typing import TYPE_CHECKING +if TYPE_CHECKING: + # Built-in imports + from typing import Union + def command(cmd, help_str: str = None) -> callable: """ @@ -33,14 +42,14 @@ def regex_command(pattern: str, help_str: str = None) -> callable: return inner -def daemon() -> callable: +def daemon(interval: Union[int, float] = 0) -> callable: """ Converts the method into a Daemon, which will then be run when the module is started. """ def inner(func): - return Daemon(func) + return Daemon(func, interval) return inner