sciter-sdk / rust-sciter

Rust bindings for Sciter
https://sciter.com
MIT License
804 stars 76 forks source link

[Question] How to attach custom functions to main loop? #40

Closed woubuc closed 6 years ago

woubuc commented 6 years ago

I noticed that window.run_app() will run the main loop for the Sciter app and block until Sciter ends. Now I would like to run my own functions in the main loop as well, to intercept events and manipulate the Sciter host from my Rust application. How would I go about doing this? I can't seem to find anything about that in the documentation.

pravic commented 6 years ago

It can be done in the same way as in WinAPI or GTK — via events: https://sciter.com/sciter-ui-application-architecture/

In our case you have a sciter::HostHandler which is one per window. It manages resource loading and custom behavior (say, custom controls) creating.

And also you can attach one or more sciter::EventHandlers (one per DOM element, at least one for the root <html> element). They are for every possible event that could occur in UI.

So, basically you attach your event handler and do your work from its callbacks. They are called from the main thread (the same as the run_app() caller).

woubuc commented 6 years ago

I see, so the only way to run code repeatedly is through a timer?

My use case: I have a thread that does a bunch of work in the background, and I need to poll the results regularly from the main thread and update the UI in response. So it doesn't respond to a Sciter / UI event, it's basically just an if statement that should run in the application's main loop.

pravic commented 6 years ago

Well, this isn't specific to Sciter or any other GUI framework - most of them have the same event loop model, and usually you can't "inject" your code into the main loop. But there are options:

  1. You can "push" results instead of polling - i.e. send them to the main thread from workers. That would be the most efficient.
  2. Polling:
    • you can poll results from a background thread, collect them and send to UI
    • you can use timers; they are low-priority, though, and they are executed on idle (i.e. when there are no other UI events in queue)
    • (sciter-specific) there are animation callbacks, they are high-priority events and executed with 60-100 FPS
woubuc commented 6 years ago

I've been able to solve it using a timer. It's not perfect but it seems to work well enough. Thanks for the help!