use std::hash::Hash;
use crate::cards::Card;
use crate::state::StateId;
use crate::CardCtx;
use crate::NotebookCtx;
type StatefulCardFn<T> = dyn for<'a, 'b> FnMut(&'a mut CardCtx<'b>, &mut T);
pub struct StatefulCard<T> {
state: StateId<T>,
function: Box<StatefulCardFn<T>>,
}
impl<T> StatefulCard<T> {
pub(crate) fn new(
state: StateId<T>,
function: impl for<'a, 'b> FnMut(&'a mut CardCtx<'b>, &mut T) + 'static,
) -> Self {
Self {
state,
function: Box::new(function),
}
}
}
impl<T: Send + Sync + 'static> Card for StatefulCard<T> {
fn draw(&mut self, ctx: &mut CardCtx<'_>) {
let mut current = self.state.read_mut(ctx);
(self.function)(ctx, &mut current);
}
}
#[track_caller]
pub fn stateful_card<K, T>(
nb: &mut NotebookCtx,
key: &K,
init: T,
function: impl for<'a, 'b> FnMut(&'a mut CardCtx<'b>, &mut T) + 'static,
) -> StateId<T>
where
K: Hash + ?Sized,
T: Send + Sync + 'static,
{
nb.state(key, init, function)
}