germaniumhq / mopyx

MoPyX is a MobX / Vue inspired reactive model driven UI library for Python. UI Toolkit independent.
BSD 3-Clause "New" or "Revised" License
37 stars 3 forks source link

using a specific render thread? #3

Open keturn opened 2 years ago

keturn commented 2 years ago

I see that there's a THREAD_CHECK debugging assertion. Any pointers for what to do when that's tripped?

Responding to model changes that happen on another thread is definitely a feature I'm looking for, but I guess that needs some integration with an event loop or dispatcher or some such thing.

Might there be a way to tag a render method so that, instead of getting invoked directly by the thread that changed the model, it sends it through some kind of "run later on main thread" handler?

bmustiata commented 2 years ago

Yeah, I agree a generic solution to deal with the rendering threads issues would be nice.

However, it isn't that simple.

There are two options:

  1. sync action model updates + renderings with a global lock. I'm not sure if that's "the way" to do things. This would have a significant performance impact as well, and I'm not even sure if it would work correctly especially if we are trying to render UI items, while on the other hand on model we keep editing it - changing items fields, etc. I remember having some issues in making it right, can't remember now exactly which.
  2. Integration with the rendering engine, so we enqueue the actions Integrations with the rendering engine aren't possible unless you know how to enqueue calls in the rendering thread. For QT look here for a sample: https://github.com/germaniumhq/felix/blob/master/germanium_build_monitor/ui/core.py#L34-L68

And here are some usages: https://github.com/germaniumhq/felix/blob/master/germanium_build_monitor/ui/jenkins_add/AddServerDialog.py#L140-L154 https://github.com/germaniumhq/felix/blob/master/germanium_build_monitor/mainapp.py#L72-L82

I hope that helps.

On Wed, Sep 14, 2022, 05:02 Kevin Turner @.***> wrote:

I see that there's a THREAD_CHECK debugging assertion. Any pointers for what to do when that's tripped?

Responding to model changes that happen on another thread is definitely a feature I'm looking for, but I guess that needs some integration with an event loop or dispatcher or some such thing.

Might there be a way to tag a render method so that, instead of getting invoked directly by the thread that changed the model, it sends it through some kind of "run later on main thread" handler?

— Reply to this email directly, view it on GitHub https://github.com/germaniumhq/mopyx/issues/3, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADPZCT4ESR54C2Y4I2F34DV6E523ANCNFSM6AAAAAAQL7UFZE . You are receiving this because you are subscribed to this thread.Message ID: @.***>

keturn commented 2 years ago

Yeah, that's the idea.

Does it work to put such a @ui_thread decorator on a @render method? I feared that breaking up the flow like that would confound whatever clever thing it is that associates model attributes with the specific renderers that access them.

bmustiata commented 2 years ago

You are right it won't work on the render function. Renderers are hierarchical, in order to know if there's no point in calling them. To make matters worse, the @ui_thread is now a defacto async function, so we wouldn't be able to build this rerender hierarchy. Whenever you do a call to a @ui_thread function, the parameters are encapsulated into an object, and posted on the other thread queue for execution. The function returns immediately, but the execution on the UI thread will happen later.

It would work if you put it on the action, where you update the model. BTW, the main logic can be moved to the regular thread, just when updating the values that would reflect in the UI, then you'd annotate that method with @ui_thread so it runs in the ui thread.

bmustiata commented 2 years ago

I marked this as an enhancement since I was thinking for a while to maybe move the @ui_thread QT function in its own package.