Finalizing new RenderEngine
This commit is contained in:
parent
73860eccdf
commit
6185fa27d8
3 changed files with 73 additions and 62 deletions
|
|
@ -37,65 +37,18 @@ impl AppWindow {
|
||||||
/// This method is called on the `show` event, and in rare cases can be useful to call
|
/// This method is called on the `show` event, and in rare cases can be useful to call
|
||||||
/// directly.
|
/// directly.
|
||||||
pub fn render(&mut self) {
|
pub fn render(&mut self) {
|
||||||
/*
|
let children = match self.delegate.render() {
|
||||||
let mut new_root_node = create_root_node(None, &mut self.layout);
|
Ok(opt) => opt,
|
||||||
|
Err(e) => {
|
||||||
// For API reasons, we'll call the render for this Window, and then patch it into a new
|
eprintln!("Error rendering window! {}", e);
|
||||||
// root node for the tree diff/patch comparison. For this we only need to go one level
|
RSX::None
|
||||||
// deep, the recursion in the next step will handle the rest.
|
}
|
||||||
match self.delegate.render() {
|
};
|
||||||
Ok(opt) => match opt {
|
|
||||||
RSX::VirtualNode(mut child) => {
|
|
||||||
if let RSX::VirtualNode(root) = &mut new_root_node {
|
|
||||||
if child.tag == "Fragment" {
|
|
||||||
root.children.append(&mut child.children);
|
|
||||||
} else {
|
|
||||||
root.children.push(RSX::VirtualNode(child));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// If it's an RSX::None, or a RSX::VirtualText, we do nothing, as... one
|
|
||||||
// requires nothing, and one isn't supported unless it's inside a <Text> tag.
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
match RENDER_ENGINE.diff_and_render_root(&self.render_key, children) {
|
||||||
|
Ok(_) => {}
|
||||||
Err(e) => { eprintln!("Error rendering window! {}", e); }
|
Err(e) => { eprintln!("Error rendering window! {}", e); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Taking ownership of the tree makes parts of this so much easier, so let's swap
|
|
||||||
// them out for the moment. We're going to discard the old one anyway.
|
|
||||||
let mut old_root_node = RSX::None;
|
|
||||||
std::mem::swap(&mut old_root_node, &mut self.root_node);
|
|
||||||
|
|
||||||
self.root_node = match diff_and_patch_tree(old_root_node, new_root_node, &mut self.layout, 0) {
|
|
||||||
Ok(node) => node,
|
|
||||||
Err(e) => { eprintln!("Error: {}", e); RSX::None }
|
|
||||||
};
|
|
||||||
|
|
||||||
self.configure_and_apply_styles();
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Walks the tree again, purely concerning itself with calculating layout and applying styles.
|
|
||||||
/// This in effect creates a two-pass layout system. In the future much of this may be made
|
|
||||||
/// async, so relying on underlying behavior in here is considered... suspect.
|
|
||||||
///
|
|
||||||
/// This method is called on window resize and show events.
|
|
||||||
fn configure_and_apply_styles(&mut self) -> Result<(), Box<std::error::Error>> {
|
|
||||||
let window_size = Size {
|
|
||||||
width: Number::Defined(600.),
|
|
||||||
height: Number::Defined(600.)
|
|
||||||
};
|
|
||||||
|
|
||||||
/*if let RSX::VirtualNode(root_node) = &mut self.root_node {
|
|
||||||
if let Some(layout_node) = &root_node.layout_node {
|
|
||||||
self.layout.compute_layout(*layout_node, window_size)?;
|
|
||||||
walk_and_apply_styles(&root_node, &mut self.layout)?;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders and calls through to the native platform window show method.
|
/// Renders and calls through to the native platform window show method.
|
||||||
|
|
|
||||||
30
lifecycle/src/reconciler/error.rs
Normal file
30
lifecycle/src/reconciler/error.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
//! Implements a set of Error types that could happen during a diff/patch/reflow
|
||||||
|
//! run. These are mostly internal to the rendering engine itself, but could potentially
|
||||||
|
//! show up elsewhere.
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
pub enum RenderEngineError {
|
||||||
|
InvalidKeyError
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for RenderEngineError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
RenderEngineError::InvalidKeyError => write!(f, "An invalid key was passed to the render engine.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for RenderEngineError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
RenderEngineError::InvalidKeyError => write!(f, "An invalid key was passed to the render engine: {{ file: {}, line: {} }}", file!(), line!())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for RenderEngineError {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,9 @@ use alchemy_styles::geometry::Size;
|
||||||
use crate::traits::Component;
|
use crate::traits::Component;
|
||||||
use crate::rsx::{Props, RSX, VirtualNode};
|
use crate::rsx::{Props, RSX, VirtualNode};
|
||||||
|
|
||||||
|
mod error;
|
||||||
|
use error::RenderEngineError;
|
||||||
|
|
||||||
// This is never actually created, it's just to satisfy the fact that View
|
// This is never actually created, it's just to satisfy the fact that View
|
||||||
// is defined in the core crate, which we can't import here without creating a
|
// is defined in the core crate, which we can't import here without creating a
|
||||||
// circular dependency.
|
// circular dependency.
|
||||||
|
|
@ -77,12 +80,37 @@ impl RenderEngine {
|
||||||
/// the new tree before discarding the old tree.
|
/// the new tree before discarding the old tree.
|
||||||
///
|
///
|
||||||
/// This calls the necessary component lifecycles per-component.
|
/// This calls the necessary component lifecycles per-component.
|
||||||
pub fn diff_and_apply_root(&self, key: &Uuid, new_root: RSX) -> Result<(), Box<Error>> {
|
pub fn diff_and_render_root(&self, key: &Uuid, child: RSX) -> Result<(), Box<Error>> {
|
||||||
/*let trees = self.trees.lock().unwrap();
|
let mut new_root = RSX::node("root", || {
|
||||||
let (old_root, stretch) = trees.remove(key)?;
|
Arc::new(RwLock::new(StubView {}))
|
||||||
diff_and_patch_trees(old_root, new_root, &mut stretch, 0)?;
|
}, {
|
||||||
trees.insert(*key, (new_root, stretch));
|
let mut props = Props::default();
|
||||||
*/
|
props.styles = "root".into();
|
||||||
|
props
|
||||||
|
});
|
||||||
|
|
||||||
|
// If it's an RSX::None, or a RSX::VirtualText, we do nothing, as... one
|
||||||
|
// requires nothing, and one isn't supported unless it's inside a <Text> tag.
|
||||||
|
if let RSX::VirtualNode(mut child) = child {
|
||||||
|
if let RSX::VirtualNode(new_root_node) = &mut new_root {
|
||||||
|
if child.tag == "Fragment" {
|
||||||
|
new_root_node.children.append(&mut child.children);
|
||||||
|
} else {
|
||||||
|
new_root_node.children.push(RSX::VirtualNode(child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut trees = self.trees.lock().unwrap();
|
||||||
|
let (old_root, mut stretch) = trees.remove(key).ok_or_else(|| RenderEngineError::InvalidKeyError {})?;
|
||||||
|
let patched_new_root = diff_and_patch_trees(old_root, new_root, &mut stretch, 0)?;
|
||||||
|
|
||||||
|
if let RSX::VirtualNode(node) = &patched_new_root {
|
||||||
|
walk_and_apply_styles(node, &mut stretch)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
trees.insert(*key, (patched_new_root, stretch));
|
||||||
|
println!("RENDERED");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in a new issue