Skip to main content

Module slot

Module slot 

Source
Expand description

Slots: the places a host declares in its own view for an extension to fill, with parameters in and replies out.

A slot is a position, not a node. Ui::slot (or slot_with) is a call the host makes anywhere among its children, and whatever fills it draws then and there, as children of the node the host is inside. The filling is done by whatever implements Fill, which the frame was begun with (Core::frame_with); the windowed runner hands in its Extensions. An app that loads no extensions never meets this module.

Slot names are namespaced, and the host decides the namespace. An extension names the slots it fills in its own vocabulary ("panel", "status", no / in them). The host gives each extension a namespace when it loads it (Extensions::push_as; Extensions::push uses the extension’s own name) and declares slots by their full name: ui.slot("fs/panel") is the "panel" of the extension the host calls fs. The same plugin loaded twice is two namespaces with two sets of slots.

use kui_core::slot::{full_name, split_name, Extensions, ROOT_SLOT};

assert_eq!(full_name("fs", "panel"), "fs/panel");
assert_eq!(split_name("left/fs/panel"), ("left/fs", "panel"));
assert_eq!(split_name("root"), ("", ROOT_SLOT));

// The runner's list; `push_as(namespace, Box<dyn Extension>)` loads one.
let exts = Extensions::new();
assert!(exts.is_empty());

The reserved slot name "root" (ROOT_SLOT) is what an extension listing no slots fills: ns/root, once after the host’s view. A host that declares ui.slot("ns/root") itself moves that fill to the position it chose.

An extension may host extensions of its own, by the same mechanism one level down: Fill::add loads one while a frame is being built, under a namespace of its own in the same list; a guest’s ui.slot(..) declares a slot like anyone’s, except that it cannot fill itself (a cycle is the recursive-slot warning and an empty position); and replies go to whoever declared the slot (Extensions::route), which for every extension the host declared is the host.

Structs§

Extensions
The runner’s extensions, each under the namespace the host gave it. Origins are positions here: the host is OriginId::HOST and the extension at index i is OriginId(i + 1), which is what an event’s origin indexes back into.
Slot
Which slot an extension is filling, handed to Extension::view.

Constants§

ANY_SLOT
The one entry in Extension::slots that means “every name the host declares under my namespace”: for an extension that learns its slots after it loads. fill matches any declared name against it and finish has nothing to warn about for it.
MAX_REPLY_HOPS
How many times a reply may be answered by another reply before the rest go to the host instead (Extensions::route). Nesting is a few levels deep in anything sane; this is the bound that keeps two extensions answering each other from being an infinite loop.
NAMESPACE_SEPARATOR
What separates a namespace from a slot name in a full name. A namespace may contain it (the host chooses namespaces, and "left/fs" is a fine one); a slot name an extension lists may not, so a full name splits at its last one.
ROOT_SLOT
The reserved slot name an extension listing none fills.

Statics§

NULL_PARAMS
Value::Null with a 'static address, for a slot with no params.

Traits§

Fill
What fills slots: the runner’s extension list, or a test’s stand-in. A frame begun with Core::frame_with carries one; Ui::slot calls Fill::fill at the position the host declared, and Ui::finish calls Fill::finish once the host’s view is done.

Functions§

full_name
namespace/name, or name alone when the namespace is empty.
split_name
Splits a full slot name at its last separator into (namespace, name); a name with none has the empty namespace.