Drivers
The native drivers that provide the interface, animation and network.
Contents
How a Program becomes Dart, in parts. Start with the introduction, then follow each part into the rendered output and the runtime it links against.
- Introduction — what the Dart target is, and how to read the rest of this section.
- Capabilities — which high-level features are possible, built in or through a library.
- Example — a full program using every keyword, and the Dart it renders to.
- Naming considerations — how Program's dotted names are carried into Dart.
- Entry point — starting a program and mounting it as a Flutter app.
- Drivers — the native drivers that provide the interface, animation and network.
- Runtime — the Reactive and Context machinery the rendered code links against.
- Native modules — the hand-written Dart behind
NATIVEfunctions. - Keywords — how each of Program's keywords renders to Dart.
- Project setup — the files and commands to build and run the rendered program.
- Reserved words — the words Dart keeps for itself, and how a colliding name is escaped.
Defining a driver
A driver is a class that drains one context channel and reconciles the resources it owns. Here is a
console driver: it drains the Console.Lines channel and prints each line that has
changed since the last cycle.
class ConsoleDriver implements Driver {
final Map<int, String> _lastById = {};
@override String get channel => 'Console.Lines';
@override DriverKind get kind => DriverKind.array;
@override void init(AddUpdates addUpdates) {}
@override
void dispatch(List<Line> emissions) {
for (final line in emissions) {
if (_lastById[line.id] != line.text) {
print(line.text);
_lastById[line.id] = line.text;
}
}
}
}
Registering it
A program lists the drivers it uses; the runtime opens a channel for each and never hardcodes one.
runApp(Program.Application(
() { Main(); },
[ ConsoleDriver() ],
));
How the runtime runs it
Each cycle the runtime opens the driver's channel, runs the reactive program (which emits into it),
drains it, and hands the list to dispatch:
Context.openArray('Console.Lines');
program = Reactive.Run(program, updates);
driver.dispatch(Context.drainArray('Console.Lines'));
A driver that produces events — a timer, a network reply — calls the
addUpdates it was given in init, which schedules the next cycle. The
interface driver is the same shape, only its channel is the nested widget tree and its
dispatch reconciles Flutter widgets, registering custom components that return a
Widget:
class MapView implements UiComponent {
@override String get name => 'Map.View';
@override
Widget render(Attributes attributes, RenderChildren renderChildren) {
return SizedBox(height: 400, child: GoogleMap(/* … */));
}
}