Closed jdkuki closed 10 months ago
Microgui is designed to be usable in an application that uses only synchronous code - indeed by users with no knowledge of asyncio
. Its use of asyncio
is therefore hidden and as you have realised it is started when the first screen is instantiated: in the first call to Screen.change(BaseScreen)
. asyncio
runs until the base screen terminates, returning to the REPL.
The use of reg_task
is entirely optional: it allows a task to be associated with a Screen
instance, being cancelled when the screen is closed. If tasks are to run for the lifetime of the application (or for some lesser duration) they may be launched at any point by issuing asyncio.create_task
. The earliest a task may be started is in the constructor of the base screen.
Thanks Peter, I am somewhat new to micropython and just setup a test between normal asyncio and uasyncio on the esp32.
In normal python, calling create_task without an event loop throws an excpetion. It looks like in uasyncio, create_task can be called at any time and is kept in some sort of global task list. Ex:
try:
import uasyncio as asyncio
except ImportError:
import asyncio
async def test():
while True:
print("hello world")
await asyncio.sleep(1)
async def main():
i = 0
while i < 10:
i = i + 1
await asyncio.sleep(1)
asyncio.create_task(test())
asyncio.run(main())
Will throw an exception in a normal interpreter but not on micropython. I think the Screen code is taking advantage of this but was hard to follow (micropython seems to imply uasyncio is a rough 1:1 port?) (at least for me coming from golang into python coroutines and micropython at the same time)
Your observation about create_task
is correct. MicroPython is not strictly correct in allowing it to be called prior to creating an event loop. You are also right in that Screen.change() instantiates the base screen before starting asyncio
. Thanks for pointing this out - this had escaped me.
I'll consider what to do about this. In practical terms I can't see any impact on application design or behaviour.
I have pushed an update which fixes this. Thanks for the report.
Thanks!
Hello,
I am looking to use this library to integrate into a small "client" device I'm building to display data being polled from another device over bluetooth. I would like my client to be able to setup the connection to bluetooth in the background, periodically poll data to store in memory or respond to any incoming bluetooth data appropriately. My client device will have multiple "screens" to navigate between to control various aspects of the device.
I am having trouble figuring out how to setup a long lived background task that will persist throughout screen navigations. It seems I can register a task via
reg_task
, however all tasks here will be cancelled between navigations? It seems I can't setup anything prior to callingScreen.change
as this will callasyncio.run
which should create the event loop, which would throw an exception if I tried to set one up prior. Calling create_task prior to this should also throw an exception (although it seems likereg_task
is callingcreate_task
beforeasyncio.run(Screen.monitor())
creates the event loop (should also be throwing an exception)?Any guidance on how I should go about things would be greatly appreciated