What's new in 2.0
The three breaking changes 1.x announced, delivered together. Nothing here needs more than a rename,
a delete or a decision about color — Migrating to 2.0 is the edit list, and the
changelog is the full record.
Widgets draw and hand back what is left
IArlecchinoWidget.Place is now Draw, and the interface has one member:
SurfaceRegion Draw(SurfaceRegion region);
It paints the widget and answers what is left of the region underneath, so a view stacks things without counting rows:
private readonly StatusBar _header;
private readonly Tabs _tabs;
private readonly ListBox<Mod> _list;
private readonly Surface surface;
var rest = _header.Draw(surface.Content);
var below = _tabs.Draw(rest);
_list.Draw(below);
The obsolete void Draw is gone, along with the ARL0001 diagnostic id that existed to let its
deprecation be silenced on its own. See Widgets.
The framework's own colors are the default
new ThemePalette() is now crimson titles, bone text, ash borders and an ink cursor row rather than
the terminal's plain sixteen, so an application that never called UseTheme looks like Arlecchino.
ThemePalette.Basic is exactly the old defaults, and UseTheme(ThemePalette.Basic) is the whole of
the way back. ThemePalette.Arlecchino still exists and still means the same thing; it is only
redundant now. See Theming.
The dispatcher is gone
UiDispatcher is removed. The queue it held moved into FrameThread, the type that already knew
which thread draws, so handing a result back from background work is one static call with nothing
injected:
private IReadOnlyList<Mod> _rows = [];
FrameThread.Post(() => _rows = loaded);
AsyncAtom<T> and ViewLifetime no longer take a dispatcher either: new AsyncAtom<T>(initial) and
new ViewLifetime().
Everything else about posting is unchanged: it is safe from any thread, runs in order just before the next frame, asks for that frame by itself, and reports an action that threw without dropping the rest. See The frame loop.
Added
FrameThread.DiscardPending()drops work that was posted and can no longer run — which is what giving up the last claim on the drawing thread does by itself, and whatArlecchinoTestHostdoes as it is disposed, so one test's leftovers never run inside the next.ThemePalette.Basic, the sixteen plain colors that were the default before this release.
Fixed
Posting work while nothing is drawing no longer runs it inline. FrameThread.Post used to run the
action on the calling thread when no frame loop had claimed one, so an action that posted itself — the
ordinary way to say "again next frame" — recursed until the stack ended instead of queueing. It always
queues now.
What came just before it
1.3.0 is worth knowing about even coming from 1.2, because it changed where input runs. The reader
thread used to route what it read there and then, so a key press changed the selection, the modal
stack, the route and any atom it touched while the drawing loop was reading the same things.
The reader now queues what it reads and the frame loop drains the queue at the top of each turn,
before the ticker and before drawing. Everything an application writes is touched by one thread, which
is what the documentation already claimed, and a key press costs at most one frame of latency — 16 ms
at the default rate. FrameThread.Verify is what turns that from a claim into a check.