Browse Source

allow creating new timers during runtime

Falko Schindler 3 years ago
parent
commit
ab327ef516
3 changed files with 15 additions and 9 deletions
  1. 2 0
      nicegui/globals.py
  2. 5 6
      nicegui/nicegui.py
  3. 8 3
      nicegui/timer.py

+ 2 - 0
nicegui/globals.py

@@ -1,4 +1,5 @@
 from __future__ import annotations
+import asyncio
 from typing import TYPE_CHECKING
 if TYPE_CHECKING:
     from starlette.applications import Starlette
@@ -10,3 +11,4 @@ app: 'Starlette'
 config: 'Config'
 page_stack: list['Page'] = []
 view_stack: list['jp.HTMLBaseComponent'] = []
+tasks: list[asyncio.tasks.Task] = []

+ 5 - 6
nicegui/nicegui.py

@@ -9,16 +9,15 @@ from . import globals
 from . import binding
 
 
-def create_task(coro):
+def create_task(coro) -> asyncio.tasks.Task:
     loop = asyncio.get_event_loop()
     return loop.create_task(coro)
 
-tasks = []
-
 @jp.app.on_event('startup')
 def startup():
-    tasks.extend(create_task(t) for t in Timer.tasks)
-    tasks.extend(create_task(t) for t in Ui.startup_tasks if isinstance(t, Awaitable))
+    globals.tasks.extend(create_task(t) for t in Timer.prepared_coroutines)
+    Timer.prepared_coroutines.clear()
+    globals.tasks.extend(create_task(t) for t in Ui.startup_tasks if isinstance(t, Awaitable))
     [t() for t in Ui.startup_tasks if isinstance(t, Callable)]
     jp.run_task(binding.loop())
 
@@ -26,7 +25,7 @@ def startup():
 def shutdown():
     [create_task(t) for t in Ui.shutdown_tasks if isinstance(t, Awaitable)]
     [t() for t in Ui.shutdown_tasks if isinstance(t, Callable)]
-    [t.cancel() for t in tasks]
+    [t.cancel() for t in globals.tasks]
 
 
 app = globals.app = jp.app

+ 8 - 3
nicegui/timer.py

@@ -4,10 +4,10 @@ import traceback
 from typing import Awaitable, Callable, Union
 
 from .binding import BindableProperty
-from .globals import view_stack
+from .globals import tasks, view_stack
 
 class Timer:
-    tasks = []
+    prepared_coroutines = []
 
     active = BindableProperty()
 
@@ -57,4 +57,9 @@ class Timer:
                     traceback.print_exc()
                     await asyncio.sleep(interval)
 
-        self.tasks.append(timeout() if once else loop())
+        coroutine = timeout() if once else loop()
+        event_loop = asyncio.get_event_loop()
+        if not event_loop.is_running():
+            self.prepared_coroutines.append(coroutine)
+        else:
+            tasks.append(event_loop.create_task(coroutine))