Cleaning

By default, values in the Depends dependency graph do not perform any cleanup between graph calculations. This means any transient state being tracked will remain.

If you need to perform cleanup on a value, you can specify the #[depends(custom_clean)] attribute.

struct Post {
    id: i64,
    // ... your fields go here
}

// This node allows dependencies to iterate only values which have changed
// since the graph was last resolved.
#[derive(Value, Default)]
#[depends(custom_clean)]
struct Posts {
    // Keep track of all the posts we've seen.
    all_posts: HashMap<i64, Post>,
    // Track which data has changed since the last time we resolved this
    // node. Don't worry about how we populate this for now.
    changed_post_ids: Vec<i64>,
    #[depends(hash)]
    generation: usize,
}

impl Clean for Posts {
    fn clean(&mut self) {
        // We _must_ clean up any temporary state used to track changes.
        self.changed_post_ids.clear();
    }
}

impl Posts {
    // This public method can be called by any dependency of `Posts` to
    // iterate only the new/changed values.
    pub fn iter_changed(&self) -> impl Iterator<Item = &Post> + '_ {
        self.changed_post_ids.iter().map(|key| &self.all_posts[key])
    }
}

When this attribute is used, you are required to implement the Clean trait for the struct. The Clean trait contains a single method, clean, which should be implemented to reset any transient state being tracked by your struct.

This enables you to manually control the cleanup process between computations, ensuring that your transient state is always correctly managed.

Correct cleanup is vital to maintain the accuracy and efficiency of your computations.