|
@@ -1,9 +1,11 @@
|
|
-from typing import Callable, List
|
|
|
|
|
|
+from typing import Any, Callable, Dict, List, Tuple
|
|
|
|
|
|
from typing_extensions import Self
|
|
from typing_extensions import Self
|
|
|
|
|
|
|
|
+from .. import background_tasks, globals
|
|
from ..dependencies import register_component
|
|
from ..dependencies import register_component
|
|
from ..element import Element
|
|
from ..element import Element
|
|
|
|
+from ..helpers import is_coroutine
|
|
|
|
|
|
register_component('refreshable', __file__, 'refreshable.js')
|
|
register_component('refreshable', __file__, 'refreshable.js')
|
|
|
|
|
|
@@ -18,19 +20,43 @@ class refreshable:
|
|
"""
|
|
"""
|
|
self.func = func
|
|
self.func = func
|
|
self.instance = None
|
|
self.instance = None
|
|
- self.containers: List[Element] = []
|
|
|
|
|
|
+ self.containers: List[Tuple[Element, List[Any], Dict[str, Any]]] = []
|
|
|
|
|
|
def __get__(self, instance, _) -> Self:
|
|
def __get__(self, instance, _) -> Self:
|
|
self.instance = instance
|
|
self.instance = instance
|
|
return self
|
|
return self
|
|
|
|
|
|
- def __call__(self) -> None:
|
|
|
|
|
|
+ def __call__(self, *args, **kwargs) -> None:
|
|
|
|
+ self.prune()
|
|
with Element('refreshable') as container:
|
|
with Element('refreshable') as container:
|
|
- self.func() if self.instance is None else self.func(self.instance)
|
|
|
|
- self.containers.append(container)
|
|
|
|
|
|
+ self.containers.append((container, args, kwargs))
|
|
|
|
+ return self.func(*args, **kwargs) if self.instance is None else self.func(self.instance, *args, **kwargs)
|
|
|
|
|
|
def refresh(self) -> None:
|
|
def refresh(self) -> None:
|
|
- for container in self.containers:
|
|
|
|
|
|
+ self.prune()
|
|
|
|
+ for container, args, kwargs in self.containers:
|
|
container.clear()
|
|
container.clear()
|
|
- with container:
|
|
|
|
- self.func() if self.instance is None else self.func(self.instance)
|
|
|
|
|
|
+ if is_coroutine(self.func):
|
|
|
|
+ async def wait_for_result(container: Element, args, kwargs):
|
|
|
|
+ with container:
|
|
|
|
+ if self.instance is None:
|
|
|
|
+ await self.func(*args, **kwargs)
|
|
|
|
+ else:
|
|
|
|
+ await self.func(self.instance, *args, **kwargs)
|
|
|
|
+ if globals.loop and globals.loop.is_running():
|
|
|
|
+ background_tasks.create(wait_for_result(container=container, args=args, kwargs=kwargs))
|
|
|
|
+ else:
|
|
|
|
+ globals.app.on_startup(wait_for_result(container=container, args=args, kwargs=kwargs))
|
|
|
|
+ else:
|
|
|
|
+ with container:
|
|
|
|
+ if self.instance is None:
|
|
|
|
+ self.func(*args, **kwargs)
|
|
|
|
+ else:
|
|
|
|
+ self.func(self.instance, *args, **kwargs)
|
|
|
|
+
|
|
|
|
+ def prune(self) -> None:
|
|
|
|
+ self.containers = [
|
|
|
|
+ (container, args, kwargs)
|
|
|
|
+ for container, args, kwargs in self.containers
|
|
|
|
+ if container.client.id in globals.clients
|
|
|
|
+ ]
|