Updates for recent versions of Rust.
* Added lots of dyns * Removed unused whitespace. * Removed rust-toolchain because stable rust compiles the project. * Fixed Doc-tests with ignore keyword.
This commit is contained in:
parent
f15cf258af
commit
5695ec9b94
23 changed files with 170 additions and 171 deletions
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
/// A generic Error type that we use. It currently just aliases to `Box<std::error::Error>`,
|
||||
/// but could change in the future.
|
||||
pub type Error = Box<std::error::Error>;
|
||||
pub type Error = Box<dyn std::error::Error>;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ impl GenericRootView {
|
|||
}
|
||||
|
||||
impl Props for GenericRootView {
|
||||
fn set_props(&mut self, _: &mut Any) {}
|
||||
fn set_props(&mut self, _: &mut dyn Any) {}
|
||||
}
|
||||
|
||||
impl Component for GenericRootView {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Implements tree diffing, updating, and so on. Unlike a lot of the VDom implementations
|
||||
//! you find littered around the web, this is a bit more ECS-ish, and expects Components to retain
|
||||
//! their `ComponentKey` passed in their constructor if they want to update. Doing this
|
||||
//! Implements tree diffing, updating, and so on. Unlike a lot of the VDom implementations
|
||||
//! you find littered around the web, this is a bit more ECS-ish, and expects Components to retain
|
||||
//! their `ComponentKey` passed in their constructor if they want to update. Doing this
|
||||
//! enables us to avoid re-scanning or diffing an entire tree.
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
|
@ -48,12 +48,12 @@ impl RenderEngine {
|
|||
// pub fn queue_update_for(&self, component_ptr: usize, updater: Box<Fn() -> Component + Send + Sync + 'static>) {
|
||||
// }
|
||||
|
||||
/// `Window`'s (or anything "root" in nature) need to register with the
|
||||
/// `Window`'s (or anything "root" in nature) need to register with the
|
||||
/// reconciler for things like setState to work properly. When they do so,
|
||||
/// they get a key back. When they want to instruct the global `RenderEngine`
|
||||
/// to re-render or update their tree, they pass that key and whatever the new tree
|
||||
/// they get a key back. When they want to instruct the global `RenderEngine`
|
||||
/// to re-render or update their tree, they pass that key and whatever the new tree
|
||||
/// should be.
|
||||
pub fn register_root_component<C: Component + 'static>(&self, component: C) -> Result<ComponentKey, Box<Error>> {
|
||||
pub fn register_root_component<C: Component + 'static>(&self, component: C) -> Result<ComponentKey, Box<dyn Error>> {
|
||||
// Conceivably, this doesn't NEED to be a thing... but for now it is. If you've stumbled
|
||||
// upon here, wayward traveler, in need of a non-native-root-component, please open an
|
||||
// issue to discuss. :)
|
||||
|
|
@ -75,7 +75,7 @@ impl RenderEngine {
|
|||
Ok(component_key)
|
||||
}
|
||||
|
||||
/// Rendering the root node is a bit different than rendering or updating other nodes, as we
|
||||
/// Rendering the root node is a bit different than rendering or updating other nodes, as we
|
||||
/// never want to unmount it, and the results come from a non-`Component` entity (e.g, a
|
||||
/// `Window`). Thus, for this one, we do some manual mucking with what we know is the
|
||||
/// root view (a `Window` or such root component would call this with it's registered
|
||||
|
|
@ -85,7 +85,7 @@ impl RenderEngine {
|
|||
key: ComponentKey,
|
||||
dimensions: (f64, f64),
|
||||
child: RSX
|
||||
) -> Result<(), Box<Error>> {
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let mut component_store = self.components.lock().unwrap();
|
||||
let mut layout_store = self.layouts.lock().unwrap();
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ impl RenderEngine {
|
|||
width: Number::Defined(dimensions.0 as f32),
|
||||
height: Number::Defined(dimensions.1 as f32)
|
||||
})?;
|
||||
|
||||
|
||||
walk_and_apply_styles(key, &mut component_store, &mut layout_store)?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -138,8 +138,8 @@ fn recursively_diff_tree(
|
|||
new_tree: RSX,
|
||||
component_store: &mut ComponentStore,
|
||||
layout_store: &mut LayoutStore
|
||||
) -> Result<(), Box<Error>> {
|
||||
// First we need to determine if this node is being replaced or updated. A replace happens if
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
// First we need to determine if this node is being replaced or updated. A replace happens if
|
||||
// two nodes are different types - in this case, we check their tag values. This is also a case
|
||||
// where, for instance, if the RSX tag is `::None` or `::VirtualText`, we'll treat it as
|
||||
// replacing with nothing.
|
||||
|
|
@ -173,7 +173,7 @@ fn recursively_diff_tree(
|
|||
if let RSX::VirtualNode(mut child) = new_tree {
|
||||
for new_child_tree in child.children {
|
||||
match old_children.pop() {
|
||||
// If there's a key in the old children for this position, it's
|
||||
// If there's a key in the old children for this position, it's
|
||||
// something we need to update, so let's recurse right back into it.
|
||||
Some(old_child_key) => {
|
||||
recursively_diff_tree(
|
||||
|
|
@ -184,7 +184,7 @@ fn recursively_diff_tree(
|
|||
)?;
|
||||
},
|
||||
|
||||
// If there's no matching old key in this position, then we've got a
|
||||
// If there's no matching old key in this position, then we've got a
|
||||
// new component instance to mount. This part now diverts into the Mount
|
||||
// phase.
|
||||
None => {
|
||||
|
|
@ -218,17 +218,17 @@ fn recursively_diff_tree(
|
|||
/// tree, emitting required lifecycle events and persisting values. This happens in an inward-out
|
||||
/// fashion, which helps avoid unnecessary reflow in environments where it can get tricky.
|
||||
///
|
||||
/// This method returns a Result, the `Ok` variant containing a tuple of Vecs. These are the child
|
||||
/// This method returns a Result, the `Ok` variant containing a tuple of Vecs. These are the child
|
||||
/// Component instances and Layout instances that need to be set in the stores.
|
||||
fn mount_component_tree(
|
||||
tree: VirtualNode,
|
||||
component_store: &mut ComponentStore,
|
||||
layout_store: &mut LayoutStore
|
||||
) -> Result<ComponentKey, Box<Error>> {
|
||||
) -> Result<ComponentKey, Box<dyn Error>> {
|
||||
let key = component_store.new_key();
|
||||
let component = (tree.create_component_fn)(key);
|
||||
let is_native_backed = component.has_native_backing_node();
|
||||
|
||||
|
||||
// let state = get_derived_state_from_props()
|
||||
let mut instance = Instance {
|
||||
tag: tree.tag,
|
||||
|
|
@ -243,7 +243,7 @@ fn mount_component_tree(
|
|||
THEME_ENGINE.configure_styles_for_keys(&instance.style_keys, &mut style, &mut instance.appearance);
|
||||
instance.layout = Some(layout_store.new_node(style, vec![])?);
|
||||
}
|
||||
|
||||
|
||||
let rendered = instance.component.render(tree.children);
|
||||
// instance.get_snapshot_before_update()
|
||||
component_store.insert(key, instance)?;
|
||||
|
|
@ -258,7 +258,7 @@ fn mount_component_tree(
|
|||
for child_tree in child.children {
|
||||
if let RSX::VirtualNode(child_tree) = child_tree {
|
||||
let child_key = mount_component_tree(child_tree, component_store, layout_store)?;
|
||||
|
||||
|
||||
component_store.add_child(key, child_key)?;
|
||||
if is_native_backed {
|
||||
link_layout_nodess(key, child_key, component_store, layout_store)?;
|
||||
|
|
@ -267,7 +267,7 @@ fn mount_component_tree(
|
|||
}
|
||||
} else {
|
||||
let child_key = mount_component_tree(child, component_store, layout_store)?;
|
||||
|
||||
|
||||
component_store.add_child(key, child_key)?;
|
||||
if is_native_backed {
|
||||
link_layout_nodess(key, child_key, component_store, layout_store)?;
|
||||
|
|
@ -298,12 +298,12 @@ fn unmount_component_tree(
|
|||
key: ComponentKey,
|
||||
component_store: &mut ComponentStore,
|
||||
layout_store: &mut LayoutStore
|
||||
) -> Result<Vec<LayoutNode>, Box<Error>> {
|
||||
) -> Result<Vec<LayoutNode>, Box<dyn Error>> {
|
||||
let mut instance = component_store.remove(key)?;
|
||||
instance.component.component_will_unmount();
|
||||
|
||||
|
||||
let mut layout_nodes = vec![];
|
||||
|
||||
|
||||
let children = component_store.children(key)?;
|
||||
for child in children {
|
||||
match unmount_component_tree(child, component_store, layout_store) {
|
||||
|
|
@ -327,8 +327,8 @@ fn unmount_component_tree(
|
|||
}
|
||||
|
||||
/// Given a tree, will walk the branches until it finds the next root nodes to connect.
|
||||
/// While this sounds slow, in practice it rarely has to go far in any direction. This could
|
||||
/// potentially be done away with some hoisting magic in the `mount()` recursion, but I couldn't
|
||||
/// While this sounds slow, in practice it rarely has to go far in any direction. This could
|
||||
/// potentially be done away with some hoisting magic in the `mount()` recursion, but I couldn't
|
||||
/// find a pattern that didn't feel like some utter magic in Rust.
|
||||
///
|
||||
/// It might be because I'm writing this at 3AM. Feel free to improve it.
|
||||
|
|
@ -337,7 +337,7 @@ fn link_layout_nodess(
|
|||
child: ComponentKey,
|
||||
components: &mut ComponentStore,
|
||||
layouts: &mut LayoutStore
|
||||
) -> Result<(), Box<Error>> {
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
if let (Ok(parent_instance), Ok(child_instance)) = (components.get(parent), components.get(child)) {
|
||||
if let (Some(parent_layout), Some(child_layout)) = (parent_instance.layout, child_instance.layout) {
|
||||
layouts.add_child(parent_layout, child_layout)?;
|
||||
|
|
@ -364,7 +364,7 @@ fn walk_and_apply_styles(
|
|||
key: ComponentKey,
|
||||
components: &mut ComponentStore,
|
||||
layouts: &mut LayoutStore
|
||||
) -> Result<(), Box<Error>> {
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let instance = components.get_mut(key)?;
|
||||
|
||||
if let Some(layout_key) = instance.layout {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ impl RSX {
|
|||
pub fn node<P: Any + 'static>(
|
||||
tag: &'static str,
|
||||
styles: StylesList,
|
||||
create_fn: fn(key: ComponentKey) -> Box<Component>,
|
||||
create_fn: fn(key: ComponentKey) -> Box<dyn Component>,
|
||||
props: P,
|
||||
children: Vec<RSX>
|
||||
) -> RSX {
|
||||
|
|
@ -43,9 +43,9 @@ impl RSX {
|
|||
children: children
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/// Shorthand method for creating a new `RSX::VirtualText` instance. Rarely should you call
|
||||
/// this yourself; the `rsx! {}` and `text!()` macros handle this for you.
|
||||
/// this yourself; the `rsx! {}` and `text!()` macros handle this for you.
|
||||
pub fn text(s: String) -> RSX {
|
||||
RSX::VirtualText(VirtualText(s))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ pub struct VirtualNode {
|
|||
|
||||
/// `Component` instances are created on-demand, if the reconciler deems it be so. This
|
||||
/// is a closure that should return an instance of the correct type.
|
||||
pub create_component_fn: fn(key: ComponentKey) -> Box<Component>,
|
||||
pub create_component_fn: fn(key: ComponentKey) -> Box<dyn Component>,
|
||||
|
||||
/// When some RSX is returned, we scoop up the props inside a special block, and then shove
|
||||
/// them in here as an `Any` object. When you `derive(Props)` on a `Component` struct, it
|
||||
/// them in here as an `Any` object. When you `derive(Props)` on a `Component` struct, it
|
||||
/// creates a setter that specifically handles downcasting and persisting props for you.
|
||||
pub props: Box<Any>,
|
||||
pub props: Box<dyn Any>,
|
||||
|
||||
/// Child components for this node.
|
||||
pub children: Vec<RSX>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ pub trait AppDelegate: Send + Sync {
|
|||
fn will_resign_active(&mut self) {}
|
||||
|
||||
/// Fired when an Application has resigned active.
|
||||
fn did_resign_active(&mut self) {}
|
||||
fn did_resign_active(&mut self) {}
|
||||
|
||||
/// Fired when an Application is going to terminate. You can use this to, say, instruct the
|
||||
/// system to "wait a minute, lemme finish".
|
||||
|
|
@ -73,11 +73,11 @@ pub trait WindowDelegate: Send + Sync {
|
|||
}
|
||||
|
||||
pub trait Props {
|
||||
fn set_props(&mut self, new_props: &mut Any);
|
||||
fn set_props(&mut self, new_props: &mut dyn Any);
|
||||
}
|
||||
|
||||
/// The `Component` lifecycle, mostly inspired from React, with a few extra methods for views that
|
||||
/// need to have a backing native layer. A good breakdown of the React Component lifecycle can be
|
||||
/// need to have a backing native layer. A good breakdown of the React Component lifecycle can be
|
||||
/// found [in this tweet](https://twitter.com/dan_abramov/status/981712092611989509?lang=en).
|
||||
///
|
||||
/// Alchemy does not currently implement Hooks, and at the moment has no plans to do so (the API
|
||||
|
|
@ -106,7 +106,7 @@ pub trait Component: Props + Send + Sync {
|
|||
/// `node`, you need to instruct the system how to remove it from the tree at your point.
|
||||
fn remove_child_node(&self, _component: PlatformSpecificNodeType) {}
|
||||
|
||||
/// Given a configured 'appearance' and computed `layout`, this method should transform them
|
||||
/// Given a configured 'appearance' and computed `layout`, this method should transform them
|
||||
/// into appropriate calls to the backing native node.
|
||||
fn apply_styles(&self, _appearance: &Appearance, _layout: &Layout) {}
|
||||
|
||||
|
|
@ -114,80 +114,80 @@ pub trait Component: Props + Send + Sync {
|
|||
/// It should return an object to update the state, or null to update nothing.
|
||||
/// This method exists for rare use cases where the state depends on changes in props over time.
|
||||
fn get_derived_state_from_props(&self) {}
|
||||
|
||||
|
||||
/// Invoked right before the most recently rendered output is committed to the backing layer tree.
|
||||
/// It enables your component to capture some information from the tree (e.g. scroll position) before it's
|
||||
/// potentially changed. Any value returned by this lifecycle will be passed as a parameter
|
||||
/// It enables your component to capture some information from the tree (e.g. scroll position) before it's
|
||||
/// potentially changed. Any value returned by this lifecycle will be passed as a parameter
|
||||
/// to component_did_update().
|
||||
///
|
||||
/// This use case is not common, but it may occur in UIs like a chat thread that need to handle scroll
|
||||
///
|
||||
/// This use case is not common, but it may occur in UIs like a chat thread that need to handle scroll
|
||||
/// position in a special way. A snapshot value (or None) should be returned.
|
||||
fn get_snapshot_before_update(&self) {}
|
||||
|
||||
/// Invoked immediately after a component is mounted (inserted into the tree).
|
||||
/// If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
|
||||
/// This method is also a good place to set up any subscriptions. If you do that, don’t forget to unsubscribe
|
||||
/// This method is also a good place to set up any subscriptions. If you do that, don’t forget to unsubscribe
|
||||
/// in component_will_unmount().
|
||||
fn component_did_mount(&mut self) {}
|
||||
|
||||
/// Invoked immediately after updating occurs. This method is not called for the initial render.
|
||||
/// This is also a good place to do network requests as long as you compare the current props to previous props
|
||||
/// This is also a good place to do network requests as long as you compare the current props to previous props
|
||||
/// (e.g. a network request may not be necessary if the props have not changed).
|
||||
fn component_did_update(&mut self) {}
|
||||
|
||||
/// Invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this
|
||||
/// method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that
|
||||
/// Invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this
|
||||
/// method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that
|
||||
/// were created in component_did_mount().
|
||||
///
|
||||
/// You should not call set state in this method because the component will never be re-rendered. Once a
|
||||
///
|
||||
/// You should not call set state in this method because the component will never be re-rendered. Once a
|
||||
/// component instance is unmounted, it will never be mounted again.
|
||||
fn component_will_unmount(&mut self) {}
|
||||
|
||||
/// Invoked after an error has been thrown by a descendant component. Called during the "commit" phase,
|
||||
/// Invoked after an error has been thrown by a descendant component. Called during the "commit" phase,
|
||||
/// so side-effects are permitted. It should be used for things like logging errors (e.g,
|
||||
/// Sentry).
|
||||
fn component_did_catch(&mut self /* error: */) {}
|
||||
|
||||
/// Use this to let Alchemy know if a component’s output is not affected by the current change in state
|
||||
/// or props. The default behavior is to re-render on every state change, and in the vast majority of
|
||||
/// Use this to let Alchemy know if a component’s output is not affected by the current change in state
|
||||
/// or props. The default behavior is to re-render on every state change, and in the vast majority of
|
||||
/// cases you should rely on the default behavior.
|
||||
///
|
||||
/// This is invoked before rendering when new props or state are being received. Defaults to true. This
|
||||
/// method is not called for the initial render or when force_update() is used. This method only exists
|
||||
/// This is invoked before rendering when new props or state are being received. Defaults to true. This
|
||||
/// method is not called for the initial render or when force_update() is used. This method only exists
|
||||
/// as a performance optimization. Do not rely on it to “prevent” a rendering, as this can lead to bugs.
|
||||
fn should_component_update(&self) -> bool { true }
|
||||
|
||||
/// The only required method for a `Component`. Should return a Result of RSX nodes, or an
|
||||
/// Error (in very rare cases, such as trying to get a key from a strange HashMap or
|
||||
/// something).
|
||||
/// something).
|
||||
///
|
||||
/// The render() function should be pure, meaning that it does not modify component state, it
|
||||
/// returns the same result each time it’s invoked, and it does not directly interact with the
|
||||
/// The render() function should be pure, meaning that it does not modify component state, it
|
||||
/// returns the same result each time it’s invoked, and it does not directly interact with the
|
||||
/// backing rendering framework.
|
||||
///
|
||||
/// If you need to interact with the native layer, perform your work in component_did_mount() or the other
|
||||
/// If you need to interact with the native layer, perform your work in component_did_mount() or the other
|
||||
/// lifecycle methods instead. Keeping `render()` pure makes components easier to think about.
|
||||
///
|
||||
/// This method is not called if should_component_update() returns `false`.
|
||||
fn render(&self, children: Vec<RSX>) -> Result<RSX, Error> { Ok(RSX::None) }
|
||||
|
||||
/// This lifecycle is invoked after an error has been thrown by a descendant component. It receives
|
||||
/// This lifecycle is invoked after an error has been thrown by a descendant component. It receives
|
||||
/// the error that was thrown as a parameter and should return a value to update state.
|
||||
///
|
||||
/// This is called during the "render" phase, so side-effects are not permitted.
|
||||
/// This is called during the "render" phase, so side-effects are not permitted.
|
||||
/// For those use cases, use component_did_catch() instead.
|
||||
fn get_derived_state_from_error(&self, _error: ()) {}
|
||||
|
||||
/// By default, when your component’s state or props change, your component will re-render.
|
||||
/// If your `render()` method depends on some other data, you can tell Alchemy that the component
|
||||
/// By default, when your component’s state or props change, your component will re-render.
|
||||
/// If your `render()` method depends on some other data, you can tell Alchemy that the component
|
||||
/// needs re-rendering by calling `force_update()`.
|
||||
///
|
||||
/// Calling `force_update()` will cause `render()` to be called on the component, skipping
|
||||
/// `should_component_update()`. This will trigger the normal lifecycle methods for child components,
|
||||
/// including the `should_component_update()` method of each child. Alchemy will still only update the
|
||||
/// Calling `force_update()` will cause `render()` to be called on the component, skipping
|
||||
/// `should_component_update()`. This will trigger the normal lifecycle methods for child components,
|
||||
/// including the `should_component_update()` method of each child. Alchemy will still only update the
|
||||
/// backing widget tree if the markup changes.
|
||||
///
|
||||
/// Normally, you should try to avoid all uses of `force_update()` and only read from `this.props`
|
||||
/// Normally, you should try to avoid all uses of `force_update()` and only read from `this.props`
|
||||
/// and `this.state` in `render()`.
|
||||
fn force_update(&self) {}
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue