pglet / pglet-python

Python client for Pglet - build real-time interactive web apps in Python
MIT License
18 stars 7 forks source link

Feature query: event chaining #40

Open mikaelho opened 2 years ago

mikaelho commented 2 years ago

Does pglet server and the python client support any methods for chaining events or other ways to run simple animations defined in Python?

A simple example scenario would be where an error popup is displayed, then after a small delay it goes away.

In theory this would seem feasible, if I understand the "command" channel between the client and the server correctly. On Python side, asyncio would provide a convenient programming model for this.

mikaelho commented 2 years ago

Correcting myself (again), I see that the client-server architecture of pglet already handles the basics of this very nicely, even while Python stays in "single-threaded" mode, as long as you call update at the right places. E.g.

original_background_color = my_control.bgcolor
my_control.bgcolor = 'red'
page.update()
time.sleep(1)
my_control.bgcolor = original_background_color
page.update()

And each event handler seems to be a separate "thread", so this works as expected also when several events are running concurrently. Very nice, very powerful.

Do you see underlying consistency/capacity issues if you have e.g. too many events waiting too long?

FeodorFitsner commented 2 years ago

Considering there is a human on the other side of the wire (browser) I wouldn't expect too many events generated (clicks, typings, etc.). However, my main concern would be thread-safe update of a page tree if there are many event handlers in separate threads. Page object with all its controls is not currently thread-safe. I tried doing a proof-of-concept of thread-safe Page control in C#, but apparently it's kind of challenging task. So, my advice would be doing sychronization in the user app itself with some global lock/mutex.

FeodorFitsner commented 2 years ago

But yes, animations could be done in the client code, especially nice if you wrap it into a custom "component" like in Todo example: https://github.com/pglet/examples/blob/main/python/todo/todo-complete.py

mikaelho commented 2 years ago

I know it is a completely different can of worms and not a priority right now, but exposing animation properties would enable much flashier UIs.

I do have an unfinished "pure Python web coding" project that had a nice with animation() context manager to handle the animations very cleanly in Python, but of course anything like that would rely on support from the protocol.

FeodorFitsner commented 2 years ago

Sounds interesting. How does the animation look like in Python code? Could you give me a few examples?

mikaelho commented 2 years ago

To be exact, the animation parameters are managed in Python, and then passed to js where they are used more or less as-is in animate calls.

The context manager is here. It supports nested contexts like this:

def test_animation_contextmanager():
    assert _animation_context() is None

    with animation(0.3):
        assert _animation_context().duration == 0.3

        with animation(1.0, 'ease-in'):
            assert _animation_context().duration == 1.0
            assert _animation_context().ease == 'ease-in'

        assert _animation_context().duration == 0.3
        assert _animation_context().ease is None

    assert _animation_context() is None

And convenience functions for individual animation properties like:

with duration(3):
    assert _animation_context().duration == 3

Whenever I set the value of an attribute corresponding to a CSS value, I store the current state of the above animation context and relay it to js.

Not sure how directly this would translate to the pglet approach, but happy to participate if you want to pursue this on any level.