feat: prefetch visible observation frontier
This commit is contained in:
@@ -299,7 +299,9 @@ impl App {
|
||||
#[must_use]
|
||||
pub fn new(endpoint: impl Into<String>) -> Self {
|
||||
let mut entries = BTreeMap::new();
|
||||
entries.insert("/".into(), EntryView::placeholder("/"));
|
||||
let mut root = EntryView::placeholder("/");
|
||||
root.expanded = true;
|
||||
entries.insert("/".into(), root);
|
||||
Self {
|
||||
endpoint: endpoint.into(),
|
||||
connection: ConnectionState::Disconnected,
|
||||
@@ -556,7 +558,6 @@ impl App {
|
||||
let entry = self.ensure_entry(&observation.path);
|
||||
entry.children = children.clone();
|
||||
entry.tree_state = ViewState::from(&observation.state);
|
||||
entry.expanded = true;
|
||||
for path in children {
|
||||
self.ensure_entry(&path);
|
||||
}
|
||||
@@ -876,6 +877,6 @@ mod tests {
|
||||
wip_client::SecurityContext::new("test"),
|
||||
)
|
||||
.unwrap();
|
||||
client.prepare_observe(&session, "/", 0).unwrap().id
|
||||
client.refresh_object(&session, "/").unwrap().id
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,6 +608,36 @@ mod tests {
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn observed_empty_visible_entry_is_labeled_without_expansion() {
|
||||
let mut app = App::new("https://example.test/wip/");
|
||||
{
|
||||
let root = app.entries.get_mut("/").unwrap();
|
||||
root.children = vec!["/empty".into()];
|
||||
root.tree_state = ViewState::Fresh;
|
||||
}
|
||||
app.entries.insert(
|
||||
"/empty".into(),
|
||||
EntryView {
|
||||
path: "/empty".into(),
|
||||
object: Some(Object {
|
||||
name: "empty".into(),
|
||||
description: None,
|
||||
interfaces: vec![],
|
||||
r#ref: None,
|
||||
validator: None,
|
||||
}),
|
||||
state: ViewState::Fresh,
|
||||
children: vec![],
|
||||
tree_state: ViewState::Fresh,
|
||||
expanded: false,
|
||||
},
|
||||
);
|
||||
|
||||
let snapshot = rendered(&app, 80, 20);
|
||||
assert!(snapshot.contains("empty [empty]"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn snapshot_contains_non_color_state_markers_and_hides_validators() {
|
||||
let mut app = App::new("https://example.test/wip/");
|
||||
|
||||
@@ -304,7 +304,7 @@ impl<T: Transport> Runtime<T> {
|
||||
/// Starts or restarts observation at Worldspace `/`.
|
||||
pub fn connect(&mut self) {
|
||||
self.app.connection = ConnectionState::Connecting;
|
||||
match self.client.prepare_observe(&self.session, "/", 1) {
|
||||
match self.client.refresh_children(&self.session, "/") {
|
||||
Ok(request) => self.dispatch(request, InFlightKind::Tree("/".into()), false),
|
||||
Err(error) => self.local_error("connect", error),
|
||||
}
|
||||
@@ -317,6 +317,9 @@ impl<T: Transport> Runtime<T> {
|
||||
for action in actions {
|
||||
quit |= self.perform(action);
|
||||
}
|
||||
if !quit {
|
||||
self.reconcile_visible_lookahead();
|
||||
}
|
||||
quit
|
||||
}
|
||||
|
||||
@@ -347,16 +350,14 @@ impl<T: Transport> Runtime<T> {
|
||||
|
||||
fn perform(&mut self, action: Action) -> bool {
|
||||
match action {
|
||||
Action::Expand { path } => match self.client.prepare_observe(&self.session, &path, 1) {
|
||||
Action::Expand { path } => match self.client.refresh_children(&self.session, &path) {
|
||||
Ok(request) => self.dispatch(request, InFlightKind::Tree(path), false),
|
||||
Err(error) => self.local_error("tree expansion", error),
|
||||
},
|
||||
Action::Refresh { path } => {
|
||||
match self.client.prepare_observe(&self.session, &path, 1) {
|
||||
Ok(request) => self.dispatch(request, InFlightKind::Tree(path), false),
|
||||
Err(error) => self.local_error("subtree refresh", error),
|
||||
}
|
||||
}
|
||||
Action::Refresh { path } => match self.client.refresh_children(&self.session, &path) {
|
||||
Ok(request) => self.dispatch(request, InFlightKind::Tree(path), false),
|
||||
Err(error) => self.local_error("subtree refresh", error),
|
||||
},
|
||||
Action::FetchInterface(reference) => {
|
||||
match self.client.prepare_interface(&self.session, &reference) {
|
||||
Ok(request) => {
|
||||
@@ -393,7 +394,7 @@ impl<T: Transport> Runtime<T> {
|
||||
Action::Reconnect => self.connect(),
|
||||
Action::NavigateEntry(path) => {
|
||||
self.app.navigate_entry(path.clone());
|
||||
match self.client.prepare_observe(&self.session, &path, 0) {
|
||||
match self.client.refresh_object(&self.session, &path) {
|
||||
Ok(request) => self.dispatch(request, InFlightKind::Object(path), false),
|
||||
Err(error) => self.local_error("Entry navigation", error),
|
||||
}
|
||||
@@ -403,6 +404,24 @@ impl<T: Transport> Runtime<T> {
|
||||
false
|
||||
}
|
||||
|
||||
fn reconcile_visible_lookahead(&mut self) {
|
||||
if self.app.connection != ConnectionState::Connected {
|
||||
return;
|
||||
}
|
||||
for path in self.app.visible_paths() {
|
||||
match self.client.ensure_children_observed(&self.session, &path) {
|
||||
Ok(Some(request)) => {
|
||||
self.dispatch(request, InFlightKind::Tree(path), false);
|
||||
}
|
||||
Ok(None) => {}
|
||||
Err(error) => {
|
||||
self.local_error("observation lookahead", error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn dispatch(&mut self, request: PreparedRequest, kind: InFlightKind, operation: bool) {
|
||||
let id = request.id;
|
||||
self.app.request_started(id.get(), kind.clone());
|
||||
@@ -567,6 +586,7 @@ impl<T: Transport> Runtime<T> {
|
||||
}
|
||||
}
|
||||
self.reconcile_authoritative();
|
||||
self.reconcile_visible_lookahead();
|
||||
}
|
||||
|
||||
fn apply_completion(&mut self, completion: Completion, kind: Option<&InFlightKind>) {
|
||||
|
||||
Reference in New Issue
Block a user