Skip to content
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

Updating in a for or while loop #49

Open
kushalkolar opened this issue Dec 25, 2024 · 1 comment
Open

Updating in a for or while loop #49

kushalkolar opened this issue Dec 25, 2024 · 1 comment

Comments

@kushalkolar
Copy link
Contributor

Finally catching up with all this! Taking a look at the examples and wondering if this would be the right way to update the canvas in a for or while loop. It works but I'm not sure if this is the way it's intended to be used, without an event loop running.

import numpy as np
from rendercanvas.auto import RenderCanvas, loop

canvas = RenderCanvas(update_mode="ondemand")
context = canvas.get_context("bitmap")

for i in range(100):
    w, h = canvas.get_logical_size()
    shape = int(h) // 4, int(w) // 4

    bitmap = np.random.uniform(0, 255, shape).astype(np.uint8)
    context.set_bitmap(bitmap)
    canvas.force_draw()

related: pygfx/pygfx#667

I'm starting to think about how to implement this for fastplotlib, might help to have a mode where the canvas is updated only when an event occurs or when any buffer in the scene changes? Anyways that will be a separate issue which I'll think about later.

@almarklein
Copy link
Member

Yes, the way to go is to use force_draw(), also see the demo.py example:

elif event["key"] in " f":
# Force draw for 2 secs
print("force-drawing ...")
etime = time.time() + 2
i = 0
while time.time() < etime:
i += 1
canvas.force_draw()
print(f"Drew {i} frames in 2s.")

However, it is meant to be used only in special scenarios because it bypasses the normal event loop and scheduling, which means that there will also be no updates, unless you also flush the events etc. and then you are basically creating your own scheduler ...

In use-cases where you are running a simulation like pygfx/pygfx#667, I think it would be better to use something like:

async def do_my_simulation():
    for .... 
         do whatever you want to do
         but from time to time call
         asyncio.sleep(0)  # allow the window to stay active

and then run that together with the rendercanvas.asyncio.loop.

Would be good to cover this in an example! 🤔

might help to have a mode where the canvas is updated only when an event occurs or when any buffer in the scene changes?

No, that's what the "ondemand" mode is for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants