map_each previously was written such that if a chain of mappings fed
each other, a deadlock could occur because while the first one was
mapped, the second callback gets invoked and tries to update the first
value while it's still being held.
This refactor switches from std Mutex to parking_lot, allowing me to
remove a workaround for needing to run drop callbacks in a separate
thread during the drop of a DynamicGuard.
In addition to that change, the lower level `map_generational` calls now
take a DynamicGuard as their parameter. This allows these functions to
drop ownership of the referenced data during the callback.
The map_each implementation takes advantage of this by ensuring that the
guard is dropped before set is invoked, minimizing potential lock overlaps.
With this refactor, some old code of mine with complex validations now works
again.
While working on the changelog, I realized I didn't provide a type that
allowed a third party developer to provide a
PlatformWindowImplementation. This type now completes it.
Closes#98
This finishes my initial refactoring of the dynamic system to add
support for several dataflows including:
- Pure data sources that can be implemented using an `Owned<T>` at the
root of a graph of `Dynamic<U>`/`DynamicReader<U>`s.
- Read-only data sinks. I thought this would be more useful across other
widgets, but in general, Progress and Label seem like the only types
that this applies to currently.
- The ability to mix/match Dynamic/DynamicReader in tuple-based
for_each/map_each.
This cascaded into a lot more work than expected. However, in general,
if one clones a `WidgetInstance` and shares it between two windows, it
should now work. Widget authors must ensure that when they cache
information, they do so with either a `WidgetCacheKey` or use a
`WindowLocal<T>` if per-window state is desired.
This is demonstrated in the debug-window example, where the counter of
open windows is next to a clone of the same button from the main window
that opens a new window.
While this was a workaround for a docs.rs issue (Px/Lp are not
linked), I decided having the shorter import path would look better in
the examples.
It probably wasn't necessary to update all of the references in the
internal code, but I decided it was worth the consistency.
Closes#91
There's some details to still figure out, which are in new issues:
- #109: When opening a window, no handle is returned that gives access to the
window from the opener. Technically this can all be wired up manually,
with exception of requeesting the window close.
- #107: How can a window close itself? Once we have a handle type, we still
need a mechanism to allow a button on a window request that the window
closes gracefully. The examples that currently close the window
call exit instad.
- Blur no longer expands the shadow geometry, but instead is clamped to
avoid overlapping drawing calls.
- Overlay now handles hit tests correctly with regards to the original
relative widget.
- Align was using an Into conversion that wasn't actually correct,
causing the contents to not actually get aligned in some situations.
- On Linux, `fm-match` is used to query for the default fonts.
- DynamicComponents now have their own trait and can now be specified
with a constant or dynamic.
- Roboto Flex is now always loaded when the feature is enabled.
Overriding the default sans serif font prefers the overridden value,
then roboto, then the result of fc-match/fontdb's default.
- Button now supports background colors being set on a transparent
button.
Debug printing widgets was quite verbose. While developing a widget, you
often want to see a full debug printout, but this feature assumes that
debug printing a WidgetInstance should show a summary of the widget, not
a full debug printout containing cached glyph information of every
label.
By default, summarize just calls Debug, but this extra layer allows
widgets to provide a more condensed summary and exclude details like
caches.
Originally, adding dbg!() around the theme example's UI yielded a
whopping 20,324 lines of text. The summary code only prints 3,858
lines.