WIP suggestion: Simplify context lock lifetimes with lambdas
My suggestion on how to prevent double-read caused deadlocks in new/user code (and also fixes of existing ones).
The main change internally is that Context now holds Arc<Helper<Impl>> instead of Arc<RwLock<Impl>>, and Helper API consumes "transaction functors" instead of returning lock-guards. Speaking by example, ctx.input().screen_rect() now will be implemented as ctx.input(|i| i.screen_rect()).
Pros:
- Now it's way more clear when the Context is actually locked (only in lambda body), there is syntactically no way to extend its lock time.
- Now it's safe to use: locks in if-let statement, multiple locks in the same expression.
- Now it's little easier to read/write multiple fields under the same lock, instead of using multiple locks in the same expression.
Cons:
- Lambda syntax is kind of ugly for this purpose.
- Changes are trivial, but big and breaking the api.
- TBA
Notes:
- It's now harder to lock multiple fields at once, but that's a way to deadlock anyway.
Couple more words about feature state and motivation are placed in README.md.
Also, this PR features new "hello_world_par" example, which heavily uses Context in parallel (was used for smoke testing the branch).
Currently the code is a little bit dirty, not everything can compile, but I hope it's enough to get the idea and decide is the it worth it to develop these changes. I expect the possibility of early rejection so I hope to get some feedback from contributors about how useful will it be before continuing development.
Sorry for beeing so slow on this one, but I actually think this is a good idea. I've been hesitant due to the big breaking change and uglier syntax, but considering the number of deadlock issues we're seeing, I think this is the cleanest solution.
I'm gonna pick this up and try to get it up-to-date
Closed in favor of https://github.com/emilk/egui/pull/2625