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::HOSTand the extension at indexiisOriginId(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::slotsthat means “every name the host declares under my namespace”: for an extension that learns its slots after it loads.fillmatches any declared name against it andfinishhas 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::Nullwith a'staticaddress, 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_withcarries one;Ui::slotcallsFill::fillat the position the host declared, andUi::finishcallsFill::finishonce the host’s view is done.
Functions§
- full_
name namespace/name, ornamealone 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.