Skip to content

Commit ca48f8c

Browse files
committed
chore: clean up ffi
1 parent 66334da commit ca48f8c

File tree

6 files changed

+80
-61
lines changed

6 files changed

+80
-61
lines changed

crates/core/c_src/include/LiveViewNativeCore.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@
44

55
typedef uint32_t NodeRef;
66

7+
typedef struct _AttributeVec {
8+
const void *start;
9+
uintptr_t len;
10+
uintptr_t capacity;
11+
} _AttributeVec;
12+
713
typedef struct __Document {
814
void *ptr;
915
} __Document;
1016

1117
typedef struct __Element {
1218
_RustStr ns;
1319
_RustStr tag;
14-
_RustVec attributes;
20+
_AttributeVec attributes;
1521
} __Element;
1622

1723
typedef struct __Attribute {
@@ -39,6 +45,8 @@ typedef struct __Node {
3945
__NodeData data;
4046
} __Node;
4147

48+
extern void __liveview_native_core$AttributeVec$drop(_AttributeVec vec);
49+
4250
extern _RustString __liveview_native_core$Document$to_string(__Document doc);
4351

4452
extern _RustString
@@ -51,8 +59,12 @@ extern void __liveview_native_core$Document$drop(__Document doc);
5159
extern _RustResult __liveview_native_core$Document$parse(_RustStr text,
5260
_RustString *error);
5361

54-
extern bool __liveview_native_core$Document$merge(__Document doc,
55-
__Document other);
62+
typedef void (*OnChangeCallback)(void *context, NodeRef node);
63+
64+
extern void __liveview_native_core$Document$merge(__Document doc,
65+
__Document other,
66+
OnChangeCallback callback,
67+
void *context);
5668

5769
extern NodeRef __liveview_native_core$Document$root(__Document doc);
5870

@@ -61,5 +73,5 @@ extern __Node __liveview_native_core$Document$get(__Document doc, NodeRef node);
6173
extern _RustSlice __liveview_native_core$Document$children(__Document doc,
6274
NodeRef node);
6375

64-
extern _RustVec __liveview_native_core$Document$attributes(__Document doc,
65-
NodeRef node);
76+
extern _AttributeVec __liveview_native_core$Document$attributes(__Document doc,
77+
NodeRef node);

crates/core/c_src/include/Support.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,3 @@ typedef struct _RustString {
4040
} _RustString;
4141

4242
extern void __liveview_native_core$RustString$drop(_RustString string);
43-
44-
typedef struct _RustVec {
45-
const void *start;
46-
uintptr_t len;
47-
uintptr_t capacity;
48-
} _RustVec;
49-
50-
extern void __liveview_native_core$RustVec$Attribute$drop(_RustVec vec);

crates/core/src/diff/patch.rs

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,98 +78,116 @@ pub enum Patch {
7878
}
7979

8080
impl Patch {
81-
pub fn is_mutation(&self) -> bool {
82-
match self {
83-
Self::Move(_) => false,
84-
_ => true,
85-
}
86-
}
87-
88-
pub fn apply<B>(self, doc: &mut B, stack: &mut Vec<NodeRef>)
81+
/// Applies this patch to `doc` using `stack`.
82+
///
83+
/// If this patch will result in a change to the underlying document, the affected [NodeRef] is returned, else `None`.
84+
///
85+
/// For modifications, the affected node is the node to which the change applies, but for additions/removals, the affected
86+
/// node is the parent to which the child was added/removed. This can be used to associate callbacks to nodes in the document
87+
/// and be able to properly handle changes to them.
88+
pub fn apply<B>(self, doc: &mut B, stack: &mut Vec<NodeRef>) -> Option<NodeRef>
8989
where
9090
B: DocumentBuilder,
9191
{
9292
match self {
93-
Self::InsertBefore { before, node } => {
94-
doc.insert_before(node, before);
95-
}
96-
Self::InsertAfter { after, node } => {
97-
doc.insert_after(node, after);
98-
}
93+
Self::InsertBefore { before, node } => Some(doc.insert_before(node, before)),
94+
Self::InsertAfter { after, node } => Some(doc.insert_after(node, after)),
9995
Self::Create { node } => {
100-
stack.push(doc.push_node(node));
96+
let node = doc.push_node(node);
97+
stack.push(node);
98+
Some(node)
10199
}
102100
Self::CreateAndMoveTo { node } => {
103101
let node = doc.push_node(node);
104102
stack.push(node);
105103
doc.set_insertion_point(node);
104+
Some(node)
106105
}
107106
Self::PushCurrent => {
108107
stack.push(doc.insertion_point());
108+
None
109109
}
110110
Self::Push(node) => {
111111
stack.push(node);
112+
None
112113
}
113114
Self::Pop => {
114115
stack.pop().unwrap();
116+
None
115117
}
116118
Self::Attach => {
117119
let child = stack.pop().unwrap();
118120
let parent = stack.pop().unwrap();
119121
doc.set_insertion_point(parent);
120122
doc.attach_node(child);
121123
stack.push(parent);
124+
Some(parent)
122125
}
123-
Self::Append { node } => {
124-
doc.append(node);
125-
}
126+
Self::Append { node } => Some(doc.append(node)),
126127
Self::AppendTo { parent, node } => {
127128
doc.append_child(parent, node);
129+
Some(parent)
128130
}
129131
Self::AppendAfter { after } => {
130132
let node = stack.pop().unwrap();
131133
let d = doc.document_mut();
132134
d.insert_after(node, after);
135+
d.parent(after)
133136
}
134137
Self::Remove { node } => {
138+
let parent = doc.document_mut().parent(node);
135139
doc.remove(node);
140+
parent
141+
}
142+
Self::Replace { node, replacement } => {
143+
doc.replace(node, replacement);
144+
Some(node)
136145
}
137-
Self::Replace { node, replacement } => doc.replace(node, replacement),
138146
Self::AddAttribute { name, value } => {
139147
doc.set_attribute(name, value);
148+
Some(doc.insertion_point())
140149
}
141150
Self::AddAttributeTo { node, name, value } => {
142151
let mut guard = doc.insert_guard();
143152
guard.set_insertion_point(node);
144153
guard.set_attribute(name, value);
154+
Some(node)
145155
}
146156
Self::UpdateAttribute { node, name, value } => {
147157
let mut guard = doc.insert_guard();
148158
guard.set_insertion_point(node);
149159
guard.set_attribute(name, value);
160+
Some(node)
150161
}
151162
Self::RemoveAttributeByName { node, name } => {
152163
let mut guard = doc.insert_guard();
153164
guard.set_insertion_point(node);
154165
guard.remove_attribute(name);
166+
Some(node)
155167
}
156168
Self::Move(MoveTo::Node(node)) => {
157169
doc.set_insertion_point(node);
170+
None
158171
}
159172
Self::Move(MoveTo::Parent) => {
160173
doc.set_insertion_point_to_parent();
174+
None
161175
}
162176
Self::Move(MoveTo::Child(n)) => {
163177
doc.set_insertion_point_to_child(n as usize);
178+
None
164179
}
165180
Self::Move(MoveTo::ReverseChild(n)) => {
166181
doc.set_insertion_point_to_child_reverse(n as usize);
182+
None
167183
}
168184
Self::Move(MoveTo::Sibling(n)) => {
169185
doc.set_insertion_point_to_sibling(n as usize);
186+
None
170187
}
171188
Self::Move(MoveTo::ReverseSibling(n)) => {
172189
doc.set_insertion_point_to_sibling_reverse(n as usize);
190+
None
173191
}
174192
}
175193
}

crates/core/src/ffi/mod.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod support;
22

33
use crate::dom::{self, NodeRef};
44

5-
pub use support::{RustResult, RustSlice, RustStr, RustString, RustVec};
5+
pub use support::{AttributeVec, RustResult, RustSlice, RustStr, RustString};
66

77
#[repr(C)]
88
pub struct Node<'a> {
@@ -38,7 +38,7 @@ impl<'a> Node<'a> {
3838
.map(|ns| RustStr::from_str(ns.as_str()))
3939
.unwrap_or_default(),
4040
tag: RustStr::from_str(elem.name.name.as_str()),
41-
attributes: RustVec::from_vec(attributes),
41+
attributes: AttributeVec::from_vec(attributes),
4242
},
4343
},
4444
}
@@ -67,7 +67,7 @@ pub union NodeData<'a> {
6767
pub struct Element<'a> {
6868
pub namespace: RustStr<'static>,
6969
pub tag: RustStr<'static>,
70-
pub attributes: RustVec<Attribute<'a>>,
70+
pub attributes: AttributeVec<'a>,
7171
}
7272

7373
#[repr(C)]
@@ -149,21 +149,27 @@ pub extern "C" fn document_node_to_string(doc: *mut dom::Document, node: NodeRef
149149
}
150150

151151
#[export_name = "__liveview_native_core$Document$merge"]
152-
pub extern "C" fn document_merge(doc: *mut dom::Document, other: *const dom::Document) -> bool {
152+
pub extern "C" fn document_merge(
153+
doc: *mut dom::Document,
154+
other: *const dom::Document,
155+
handler: extern "C-unwind" fn(*mut (), NodeRef) -> (),
156+
context: *mut (),
157+
) {
153158
let doc = unsafe { &mut *doc };
154159
let other = unsafe { &*other };
155160
let mut patches = crate::diff::diff(doc, other);
156161
if patches.is_empty() {
157-
return false;
162+
return;
158163
}
159164

160165
let mut editor = doc.edit();
161166
let mut stack = vec![];
162167
for patch in patches.drain(..) {
163-
patch.apply(&mut editor, &mut stack);
168+
if let Some(affected) = patch.apply(&mut editor, &mut stack) {
169+
handler(context, affected);
170+
}
164171
}
165172
editor.finish();
166-
true
167173
}
168174

169175
#[export_name = "__liveview_native_core$Document$root"]
@@ -190,15 +196,15 @@ pub extern "C" fn document_get_children<'a>(
190196
}
191197

192198
#[export_name = "__liveview_native_core$Document$attributes"]
193-
pub extern "C" fn document_get_attributes<'a>(
199+
pub extern "C" fn document_get_attributes(
194200
doc: *const dom::Document,
195201
node: NodeRef,
196-
) -> RustVec<Attribute<'a>> {
202+
) -> AttributeVec<'static> {
197203
let doc = unsafe { &*doc };
198204
let attrs = doc.attributes(node);
199205
let mut result = Vec::with_capacity(attrs.len());
200206
for attr in attrs {
201207
result.push(Attribute::from(attr));
202208
}
203-
RustVec::from_vec(result)
209+
AttributeVec::from_vec(result)
204210
}

crates/core/src/ffi/support.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ use std::ptr;
44
use std::slice;
55
use std::str;
66

7-
use paste::paste;
8-
97
use super::Attribute;
108

119
#[repr(C)]
@@ -46,36 +44,28 @@ impl<'a, T> Default for RustSlice<'a, T> {
4644

4745
#[repr(C)]
4846
#[derive(Copy, Clone)]
49-
pub struct RustVec<T> {
50-
pub ptr: *mut T,
47+
pub struct AttributeVec<'a> {
48+
pub ptr: *mut Attribute<'a>,
5149
pub len: usize,
5250
pub capacity: usize,
5351
}
54-
impl<T> RustVec<T> {
55-
pub fn from_vec(vec: Vec<T>) -> Self {
52+
impl<'a> AttributeVec<'a> {
53+
pub fn from_vec(vec: Vec<Attribute<'a>>) -> Self {
5654
let (ptr, len, capacity) = Vec::into_raw_parts(vec);
5755
Self { ptr, len, capacity }
5856
}
5957

60-
pub fn to_vec(self) -> Vec<T> {
58+
pub fn to_vec(self) -> Vec<Attribute<'a>> {
6159
unsafe { Vec::from_raw_parts_in(self.ptr, self.len, self.capacity, Global) }
6260
}
6361
}
6462

65-
macro_rules! rust_vec {
66-
($ty:ident) => {
67-
paste! {
68-
#[allow(non_snake_case)]
69-
#[export_name = concat!("__liveview_native_core$RustVec$", stringify!($ty), "$drop")]
70-
pub extern "C" fn [<drop_RustVec_ $ty>](vec: RustVec<$ty>) {
71-
vec.to_vec();
72-
}
73-
}
74-
};
63+
#[allow(non_snake_case)]
64+
#[export_name = "__liveview_native_core$AttributeVec$drop"]
65+
pub extern "C" fn drop_AttributeVec(vec: AttributeVec) {
66+
vec.to_vec();
7567
}
7668

77-
rust_vec!(Attribute);
78-
7969
#[repr(C)]
8070
#[derive(Copy, Clone)]
8171
pub struct RustStr<'a> {

crates/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![feature(map_first_last)]
66
#![feature(exact_size_is_empty)]
77
#![feature(vec_into_raw_parts)]
8+
#![feature(c_unwind)]
89

910
pub mod diff;
1011
pub mod dom;

0 commit comments

Comments
 (0)