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

Examples for custom async #10

Closed
johnpmayer opened this issue Jan 10, 2020 · 7 comments
Closed

Examples for custom async #10

johnpmayer opened this issue Jan 10, 2020 · 7 comments

Comments

@johnpmayer
Copy link

Moving this topic from ryanisaacg/quicksilver#552

Its seems pretty straightforward to make an async call (like, by using platter.load_file), await that call (blocking the application loop) and resume the program execution upon the completion of the call. This will work for situations like loading game initialization data, and may be acceptable in some situations like switching "levels".

However, what's not clear is how to setup custom non-blocking events. Something that feels like

  • Initialize my own custom event stream with a custom type
  • Setup async tasks, registered to the custom event stream which, upon completion, enqueues the task output as a custom event
  • During each "big loop"
    • Poll the blinds EventStream for window events until exhausted
    • Poll the custom event stream for custom events until exhausted
    • Run my main logic
      • Drawing
      • Triggering more async tasks, similarly registered to the custom event stream

I think that this would cover things like sockets/websockets (I have a long-lived connection to the server) as well as remote procedure calls and non-blocking resource loading.

@johnpmayer
Copy link
Author

johnpmayer commented Jan 10, 2020

Outlined it a bit more here master...johnpmayer:custom_event

@johnpmayer
Copy link
Author

I'm curious which of the two directions you're planning on taking this library:

  1. Users of blinds::run can spawn their own tasks, to be scheduled on the shared event loop, and whose output (single or stream) can be appended to the shared event stream. This would change the blinds API by making the event type generic and injecting some sort of spawn function.
  2. Users of blinds::run manage their own tasks independently and communicate with the main blinds run task via a shared Arc<RefCell>

I'm going to spike out #1 to see what that would feel like

@ryanisaacg
Copy link
Owner

I'm not entirely sure yet, to be honest. The current API does allow usage of Futures and Future-related code to run custom tasks, entirely without any support from blinds. Custom event types would make waiting for other events easier, but at the cost of complicating the API for other users.

@johnpmayer
Copy link
Author

I've put a bit more work into it. Two things that I ran into

  1. blinds assumes that there's only one task running, so try_run_one is a sensible way to check if the game loop terminated, but in my branch where I've spawned other work, it winds up terminating the window. So that would need to be changed
  2. Async closures don't seem to work the same as referencing a static function, particularly with the borrow checker. Probably I can hand roll the Future instead of using async but that would be annoying.

I agree on the trade-off; it's the expansion of both the more complicated EventStream type and the injection of the spawner which make the custom_run API a lot more complicated.

@johnpmayer
Copy link
Author

johnpmayer commented Jan 13, 2020

I guess it really boils down to: should the blinds event loop be something library users interact with or not.

@johnpmayer
Copy link
Author

Taking the other side; I think that would just be exposing an intended-to-be-user-managed event loop. Now that I've taken a dive into the codebase I think it would be straightforward to roll my own. Something more like my original proposal, where waiting for blinds events and waiting for custom events can both happen in the game loop but are otherwise independent phases.

@johnpmayer
Copy link
Author

I think that between #13 (merged) and #20 (not merged yet, but a more complex example which we may not decide to merge ever) this is resolved.

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