More refactoring of tree construction; don't depend on Arc::get_mut

This commit is contained in:
Matt Campbell 2022-11-30 13:46:33 -06:00
parent 345b3c77d1
commit 4a273c754d
2 changed files with 33 additions and 38 deletions

View file

@ -111,23 +111,17 @@ impl ContextImpl {
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
if self.is_accesskit_enabled { if self.is_accesskit_enabled {
assert!(self.output.accesskit_update.is_none());
let id = crate::accesskit_root_id(); let id = crate::accesskit_root_id();
let accesskit_id = id.accesskit_id(); let node = Box::new(accesskit::Node {
let node = Arc::new(accesskit::Node {
role: accesskit::Role::Window, role: accesskit::Role::Window,
transform: Some( transform: Some(
accesskit::kurbo::Affine::scale(self.input.pixels_per_point().into()).into(), accesskit::kurbo::Affine::scale(self.input.pixels_per_point().into()).into(),
), ),
..Default::default() ..Default::default()
}); });
let nodes = vec![(accesskit_id, node)]; let mut nodes = IdMap::default();
self.frame_state.accesskit_nodes.insert(id, nodes.len() - 1); nodes.insert(id, node);
self.output.accesskit_update = Some(accesskit::TreeUpdate { self.frame_state.accesskit_nodes = Some(nodes);
nodes,
tree: Some(accesskit::Tree::new(accesskit_id)),
focus: None,
});
} }
} }
@ -159,21 +153,14 @@ impl ContextImpl {
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
fn accesskit_node(&mut self, id: Id, parent_id: Option<Id>) -> &mut accesskit::Node { fn accesskit_node(&mut self, id: Id, parent_id: Option<Id>) -> &mut accesskit::Node {
let update = self.output.accesskit_update.as_mut().unwrap(); let nodes = self.frame_state.accesskit_nodes.as_mut().unwrap();
let nodes = &mut update.nodes; if !nodes.contains_key(&id) {
let node_map = &mut self.frame_state.accesskit_nodes; nodes.insert(id, Default::default());
let index = node_map.get(&id).copied().unwrap_or_else(|| {
let accesskit_id = id.accesskit_id();
nodes.push((accesskit_id, Arc::new(Default::default())));
let index = nodes.len() - 1;
node_map.insert(id, index);
let parent_id = parent_id.unwrap_or_else(crate::accesskit_root_id); let parent_id = parent_id.unwrap_or_else(crate::accesskit_root_id);
let parent_index = node_map.get(&parent_id).unwrap(); let parent = nodes.get_mut(&parent_id).unwrap();
let parent = Arc::get_mut(&mut nodes[*parent_index].1).unwrap(); parent.children.push(id.accesskit_id());
parent.children.push(accesskit_id); }
index nodes.get_mut(&id).unwrap()
});
Arc::get_mut(&mut nodes[index].1).unwrap()
} }
} }
@ -1045,15 +1032,23 @@ impl Context {
let mut platform_output: PlatformOutput = std::mem::take(&mut self.output()); let mut platform_output: PlatformOutput = std::mem::take(&mut self.output());
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
if let Some(accesskit_update) = &mut platform_output.accesskit_update { {
let has_focus = self.input().raw.has_focus; let nodes = self.frame_state().accesskit_nodes.take();
accesskit_update.focus = has_focus.then(|| { if let Some(nodes) = nodes {
let focus_id = self.memory().interaction.focus.id; let has_focus = self.input().raw.has_focus;
focus_id.map_or_else( let root_id = crate::accesskit_root_id().accesskit_id();
|| crate::accesskit_root_id().accesskit_id(), platform_output.accesskit_update = Some(accesskit::TreeUpdate {
|id| id.accesskit_id(), nodes: nodes
) .into_iter()
}); .map(|(id, node)| (id.accesskit_id(), Arc::from(node)))
.collect(),
tree: Some(accesskit::Tree::new(root_id)),
focus: has_focus.then(|| {
let focus_id = self.memory().interaction.focus.id;
focus_id.map_or(root_id, |id| id.accesskit_id())
}),
});
}
} }
// if repaint_requests is greater than zero. just set the duration to zero for immediate // if repaint_requests is greater than zero. just set the duration to zero for immediate
@ -1585,8 +1580,8 @@ impl Context {
parent_id: Option<Id>, parent_id: Option<Id>,
) -> Option<RwLockWriteGuard<'_, accesskit::Node>> { ) -> Option<RwLockWriteGuard<'_, accesskit::Node>> {
let ctx = self.write(); let ctx = self.write();
ctx.output ctx.frame_state
.accesskit_update .accesskit_nodes
.is_some() .is_some()
.then(move || RwLockWriteGuard::map(ctx, |c| c.accesskit_node(id, parent_id))) .then(move || RwLockWriteGuard::map(ctx, |c| c.accesskit_node(id, parent_id)))
} }

View file

@ -43,7 +43,7 @@ pub(crate) struct FrameState {
pub(crate) scroll_target: [Option<(RangeInclusive<f32>, Option<Align>)>; 2], pub(crate) scroll_target: [Option<(RangeInclusive<f32>, Option<Align>)>; 2],
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
pub(crate) accesskit_nodes: IdMap<usize>, pub(crate) accesskit_nodes: Option<IdMap<Box<accesskit::Node>>>,
} }
impl Default for FrameState { impl Default for FrameState {
@ -57,7 +57,7 @@ impl Default for FrameState {
scroll_delta: Vec2::ZERO, scroll_delta: Vec2::ZERO,
scroll_target: [None, None], scroll_target: [None, None],
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
accesskit_nodes: Default::default(), accesskit_nodes: None,
} }
} }
} }
@ -85,7 +85,7 @@ impl FrameState {
*scroll_target = [None, None]; *scroll_target = [None, None];
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
{ {
accesskit_nodes.clear(); *accesskit_nodes = None;
} }
} }