Skip to content

Commit b260a86

Browse files
authored
refactor!: New C API for tree updates (#263)
1 parent 63c1715 commit b260a86

File tree

6 files changed

+83
-87
lines changed

6 files changed

+83
-87
lines changed

bindings/c/cbindgen.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ after_includes = """#ifdef _WIN32
1515
usize_is_size_t = true
1616

1717
[export]
18-
include = ["Size", "tree_update", "Vec2"]
18+
include = ["Size", "Vec2"]
1919
prefix = "accesskit_"
2020
renaming_overrides_prefixing = true
2121

bindings/c/examples/windows/hello_world.c

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,11 @@ void window_state_free(struct window_state *state) {
7979
free(state);
8080
}
8181

82-
accesskit_opt_node_id window_state_focus(struct window_state *state) {
83-
accesskit_opt_node_id result;
84-
result.has_value = state->is_window_focused;
85-
if (result.has_value) {
86-
result.value = state->focus;
82+
void window_state_set_tree_update_focus(struct window_state *state,
83+
accesskit_tree_update *update) {
84+
if (state->is_window_focused) {
85+
accesskit_tree_update_set_focus(update, state->focus);
8786
}
88-
return result;
8987
}
9088

9189
accesskit_node *window_state_build_root(struct window_state *state) {
@@ -106,21 +104,17 @@ accesskit_tree_update *window_state_build_initial_tree(
106104
build_button(BUTTON_1_ID, "Button 1", state->node_classes);
107105
accesskit_node *button_2 =
108106
build_button(BUTTON_2_ID, "Button 2", state->node_classes);
109-
accesskit_tree_update *result =
110-
accesskit_tree_update_new((state->announcement != NULL) ? 4 : 3);
111-
result->tree.has_value = true;
112-
result->tree.value = accesskit_tree_new(WINDOW_ID);
113-
result->focus = window_state_focus(state);
114-
result->ids[0] = WINDOW_ID;
115-
result->nodes[0] = root;
116-
result->ids[1] = BUTTON_1_ID;
117-
result->nodes[1] = button_1;
118-
result->ids[2] = BUTTON_2_ID;
119-
result->nodes[2] = button_2;
107+
accesskit_tree_update *result = accesskit_tree_update_with_capacity(
108+
(state->announcement != NULL) ? 4 : 3);
109+
accesskit_tree_update_set_tree(result, accesskit_tree_new(WINDOW_ID));
110+
window_state_set_tree_update_focus(state, result);
111+
accesskit_tree_update_push_node(result, WINDOW_ID, root);
112+
accesskit_tree_update_push_node(result, BUTTON_1_ID, button_1);
113+
accesskit_tree_update_push_node(result, BUTTON_2_ID, button_2);
120114
if (state->announcement != NULL) {
121-
result->ids[3] = ANNOUNCEMENT_ID;
122-
result->nodes[3] =
115+
accesskit_node *announcement =
123116
build_announcement(state->announcement, state->node_classes);
117+
accesskit_tree_update_push_node(result, ANNOUNCEMENT_ID, announcement);
124118
}
125119
return result;
126120
}
@@ -165,12 +159,10 @@ void window_state_press_button(struct window_state *state,
165159
accesskit_node *announcement =
166160
build_announcement(text, state->node_classes);
167161
accesskit_node *root = window_state_build_root(state);
168-
accesskit_tree_update *update = accesskit_tree_update_new(2);
169-
update->ids[0] = ANNOUNCEMENT_ID;
170-
update->nodes[0] = announcement;
171-
update->ids[1] = WINDOW_ID;
172-
update->nodes[1] = root;
173-
update->focus = window_state_focus(state);
162+
accesskit_tree_update *update = accesskit_tree_update_with_capacity(2);
163+
accesskit_tree_update_push_node(update, ANNOUNCEMENT_ID, announcement);
164+
accesskit_tree_update_push_node(update, WINDOW_ID, root);
165+
window_state_set_tree_update_focus(state, update);
174166
accesskit_windows_queued_events *events =
175167
accesskit_windows_adapter_update(state->adapter, update);
176168
accesskit_windows_queued_events_raise(events);
@@ -184,10 +176,9 @@ struct window_state *get_window_state(HWND window) {
184176
void update_focus(HWND window, bool is_window_focused) {
185177
struct window_state *state = get_window_state(window);
186178
state->is_window_focused = is_window_focused;
187-
accesskit_opt_node_id focus = window_state_focus(state);
188179
if (state->adapter != NULL) {
189-
accesskit_tree_update *update = accesskit_tree_update_new(0);
190-
update->focus = focus;
180+
accesskit_tree_update *update = accesskit_tree_update_new();
181+
window_state_set_tree_update_focus(state, update);
191182
accesskit_windows_queued_events *events =
192183
accesskit_windows_adapter_update(state->adapter, update);
193184
accesskit_windows_queued_events_raise(events);

bindings/c/src/common.rs

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -911,8 +911,6 @@ impl tree {
911911
}
912912
}
913913

914-
opt_struct! { opt_tree, tree }
915-
916914
impl From<tree> for Tree {
917915
fn from(tree: tree) -> Self {
918916
Self {
@@ -922,65 +920,72 @@ impl From<tree> for Tree {
922920
}
923921
}
924922

925-
/// Use `accesskit_tree_update_new` to create this struct. Do not reallocate `ids` and `nodes`.
926-
#[repr(C)]
927923
pub struct tree_update {
928-
pub node_count: usize,
929-
pub ids: *mut node_id,
930-
pub nodes: *mut *mut node,
931-
pub tree: opt_tree,
932-
pub focus: opt_node_id,
924+
_private: [u8; 0],
933925
}
934926

935927
impl CastPtr for tree_update {
936-
type RustType = tree_update;
928+
type RustType = TreeUpdate;
937929
}
938930

939931
impl BoxCastPtr for tree_update {}
940932

941933
impl tree_update {
942934
#[no_mangle]
943-
pub extern "C" fn accesskit_tree_update_new(node_count: usize) -> *mut tree_update {
944-
let mut ids = Vec::with_capacity(node_count);
945-
let mut nodes = Vec::with_capacity(node_count);
946-
let update = tree_update {
947-
node_count,
948-
ids: ids.as_mut_ptr(),
949-
nodes: nodes.as_mut_ptr(),
950-
tree: opt_tree::default(),
951-
focus: opt_node_id::default(),
935+
pub extern "C" fn accesskit_tree_update_new() -> *mut tree_update {
936+
let update = TreeUpdate::default();
937+
BoxCastPtr::to_mut_ptr(update)
938+
}
939+
940+
#[no_mangle]
941+
pub extern "C" fn accesskit_tree_update_with_capacity(capacity: usize) -> *mut tree_update {
942+
let update = TreeUpdate {
943+
nodes: Vec::with_capacity(capacity),
944+
..Default::default()
952945
};
953-
mem::forget(ids);
954-
mem::forget(nodes);
955946
BoxCastPtr::to_mut_ptr(update)
956947
}
957948

958949
#[no_mangle]
959950
pub extern "C" fn accesskit_tree_update_free(update: *mut tree_update) {
960-
drop(TreeUpdate::from(box_from_ptr(update)));
951+
drop(box_from_ptr(update));
961952
}
962-
}
963953

964-
impl From<Box<tree_update>> for TreeUpdate {
965-
fn from(update: Box<tree_update>) -> Self {
966-
let ids = unsafe {
967-
Vec::from_raw_parts(
968-
update.ids as *mut NodeId,
969-
update.node_count,
970-
update.node_count,
971-
)
972-
};
973-
let nodes =
974-
unsafe { Vec::from_raw_parts(update.nodes, update.node_count, update.node_count) };
975-
Self {
976-
nodes: ids
977-
.into_iter()
978-
.zip(nodes.into_iter().map(box_from_ptr))
979-
.map(|(id, node)| (id, *node))
980-
.collect::<Vec<(NodeId, Node)>>(),
981-
tree: update.tree.into(),
982-
focus: update.focus.into(),
983-
}
954+
/// Appends the provided node to the tree update's list of nodes.
955+
/// Takes ownership of `node`.
956+
#[no_mangle]
957+
pub extern "C" fn accesskit_tree_update_push_node(
958+
update: *mut tree_update,
959+
id: node_id,
960+
node: *mut node,
961+
) {
962+
let update = mut_from_ptr(update);
963+
let node = box_from_ptr(node);
964+
update.nodes.push((id.into(), *node));
965+
}
966+
967+
#[no_mangle]
968+
pub extern "C" fn accesskit_tree_update_set_tree(update: *mut tree_update, tree: tree) {
969+
let update = mut_from_ptr(update);
970+
update.tree = Some(tree.into());
971+
}
972+
973+
#[no_mangle]
974+
pub extern "C" fn accesskit_tree_update_clear_tree(update: *mut tree_update) {
975+
let update = mut_from_ptr(update);
976+
update.tree = None;
977+
}
978+
979+
#[no_mangle]
980+
pub extern "C" fn accesskit_tree_update_set_focus(update: *mut tree_update, focus: node_id) {
981+
let update = mut_from_ptr(update);
982+
update.focus = Some(focus.into());
983+
}
984+
985+
#[no_mangle]
986+
pub extern "C" fn accesskit_tree_update_clear_focus(update: *mut tree_update) {
987+
let update = mut_from_ptr(update);
988+
update.focus = None;
984989
}
985990
}
986991

bindings/c/src/macos.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl macos_adapter {
5353
) -> *mut macos_adapter {
5454
let initial_state = box_from_ptr(initial_state);
5555
let handler = box_from_ptr(handler);
56-
let adapter = Adapter::new(view, initial_state.into(), handler);
56+
let adapter = Adapter::new(view, *initial_state, handler);
5757
BoxCastPtr::to_mut_ptr(adapter)
5858
}
5959

@@ -71,7 +71,7 @@ impl macos_adapter {
7171
) -> *mut macos_queued_events {
7272
let adapter = ref_from_ptr(adapter);
7373
let update = box_from_ptr(update);
74-
let events = adapter.update(update.into());
74+
let events = adapter.update(*update);
7575
BoxCastPtr::to_mut_ptr(events)
7676
}
7777

@@ -130,7 +130,7 @@ impl macos_subclassing_adapter {
130130
let handler = box_from_ptr(handler);
131131
let adapter = SubclassingAdapter::new(
132132
view,
133-
move || box_from_ptr(source(source_userdata)).into(),
133+
move || *box_from_ptr(source(source_userdata)),
134134
handler,
135135
);
136136
BoxCastPtr::to_mut_ptr(adapter)
@@ -157,7 +157,7 @@ impl macos_subclassing_adapter {
157157
let handler = box_from_ptr(handler);
158158
let adapter = SubclassingAdapter::for_window(
159159
window,
160-
move || box_from_ptr(source(source_userdata)).into(),
160+
move || *box_from_ptr(source(source_userdata)),
161161
handler,
162162
);
163163
BoxCastPtr::to_mut_ptr(adapter)
@@ -179,7 +179,7 @@ impl macos_subclassing_adapter {
179179
) -> *mut macos_queued_events {
180180
let adapter = ref_from_ptr(adapter);
181181
let update = box_from_ptr(update);
182-
let events = adapter.update(update.into());
182+
let events = adapter.update(*update);
183183
BoxCastPtr::to_mut_ptr(events)
184184
}
185185

@@ -192,8 +192,8 @@ impl macos_subclassing_adapter {
192192
) -> *mut macos_queued_events {
193193
let update_factory = update_factory.unwrap();
194194
let adapter = ref_from_ptr(adapter);
195-
let events = adapter
196-
.update_if_active(|| box_from_ptr(update_factory(update_factory_userdata)).into());
195+
let events =
196+
adapter.update_if_active(|| *box_from_ptr(update_factory(update_factory_userdata)));
197197
match events {
198198
Some(events) => BoxCastPtr::to_mut_ptr(events),
199199
None => ptr::null_mut(),

bindings/c/src/unix.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl unix_adapter {
4343
app_name,
4444
toolkit_name,
4545
toolkit_version,
46-
move || box_from_ptr(initial_state(initial_state_userdata)).into(),
46+
move || *box_from_ptr(initial_state(initial_state_userdata)),
4747
handler,
4848
);
4949
adapter.map_or_else(ptr::null_mut, BoxCastPtr::to_mut_ptr)
@@ -72,6 +72,6 @@ impl unix_adapter {
7272
) {
7373
let adapter = ref_from_ptr(adapter);
7474
let update = box_from_ptr(update);
75-
adapter.update(update.into());
75+
adapter.update(*update);
7676
}
7777
}

bindings/c/src/windows.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl windows_adapter {
7777
let initial_state = box_from_ptr(initial_state);
7878
let handler = box_from_ptr(handler);
7979
let uia_init_marker = *box_from_ptr(uia_init_marker);
80-
let adapter = Adapter::new(hwnd, initial_state.into(), handler, uia_init_marker);
80+
let adapter = Adapter::new(hwnd, *initial_state, handler, uia_init_marker);
8181
BoxCastPtr::to_mut_ptr(adapter)
8282
}
8383

@@ -95,7 +95,7 @@ impl windows_adapter {
9595
) -> *mut windows_queued_events {
9696
let adapter = ref_from_ptr(adapter);
9797
let update = box_from_ptr(update);
98-
let events = adapter.update(update.into());
98+
let events = adapter.update(*update);
9999
BoxCastPtr::to_mut_ptr(events)
100100
}
101101

@@ -134,7 +134,7 @@ impl windows_subclassing_adapter {
134134
let handler = box_from_ptr(handler);
135135
let adapter = SubclassingAdapter::new(
136136
hwnd,
137-
move || box_from_ptr(source(source_userdata)).into(),
137+
move || *box_from_ptr(source(source_userdata)),
138138
handler,
139139
);
140140
BoxCastPtr::to_mut_ptr(adapter)
@@ -156,7 +156,7 @@ impl windows_subclassing_adapter {
156156
) -> *mut windows_queued_events {
157157
let adapter = ref_from_ptr(adapter);
158158
let update = box_from_ptr(update);
159-
let events = adapter.update(update.into());
159+
let events = adapter.update(*update);
160160
BoxCastPtr::to_mut_ptr(events)
161161
}
162162

@@ -169,8 +169,8 @@ impl windows_subclassing_adapter {
169169
) -> *mut windows_queued_events {
170170
let update_factory = update_factory.unwrap();
171171
let adapter = ref_from_ptr(adapter);
172-
let events = adapter
173-
.update_if_active(|| box_from_ptr(update_factory(update_factory_userdata)).into());
172+
let events =
173+
adapter.update_if_active(|| *box_from_ptr(update_factory(update_factory_userdata)));
174174
match events {
175175
Some(events) => BoxCastPtr::to_mut_ptr(events),
176176
None => ptr::null_mut(),

0 commit comments

Comments
 (0)