Skip to content

Commit

Permalink
Table render demo doesn't crash anymore
Browse files Browse the repository at this point in the history
In the push_iframe function, we have to push
display_list.rectangles not push the parent display list (bug!).

Also, temporarily removed the reparenting of the DOM in the
UiState::from_dom function - since the .add_child() clears
the UiDescription arena via the Rc it has, it leads to a crash.

Also added a nice .print_tree() for debugging the DOM. Right
now the demo still doesn't display anything (seems to hang
in the Changeset calculation function), but at least it doesn't
crash anymore.
  • Loading branch information
fschutt committed Oct 5, 2018
1 parent 6479912 commit 3a8effe
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 10 deletions.
6 changes: 3 additions & 3 deletions examples/table.rs
Expand Up @@ -22,9 +22,9 @@ fn main() {

macro_rules! CSS_PATH { () => (concat!(env!("CARGO_MANIFEST_DIR"), "/examples/table.css")) }

#[cfg(debug_assertions)]
let css = Css::hot_reload(CSS_PATH!()).unwrap();
#[cfg(not(debug_assertions))]
// #[cfg(debug_assertions)]
// let css = Css::hot_reload(CSS_PATH!()).unwrap();
// #[cfg(not(debug_assertions))]
let css = Css::new_from_str(include_str!(CSS_PATH!())).unwrap();

app.run(Window::new(WindowCreateOptions::default(), css).unwrap()).unwrap();
Expand Down
11 changes: 8 additions & 3 deletions src/css.rs
Expand Up @@ -676,13 +676,14 @@ pub(crate) fn match_dom_css_selectors<T: Layout>(
-> UiDescription<T>
{
let mut root_constraints = CssConstraintList::default();
let mut styled_nodes = BTreeMap::<NodeId, StyledNode>::new();

for global_rule in &parsed_css.pure_global_rules {
root_constraints.push_rule(global_rule);
}

let arena_borrow = &*(*arena).borrow();
let arena_borrow = &*arena.borrow();

let mut styled_nodes = BTreeMap::<NodeId, StyledNode>::new();
let sibling_iterator = root.following_siblings(arena_borrow);
// skip the root node itself, see documentation for `following_siblings` in id_tree.rs
// sibling_iterator.next().unwrap();
Expand All @@ -694,7 +695,11 @@ pub(crate) fn match_dom_css_selectors<T: Layout>(
UiDescription {
// note: this clone is neccessary, otherwise,
// we wouldn't be able to update the UiState
ui_descr_arena: (*arena).clone(),
//
// WARNING: The UIState can modify the `arena` with its copy of the Rc !
// Be careful about appending things to the arena, since that could modify
// the UiDescription without you knowing!
ui_descr_arena: arena.clone(),
ui_descr_root: root,
styled_nodes: styled_nodes,
default_style_of_node: StyledNode::default(),
Expand Down
11 changes: 10 additions & 1 deletion src/display_list.rs
Expand Up @@ -309,6 +309,7 @@ fn push_rectangles_into_displaylist<'a, 'b, T: Layout>(
referenced_content: &DisplayListParametersRef<'a,'b, T>,
referenced_mutable_content: &mut DisplayListParametersMut<'a, T>)
{
println!("push_rectangles_into_displaylist");
let arena = referenced_content.ui_description.ui_descr_arena.borrow();

for (z_index, rects) in z_ordered_rectangles.0.into_iter() {
Expand All @@ -332,13 +333,16 @@ fn insert_constraints_into_solver<'a, T: Layout>(
rectangles: &Arena<DisplayRectangle<'a>>,
window_size_has_changed: bool)
{
println!("insert constraints into DOM!");
let mut has_window_size_changed = window_size_has_changed;

let changeset = {
let changeset = dom_solver.update_dom(ui_description);
if changeset.is_empty() { None } else { Some(changeset) }
};

if changeset.is_some() {

// inefficient for now, but prevents memory leak
dom_solver.clear_all_constraints();
for rect_idx in rectangles.linear_iter() {
Expand All @@ -359,6 +363,7 @@ fn insert_constraints_into_solver<'a, T: Layout>(
}

dom_solver.update_layout_cache();
println!("end of insert constraints into DOM!");
}

/// Lazy-lock the Arc<Mutex<T>> - if it is already locked, just construct
Expand Down Expand Up @@ -643,11 +648,14 @@ fn push_iframe<'a, 'b, 'c, T: Layout>(

referenced_mutable_content.ui_solver.insert_dom(new_dom_id, dom_solver);

// ui_description.ui_descr_arena.borrow().print_tree(|t| format!("{}", t)); // REMOVE

println!("push_iframe");
insert_constraints_into_solver(
&ui_description,
referenced_mutable_content.ui_solver.get_dom_mut(&new_dom_id).unwrap(),
&rect_size,
&referenced_content.display_rectangle_arena,
&display_list.rectangles,
true
);

Expand All @@ -661,6 +669,7 @@ fn push_iframe<'a, 'b, 'c, T: Layout>(

referenced_mutable_content.ui_solver.remove_dom(&new_dom_id);

println!("push iframe done!");
None
}

Expand Down
11 changes: 11 additions & 0 deletions src/dom.rs
Expand Up @@ -449,6 +449,17 @@ impl<T: Layout> Clone for NodeData<T> {
}
}

impl<T: Layout> fmt::Display for NodeData<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
const DEFAULT: &str = "";
let id = match &self.id {
Some(s) => s,
None => DEFAULT,
};
write!(f, "[{} #{} .{:?}]", self.node_type.get_css_id(), id, self.classes)
}
}

impl<T: Layout> fmt::Debug for NodeData<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
Expand Down
25 changes: 24 additions & 1 deletion src/id_tree.rs
Expand Up @@ -209,9 +209,32 @@ impl<T> Arena<T> {
self.nodes.append(&mut other.nodes);
}

pub fn get(&self, node: &NodeId) -> Option<&Node<T>> {
pub(crate) fn get(&self, node: &NodeId) -> Option<&Node<T>> {
self.nodes.get(node.index())
}

/// Prints the debug version of the arena, without printing the actual arena
pub(crate) fn print_tree<F: Fn(&T) -> String + Copy>(&self, format_cb: F) -> String {
let mut s = String::new();
if self.nodes_len() > 0 {
self.print_tree_recursive(format_cb, &mut s, NodeId::new(0), 0);
}
s
}

fn print_tree_recursive<F: Fn(&T) -> String + Copy>(&self, format_cb: F, string: &mut String, current_node_id: NodeId, indent: usize) {
let node = &self[current_node_id];
let tabs = String::from("\t|").repeat(indent);
string.push_str(&format!("{}-- {}: {}\n", tabs, current_node_id.index(), format_cb(&node.data)));

if let Some(first_child) = node.first_child {
self.print_tree_recursive(format_cb, string, first_child, indent + 1);
}

if let Some(next_sibling) = node.next_sibling {
self.print_tree_recursive(format_cb, string, next_sibling, indent);
}
}
}

impl<T: Copy> Arena<T> {
Expand Down
7 changes: 5 additions & 2 deletions src/ui_state.rs
Expand Up @@ -71,12 +71,15 @@ impl<T: Layout> UiState<T> {

// DOM tree should have a single root element, necessary for
// layout constraints having a single root
let dom = {

// TODO: problematic, since the UiDescription has an Rc into the the DOM
// and the .add_child empties / drains the original DOM arena !!!
/* let dom = {
let mut parent_dom = Dom::with_capacity(NodeType::Div, dom.len());
parent_dom.add_child(dom);
parent_dom
};

*/
let mut tag_ids_to_callbacks = BTreeMap::new();
let mut tag_ids_to_default_callbacks = BTreeMap::new();
let mut node_ids_to_tag_ids = BTreeMap::new();
Expand Down

0 comments on commit 3a8effe

Please sign in to comment.