diff --git a/pygbag/support/cross/aio/__init__.py b/pygbag/support/cross/aio/__init__.py index 68f0947..1972935 100644 --- a/pygbag/support/cross/aio/__init__.py +++ b/pygbag/support/cross/aio/__init__.py @@ -350,8 +350,8 @@ def run(coro, *, debug=False): # the stepper when called from window.requestAnimationFrame() # https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame elif __EMSCRIPTEN__ or __wasi__: - # handle special sitecustomize() case - if coro.__name__ == "sitecustomize": + # handle special custom_site() case + if coro.__name__ == "custom_site": embed.run() run_called = False else: @@ -364,9 +364,9 @@ def run(coro, *, debug=False): elif run_called: pdb("273: aio.run called twice !!!") - # run called after a sitecustomize() completion - elif coro.__name__ != "sitecustomize": - pdb("360: * sitecustomize done *") + # run called after a custom_site() completion + elif coro.__name__ != "custom_site": + pdb("360: * custom_site done *") else: pdb("364: aio.run", coro.__name__) diff --git a/pygbag/support/cross/aio/toplevel.py b/pygbag/support/cross/aio/toplevel.py index 01a8dd0..f7001ed 100644 --- a/pygbag/support/cross/aio/toplevel.py +++ b/pygbag/support/cross/aio/toplevel.py @@ -90,11 +90,14 @@ async def get_repo_pkg(pkg_file, pkg, resume, ex): class AsyncInteractiveConsole(code.InteractiveConsole): instance = None + console = None + def __init__(self, locals, **kw): super().__init__(locals) self.compile.compiler.flags |= ast.PyCF_ALLOW_TOP_LEVEL_AWAIT self.line = "" + self.buffer = [] self.one_liner = None self.opts = kw self.coro = None @@ -138,6 +141,9 @@ def process_shell(self, shell, line, **env): return catch def runsource(self, source, filename="", symbol="single"): + if len(self.buffer): + symbol = "exec" + try: code = self.compile(source, filename, symbol) except SyntaxError: @@ -188,13 +194,7 @@ def runcode(self, code): return sys.print_exception(ex, limit=-1) - def raw_input(self, prompt): - maybe = embed.readline() - if len(maybe): - return maybe - else: - return None - # raise EOFError + async def interact(self): try: @@ -262,7 +262,9 @@ def start_console(cls, shell): shell=shell, ) - asyncio.create_task(cls.instance.interact()) + if cls.console is None: + asyncio.create_task(cls.instance.interact()) + cls.console = cls.instance @classmethod async def start_toplevel(cls, shell, console=True): @@ -276,3 +278,7 @@ async def start_toplevel(cls, shell, console=True): if console: cls.start_console(shell) + + + + diff --git a/pygbag/support/pythonrc.py b/pygbag/support/pythonrc.py index 85af516..66fc94f 100644 --- a/pygbag/support/pythonrc.py +++ b/pygbag/support/pythonrc.py @@ -557,12 +557,75 @@ async def exec(cls, sub, *args): return elif isinstance(sub, [str, Path]): # subprocess - print("N/I", stb) - + print("N/I", sub) else: await sub + @classmethod + async def preload(cls, main, callback=None): + # get a relevant list of modules likely to be imported + # and prefetch them if found in repo trees + await TopLevel_async_handler.async_imports(*TopLevel_async_handler.list_imports(None, main), callback=callback) + PyConfig.imports_ready = True + + + @classmethod + async def source(cls, main, *args): + code = "" + + def check_code(file_name): + nonlocal code + maybe_sync = False + has_pygame = False + with open(file_name,"r") as code_file: + code = code_file.read() + if code.find('asyncio.run')<0: + print("575 possibly synchronous code found") + maybe_sync = True + + has_pygame = code.find('display.flip(')>0 or code.find('display.update(')>0 + + if maybe_sync and has_pygame: + return False + return True + + if check_code(main): + print("585: running main and resuming EventTarget in a few seconds") + aio.defer(execfile, (main,), {} ) + + # makes all queued events arrive after program has looped a few cycles + # note that you need a call to asyncio.run in your main to continue past + # that check + while not aio.run_called: + await asyncio.sleep(.1) + + + # if you don't reach that step + # your main.py has an infinite sync loop somewhere ! + print("590: ready") + + + aio.create_task(platform.EventTarget.process()) + + pdb("platform event loop started") + + + else: + for base in ('pygame','pg'): + for func in ('flip','update'): + block = f'{base}.display.{func}()' + code = code.replace( block, f'{block};await asyncio.sleep(0)') + + #print(" -> won't run synchronous code with a pygame loop") + shell.debug() + + TopLevel_async_handler.instance.eval(code) + TopLevel_async_handler.instance.start_console(shell) + + + + def _process_args(argv, env): import inspect @@ -856,6 +919,27 @@ class TopLevel_async_handler(aio.toplevel.AsyncInteractiveConsole): repodata = "repodata.json" + + + def raw_input(self, prompt): + if len(self.buffer): + return self.buffer.pop(0) + + maybe = embed.readline() + + if len(maybe): + return maybe + else: + return None + # raise EOFError + + + def eval(self, source): + for line in source.split('\n'): + self.buffer.append( line ) + self.buffer.append("") + print(f"917 {len(self.buffer)} lines queued for async eval") + @classmethod def scan_imports(cls, code, filename, load_try=False): root = ast.parse(code, filename) @@ -954,11 +1038,6 @@ def default_cb(pkg, error=None): # refresh = False # for pkg in packages: # pkg_info = cls.repos[0]["packages"].get(pkg, None) - - # if pkg_info is None: - # pdb(f'144: package "{pkg}" not found in repodata') - # continue - # file_name = pkg_info.get("file_name", "") # valid = False # if file_name: diff --git a/static/default.tmpl b/static/default.tmpl index 44750aa..02160e2 100644 --- a/static/default.tmpl +++ b/static/default.tmpl @@ -1,533 +1,479 @@ - - - {{cookiecutter.title}} - - - - - - - - - - - - - - - - - - - - - -
- -
Downloading...
-
- -
-
- - - - - -
- -
- - - - - -
- - - - -
-
-
- - - - - + + + {{cookiecutter.title}} + + + + + + + + + + + + + + + + + + + + + +
+ +
Downloading...
+
+ +
+
+ + + + + +
+ +
+ + + + + +
+ + + + +
+
+
+ + + + + diff --git a/static/pythons.js b/static/pythons.js index 0aa1ca2..028440d 100644 --- a/static/pythons.js +++ b/static/pythons.js @@ -440,9 +440,9 @@ if os.path.isfile(fn): def async_exec(filename): exec(open(filename).read(), globals(), globals()) import asyncio - async def sitecustomize(): + async def custom_site(): aio.create_task(platform.EventTarget.process()) - asyncio.run( sitecustomize() ) + asyncio.run( custom_site() ) async_exec("/data/data/org.python/assets/main.py") else: print(fn,"not found")