Merge branch 'upstream' into fix-hot-reloading

This commit is contained in:
Evan Almloff committed 2022-12-22 16:58:30 -06:00
commit 608c37428d
3 files changed
+37 -34

No files matched your search

+8 -5
View File
@@ -134,8 +134,8 @@ impl VirtualDom {
} }
/// Descend through the tree, removing any borrowed props and listeners /// Descend through the tree, removing any borrowed props and listeners
pub(crate) fn ensure_drop_safety(&self, scope: ScopeId) { pub(crate) fn ensure_drop_safety(&self, scope_id: ScopeId) {
let scope = &self.scopes[scope.0]; let scope = &self.scopes[scope_id.0];
// make sure we drop all borrowed props manually to guarantee that their drop implementation is called before we // make sure we drop all borrowed props manually to guarantee that their drop implementation is called before we
// run the hooks (which hold an &mut Reference) // run the hooks (which hold an &mut Reference)
@@ -143,10 +143,13 @@ impl VirtualDom {
let mut props = scope.borrowed_props.borrow_mut(); let mut props = scope.borrowed_props.borrow_mut();
props.drain(..).for_each(|comp| { props.drain(..).for_each(|comp| {
let comp = unsafe { &*comp }; let comp = unsafe { &*comp };
if let Some(scope_id) = comp.scope.get() { match comp.scope.get() {
self.ensure_drop_safety(scope_id); Some(child) if child != scope_id => self.ensure_drop_safety(child),
_ => (),
}
if let Ok(mut props) = comp.props.try_borrow_mut() {
*props = None;
} }
drop(comp.props.take());
}); });
// Now that all the references are gone, we can safely drop our own references in our listeners. // Now that all the references are gone, we can safely drop our own references in our listeners.
+21 -19
View File
@@ -840,10 +840,9 @@ impl<'b> VirtualDom {
.node_paths .node_paths
.get(idx) .get(idx)
.map(|path| path.len()); .map(|path| path.len());
match path_len { // Roots are cleaned up automatically above and nodes with a empty path are placeholders
Some(2..) => self.remove_dynamic_node(dyn_node, false), if let Some(2..) = path_len {
// Roots are cleaned up automatically above and nodes with a empty path are placeholders self.remove_dynamic_node(dyn_node, false)
_ => continue,
} }
} }
} }
@@ -878,25 +877,28 @@ impl<'b> VirtualDom {
} }
fn remove_component_node(&mut self, comp: &VComponent, gen_muts: bool) { fn remove_component_node(&mut self, comp: &VComponent, gen_muts: bool) {
if let Some(scope) = comp.scope.take() { let scope = comp.scope.take().unwrap();
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
RenderReturn::Sync(Some(t)) => self.remove_node(t, gen_muts),
_ => todo!("cannot handle nonstandard nodes"),
};
let props = self.scopes[scope.0].props.take(); match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
RenderReturn::Sync(Some(t)) => {
println!("Removing component node sync {:?}", gen_muts);
self.remove_node(t, gen_muts)
}
_ => todo!("cannot handle nonstandard nodes"),
};
self.dirty_scopes.remove(&DirtyScope { let props = self.scopes[scope.0].props.take();
height: self.scopes[scope.0].height,
id: scope,
});
*comp.props.borrow_mut() = unsafe { std::mem::transmute(props) }; self.dirty_scopes.remove(&DirtyScope {
height: self.scopes[scope.0].height,
id: scope,
});
// make sure to wipe any of its props and listeners *comp.props.borrow_mut() = unsafe { std::mem::transmute(props) };
self.ensure_drop_safety(scope);
self.scopes.remove(scope.0); // make sure to wipe any of its props and listeners
} self.ensure_drop_safety(scope);
self.scopes.remove(scope.0);
} }
fn find_first_element(&self, node: &'b VNode<'b>) -> ElementId { fn find_first_element(&self, node: &'b VNode<'b>) -> ElementId {
+8 -10
View File
@@ -1,10 +1,7 @@
function main() { function main() {
let root = window.document.getElementById("main"); let root = window.document.getElementById("main");
if (root != null) { if (root != null) {
// create a new ipc
window.ipc = new IPC(root); window.ipc = new IPC(root);
window.ipc.postMessage(serializeIpcMessage("initialize"));
} }
} }
@@ -13,21 +10,22 @@ class IPC {
// connect to the websocket // connect to the websocket
window.interpreter = new Interpreter(root); window.interpreter = new Interpreter(root);
this.ws = new WebSocket(WS_ADDR); let ws = new WebSocket(WS_ADDR);
this.ws.onopen = () => { ws.onopen = () => {
console.log("Connected to the websocket"); ws.send(serializeIpcMessage("initialize"));
}; };
this.ws.onerror = (err) => { ws.onerror = (err) => {
console.error("Error: ", err); // todo: retry the connection
}; };
this.ws.onmessage = (event) => { ws.onmessage = (event) => {
console.log("Received message: ", event.data);
let edits = JSON.parse(event.data); let edits = JSON.parse(event.data);
window.interpreter.handleEdits(edits); window.interpreter.handleEdits(edits);
}; };
this.ws = ws;
} }
postMessage(msg) { postMessage(msg) {