Skip to content

Commit

Permalink
Merge pull request #19 from fwcd/diff-trait
Browse files Browse the repository at this point in the history
Replace `NodeDiff` with derived `Diff` trait
  • Loading branch information
fwcd authored Sep 5, 2024
2 parents eb0e0f9 + 7e7b2e7 commit dc1d77b
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 141 deletions.
130 changes: 0 additions & 130 deletions nuit-core/src/node/diff.rs

This file was deleted.

2 changes: 0 additions & 2 deletions nuit-core/src/node/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
mod diff;
mod modifier;
mod node;
mod shape;

pub(crate) use diff::*;
pub use modifier::*;
pub use node::*;
pub use shape::*;
3 changes: 2 additions & 1 deletion nuit-core/src/node/node.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use nuit_derive::Diff;
use serde::{Serialize, Deserialize};

use crate::{Alignment, Id, IdPath, IdPathBuf, Identified};

use super::{ModifierNode, ShapeNode};

/// A rendered UI component tree.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Diff, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", rename_all_fields = "camelCase")]
pub enum Node {
Empty {}, // Intentionally not a unit variant for uniform serialization
Expand Down
19 changes: 11 additions & 8 deletions nuit-core/src/root.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{cell::RefCell, rc::Rc};

use crate::{Context, Event, IdPath, IdPathBuf, Node, NodeDiff, Storage, View};
use crate::{Context, Diff, Event, IdPath, IdPathBuf, Node, Storage, View};

/// The central state of a Nuit application.
pub struct Root<T> {
Expand Down Expand Up @@ -29,16 +29,19 @@ impl<T> Root<T> where T: View {
self.view.borrow().render(&Context::new(self.storage.clone()))
});

let diff = NodeDiff::between(&new_render, &self.last_render.borrow());
{
let last_render = self.last_render.borrow();
let diff = new_render.diff(&last_render);

for id_path in diff.removed() {
self.view.borrow().fire(&Event::Disappear, id_path)
}
for (id_path, _) in &diff.removed {
self.view.borrow().fire(&Event::Disappear, id_path)
}

self.storage.apply_changes();
self.storage.apply_changes();

for id_path in diff.added() {
self.view.borrow().fire(&Event::Appear, id_path)
for (id_path, _) in &diff.added {
self.view.borrow().fire(&Event::Appear, id_path)
}
}

*self.last_render.borrow_mut() = new_render.clone();
Expand Down
47 changes: 47 additions & 0 deletions nuit-core/src/utils/diff.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use super::{IdPath, IdPathBuf};

/// A type that can be diffed in terms of id paths.
pub trait Diff: Sized {
/// Appends the difference to "construct" this type from the given other one
/// to the given difference.
fn record_diff<'a>(&'a self, old: &'a Self, id_path: &IdPath, difference: &mut Difference<&'a Self>);

/// Computes the difference to "construct" this type from the given other one.
fn diff<'a>(&'a self, old: &'a Self) -> Difference<&'a Self> {
let mut difference = Difference::new();
self.record_diff(old, IdPath::root(), &mut difference);
return difference;
}
}

/// The difference between two values.
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Difference<T> {
pub removed: Vec<(IdPathBuf, T)>,
pub changed: Vec<(IdPathBuf, T, T)>,
pub added: Vec<(IdPathBuf, T)>,
}

impl<T> Difference<T> {
pub fn new() -> Self {
Self {
removed: Vec::new(),
changed: Vec::new(),
added: Vec::new(),
}
}

pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Difference<U> {
Difference {
removed: self.removed.into_iter().map(|(p, x)| (p, f(x))).collect(),
changed: self.changed.into_iter().map(|(p, x, y)| (p, f(x), f(y))).collect(),
added: self.added.into_iter().map(|(p, x)| (p, f(x))).collect(),
}
}
}

impl<T> Default for Difference<T> {
fn default() -> Self {
Self::new()
}
}
2 changes: 2 additions & 0 deletions nuit-core/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod angle;
mod approx_eq;
mod clone;
mod color;
mod diff;
mod frame;
mod has_id;
mod id_path;
Expand All @@ -18,6 +19,7 @@ pub use alignment::*;
pub use angle::*;
pub use approx_eq::*;
pub use color::*;
pub use diff::*;
pub use frame::*;
pub use has_id::*;
pub use id_path::*;
Expand Down
1 change: 1 addition & 0 deletions nuit-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ proc-macro = true
[dependencies]
syn = "2.0"
quote = "1.0"
proc-macro2 = "1.0.86"
Loading

0 comments on commit dc1d77b

Please sign in to comment.