-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
please provide a default nonblocking async input driver #204
Comments
hi, is this issue related to pyTermTk? If this is related to pyTermTk, (i.e. trying to run it under pygame-web) |
I tried your input routine using pygbag |
sorry i did not think you would try directly on pygbag - i'm honoured - but the select.select patch is still brewing on my pc and is triggered for now by the first termios.tcsetattr() call that is expected to switch the terminal in raw mode. it's very crude __select = select.select
def patch_select(rlist, wlist, xlist, timeout=None, /):
global __select
# stdin
if rlist[0] == 0:
return [embed.stdin_select()]
return __select(rlist, wlist, xlist, timeout)
select.select = patch_select
def patch_os_read(fd, sz):
return embed.os_read()
os.read = patch_os_read the embed module from main.c manage to store all keypressed/mouse events in a c-string that happen beetween two frame call ( either from xterm.js or from a replay ). stdin_select just returns that c-string lentgh while os_read returns a suitable pyobject and truncate the c-string at the same time preventing further read until next frame fixing emscripten select would allow pyodide to behave normally regarding TTYs. it's not a problem to implement tty ioctl on js side since both pyodide-micropython can all access js it is just a matter of having enough people that agree on how to do it. For now i'm dumping everything that can/should be fixed here https://github.com/pygame-web/platform_wasm/blob/main/platform_wasm/todo.py you are very welcome to give input, it has been years i did not touch ansi nb: but in the end it is not specific to web, and should work embedded in async any program too at least on posix OSes. |
Please just provide a simple normal event loop, ie without threads and too much OOP : async def async_mainloop():
while True:
ttydata = "" # os.read(fd)
process_events(ttydata)
paint_term()
await asyncio.sleep(0)
asyncio.run( async_mainloop() ) Not only it would solve wasm/wasi but should also serve for offscreen rendering and input replay tests. |
what you mean about without too much OOP? |
I disagree you are using pyodide proxies : they are not part of cpython. They are a one of possible implementations of interacting with a js host and there are others bridges of that kind and other compilers than emscripten. So i'm just hoping for a very simple and generic event loop that :
Leaving up to the platform to implementing read and write on a real (or not) local (or not) tty. Your general oop toolkit design is very clean, but imho oop/threading add no value to the core event loop itself because they hide too much of the I/O control flow and its implementation for outside viewer. i don't have a framework at all, i only use cpython-wasm with four file descriptors instead of the standard three ( in short ALTBUF has its own non blocking fd for input ) The select+os.read above is just common mockup for classic unix terminal handling which seems to suit other terminal toolkit but that should not even be required for a serial terminal (tx/rx no ioctl). regarding pyodide although i'm a contributor i am (was?) only interested in the module build system and the cpython emscripten support (which has been dropped for cpython 3.13 this month). I have no intention of diving in pyodide specifics and no one should have to when sticking to POSIX ( async, no threads, standards FD). i don't think you have to rewrite anything , just document the pyodide (driver input / render step / driver output) control flow so a simpler driver (eg based on async or requestAnimationFrame ) can be derived from it. |
Are you able to provide me an interface with those input/output stream I can test? About pyodide, I used a single thread and any extra TTkThreading objects are emulated through the built-in Javascript Timeout routines. I had also to rewrite the input routine since it doesn't provide a proper tty device. Any keypress is captured by: this.ttk_input = this.namespace.get("ttk_input");
this.term.onData((d, evt) => { this.ttk_input(d) }) and sent to pyTermKk through: def ttk_input(val):
kevt,mevt,paste = TTkInput.key_process(val)
if kevt or mevt:
TTkInput.inputEvent.emit(kevt, mevt)
if paste:
TTkInput.pasteEvent.emit(paste) It is not ideal because it skip an extra threaded routine I use to clear the input buffer, but for my needed was ok. |
cpython-wasm behaves the same as linux/mac/posix, the same async code is valid on desktop and also supports generators based greenthreads code: test: |
Are you able to provide me some instructions I can use to try my library on your framework? |
again, there's no framework it's normal posix cpython stdin is handled here https://github.com/pygame-web/showroom/blob/c0a07cb8a9bf8416eb31937c4e4e12dab1b090f1/src/test_vt100.py#L115 you don't have a linux or mac to run that code ? |
I am using linux. |
then the same code will work. |
no, because it already runs flawlessly on linux and I don't want to change the core routine. |
I noticed that when I was working on pyodide the os type was emscriptem |
the normal way to detect wasi or emscripten is testing sys.platform |
it is ok, as long I can detect it I can make the driver |
python3 -m pip install pygbag |
beware of blocking threads they can lock up browser tabs for good if you ever forget to add a yield on vsync. |
I made a simple python script I wanted to try: import platform
def main():
print("Eugenio")
print(f"Platform {platform.system()=}")
if __name__ == "__main__":
main() if I try to run it using: python -m pygbag --PYBUILD 3.12 --git --ume_block 0 main.py I get this error:
|
That's very weird those 404 are about files that are supposed to be on the github cdn ( and i can access them ) |
yes, now it works, the network I was using is not very stable. |
eg based on select.select + os.read ( works fine already with nurses2/batgrl and Textual
for cases where
sys.platform in ('emscripten','wasi')
( but not pyodide)eg typical render task could look like :
The text was updated successfully, but these errors were encountered: