Skip to content

Commit

Permalink
refactor!: New C API for tree updates (#263)
Browse files Browse the repository at this point in the history
  • Loading branch information
mwcampbell authored Jul 30, 2023
1 parent 63c1715 commit b260a86
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 87 deletions.
2 changes: 1 addition & 1 deletion bindings/c/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ after_includes = """#ifdef _WIN32
usize_is_size_t = true

[export]
include = ["Size", "tree_update", "Vec2"]
include = ["Size", "Vec2"]
prefix = "accesskit_"
renaming_overrides_prefixing = true

Expand Down
47 changes: 19 additions & 28 deletions bindings/c/examples/windows/hello_world.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,11 @@ void window_state_free(struct window_state *state) {
free(state);
}

accesskit_opt_node_id window_state_focus(struct window_state *state) {
accesskit_opt_node_id result;
result.has_value = state->is_window_focused;
if (result.has_value) {
result.value = state->focus;
void window_state_set_tree_update_focus(struct window_state *state,
accesskit_tree_update *update) {
if (state->is_window_focused) {
accesskit_tree_update_set_focus(update, state->focus);
}
return result;
}

accesskit_node *window_state_build_root(struct window_state *state) {
Expand All @@ -106,21 +104,17 @@ accesskit_tree_update *window_state_build_initial_tree(
build_button(BUTTON_1_ID, "Button 1", state->node_classes);
accesskit_node *button_2 =
build_button(BUTTON_2_ID, "Button 2", state->node_classes);
accesskit_tree_update *result =
accesskit_tree_update_new((state->announcement != NULL) ? 4 : 3);
result->tree.has_value = true;
result->tree.value = accesskit_tree_new(WINDOW_ID);
result->focus = window_state_focus(state);
result->ids[0] = WINDOW_ID;
result->nodes[0] = root;
result->ids[1] = BUTTON_1_ID;
result->nodes[1] = button_1;
result->ids[2] = BUTTON_2_ID;
result->nodes[2] = button_2;
accesskit_tree_update *result = accesskit_tree_update_with_capacity(
(state->announcement != NULL) ? 4 : 3);
accesskit_tree_update_set_tree(result, accesskit_tree_new(WINDOW_ID));
window_state_set_tree_update_focus(state, result);
accesskit_tree_update_push_node(result, WINDOW_ID, root);
accesskit_tree_update_push_node(result, BUTTON_1_ID, button_1);
accesskit_tree_update_push_node(result, BUTTON_2_ID, button_2);
if (state->announcement != NULL) {
result->ids[3] = ANNOUNCEMENT_ID;
result->nodes[3] =
accesskit_node *announcement =
build_announcement(state->announcement, state->node_classes);
accesskit_tree_update_push_node(result, ANNOUNCEMENT_ID, announcement);
}
return result;
}
Expand Down Expand Up @@ -165,12 +159,10 @@ void window_state_press_button(struct window_state *state,
accesskit_node *announcement =
build_announcement(text, state->node_classes);
accesskit_node *root = window_state_build_root(state);
accesskit_tree_update *update = accesskit_tree_update_new(2);
update->ids[0] = ANNOUNCEMENT_ID;
update->nodes[0] = announcement;
update->ids[1] = WINDOW_ID;
update->nodes[1] = root;
update->focus = window_state_focus(state);
accesskit_tree_update *update = accesskit_tree_update_with_capacity(2);
accesskit_tree_update_push_node(update, ANNOUNCEMENT_ID, announcement);
accesskit_tree_update_push_node(update, WINDOW_ID, root);
window_state_set_tree_update_focus(state, update);
accesskit_windows_queued_events *events =
accesskit_windows_adapter_update(state->adapter, update);
accesskit_windows_queued_events_raise(events);
Expand All @@ -184,10 +176,9 @@ struct window_state *get_window_state(HWND window) {
void update_focus(HWND window, bool is_window_focused) {
struct window_state *state = get_window_state(window);
state->is_window_focused = is_window_focused;
accesskit_opt_node_id focus = window_state_focus(state);
if (state->adapter != NULL) {
accesskit_tree_update *update = accesskit_tree_update_new(0);
update->focus = focus;
accesskit_tree_update *update = accesskit_tree_update_new();
window_state_set_tree_update_focus(state, update);
accesskit_windows_queued_events *events =
accesskit_windows_adapter_update(state->adapter, update);
accesskit_windows_queued_events_raise(events);
Expand Down
91 changes: 48 additions & 43 deletions bindings/c/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,8 +911,6 @@ impl tree {
}
}

opt_struct! { opt_tree, tree }

impl From<tree> for Tree {
fn from(tree: tree) -> Self {
Self {
Expand All @@ -922,65 +920,72 @@ impl From<tree> for Tree {
}
}

/// Use `accesskit_tree_update_new` to create this struct. Do not reallocate `ids` and `nodes`.
#[repr(C)]
pub struct tree_update {
pub node_count: usize,
pub ids: *mut node_id,
pub nodes: *mut *mut node,
pub tree: opt_tree,
pub focus: opt_node_id,
_private: [u8; 0],
}

impl CastPtr for tree_update {
type RustType = tree_update;
type RustType = TreeUpdate;
}

impl BoxCastPtr for tree_update {}

impl tree_update {
#[no_mangle]
pub extern "C" fn accesskit_tree_update_new(node_count: usize) -> *mut tree_update {
let mut ids = Vec::with_capacity(node_count);
let mut nodes = Vec::with_capacity(node_count);
let update = tree_update {
node_count,
ids: ids.as_mut_ptr(),
nodes: nodes.as_mut_ptr(),
tree: opt_tree::default(),
focus: opt_node_id::default(),
pub extern "C" fn accesskit_tree_update_new() -> *mut tree_update {
let update = TreeUpdate::default();
BoxCastPtr::to_mut_ptr(update)
}

#[no_mangle]
pub extern "C" fn accesskit_tree_update_with_capacity(capacity: usize) -> *mut tree_update {
let update = TreeUpdate {
nodes: Vec::with_capacity(capacity),
..Default::default()
};
mem::forget(ids);
mem::forget(nodes);
BoxCastPtr::to_mut_ptr(update)
}

#[no_mangle]
pub extern "C" fn accesskit_tree_update_free(update: *mut tree_update) {
drop(TreeUpdate::from(box_from_ptr(update)));
drop(box_from_ptr(update));
}
}

impl From<Box<tree_update>> for TreeUpdate {
fn from(update: Box<tree_update>) -> Self {
let ids = unsafe {
Vec::from_raw_parts(
update.ids as *mut NodeId,
update.node_count,
update.node_count,
)
};
let nodes =
unsafe { Vec::from_raw_parts(update.nodes, update.node_count, update.node_count) };
Self {
nodes: ids
.into_iter()
.zip(nodes.into_iter().map(box_from_ptr))
.map(|(id, node)| (id, *node))
.collect::<Vec<(NodeId, Node)>>(),
tree: update.tree.into(),
focus: update.focus.into(),
}
/// Appends the provided node to the tree update's list of nodes.
/// Takes ownership of `node`.
#[no_mangle]
pub extern "C" fn accesskit_tree_update_push_node(
update: *mut tree_update,
id: node_id,
node: *mut node,
) {
let update = mut_from_ptr(update);
let node = box_from_ptr(node);
update.nodes.push((id.into(), *node));
}

#[no_mangle]
pub extern "C" fn accesskit_tree_update_set_tree(update: *mut tree_update, tree: tree) {
let update = mut_from_ptr(update);
update.tree = Some(tree.into());
}

#[no_mangle]
pub extern "C" fn accesskit_tree_update_clear_tree(update: *mut tree_update) {
let update = mut_from_ptr(update);
update.tree = None;
}

#[no_mangle]
pub extern "C" fn accesskit_tree_update_set_focus(update: *mut tree_update, focus: node_id) {
let update = mut_from_ptr(update);
update.focus = Some(focus.into());
}

#[no_mangle]
pub extern "C" fn accesskit_tree_update_clear_focus(update: *mut tree_update) {
let update = mut_from_ptr(update);
update.focus = None;
}
}

Expand Down
14 changes: 7 additions & 7 deletions bindings/c/src/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl macos_adapter {
) -> *mut macos_adapter {
let initial_state = box_from_ptr(initial_state);
let handler = box_from_ptr(handler);
let adapter = Adapter::new(view, initial_state.into(), handler);
let adapter = Adapter::new(view, *initial_state, handler);
BoxCastPtr::to_mut_ptr(adapter)
}

Expand All @@ -71,7 +71,7 @@ impl macos_adapter {
) -> *mut macos_queued_events {
let adapter = ref_from_ptr(adapter);
let update = box_from_ptr(update);
let events = adapter.update(update.into());
let events = adapter.update(*update);
BoxCastPtr::to_mut_ptr(events)
}

Expand Down Expand Up @@ -130,7 +130,7 @@ impl macos_subclassing_adapter {
let handler = box_from_ptr(handler);
let adapter = SubclassingAdapter::new(
view,
move || box_from_ptr(source(source_userdata)).into(),
move || *box_from_ptr(source(source_userdata)),
handler,
);
BoxCastPtr::to_mut_ptr(adapter)
Expand All @@ -157,7 +157,7 @@ impl macos_subclassing_adapter {
let handler = box_from_ptr(handler);
let adapter = SubclassingAdapter::for_window(
window,
move || box_from_ptr(source(source_userdata)).into(),
move || *box_from_ptr(source(source_userdata)),
handler,
);
BoxCastPtr::to_mut_ptr(adapter)
Expand All @@ -179,7 +179,7 @@ impl macos_subclassing_adapter {
) -> *mut macos_queued_events {
let adapter = ref_from_ptr(adapter);
let update = box_from_ptr(update);
let events = adapter.update(update.into());
let events = adapter.update(*update);
BoxCastPtr::to_mut_ptr(events)
}

Expand All @@ -192,8 +192,8 @@ impl macos_subclassing_adapter {
) -> *mut macos_queued_events {
let update_factory = update_factory.unwrap();
let adapter = ref_from_ptr(adapter);
let events = adapter
.update_if_active(|| box_from_ptr(update_factory(update_factory_userdata)).into());
let events =
adapter.update_if_active(|| *box_from_ptr(update_factory(update_factory_userdata)));
match events {
Some(events) => BoxCastPtr::to_mut_ptr(events),
None => ptr::null_mut(),
Expand Down
4 changes: 2 additions & 2 deletions bindings/c/src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl unix_adapter {
app_name,
toolkit_name,
toolkit_version,
move || box_from_ptr(initial_state(initial_state_userdata)).into(),
move || *box_from_ptr(initial_state(initial_state_userdata)),
handler,
);
adapter.map_or_else(ptr::null_mut, BoxCastPtr::to_mut_ptr)
Expand Down Expand Up @@ -72,6 +72,6 @@ impl unix_adapter {
) {
let adapter = ref_from_ptr(adapter);
let update = box_from_ptr(update);
adapter.update(update.into());
adapter.update(*update);
}
}
12 changes: 6 additions & 6 deletions bindings/c/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl windows_adapter {
let initial_state = box_from_ptr(initial_state);
let handler = box_from_ptr(handler);
let uia_init_marker = *box_from_ptr(uia_init_marker);
let adapter = Adapter::new(hwnd, initial_state.into(), handler, uia_init_marker);
let adapter = Adapter::new(hwnd, *initial_state, handler, uia_init_marker);
BoxCastPtr::to_mut_ptr(adapter)
}

Expand All @@ -95,7 +95,7 @@ impl windows_adapter {
) -> *mut windows_queued_events {
let adapter = ref_from_ptr(adapter);
let update = box_from_ptr(update);
let events = adapter.update(update.into());
let events = adapter.update(*update);
BoxCastPtr::to_mut_ptr(events)
}

Expand Down Expand Up @@ -134,7 +134,7 @@ impl windows_subclassing_adapter {
let handler = box_from_ptr(handler);
let adapter = SubclassingAdapter::new(
hwnd,
move || box_from_ptr(source(source_userdata)).into(),
move || *box_from_ptr(source(source_userdata)),
handler,
);
BoxCastPtr::to_mut_ptr(adapter)
Expand All @@ -156,7 +156,7 @@ impl windows_subclassing_adapter {
) -> *mut windows_queued_events {
let adapter = ref_from_ptr(adapter);
let update = box_from_ptr(update);
let events = adapter.update(update.into());
let events = adapter.update(*update);
BoxCastPtr::to_mut_ptr(events)
}

Expand All @@ -169,8 +169,8 @@ impl windows_subclassing_adapter {
) -> *mut windows_queued_events {
let update_factory = update_factory.unwrap();
let adapter = ref_from_ptr(adapter);
let events = adapter
.update_if_active(|| box_from_ptr(update_factory(update_factory_userdata)).into());
let events =
adapter.update_if_active(|| *box_from_ptr(update_factory(update_factory_userdata)));
match events {
Some(events) => BoxCastPtr::to_mut_ptr(events),
None => ptr::null_mut(),
Expand Down

0 comments on commit b260a86

Please sign in to comment.