mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 21:28:11 +08:00
Add MemoizeImpure node and cache image base64 in graph (#1595)
* Cache base64 representation of images when converting to graphic group * Fix build * Fix build again * Actually fix it this time --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
8fa46ba63a
commit
349ec5da72
@@ -7,7 +7,7 @@ use core::cell::Cell;
|
||||
use core::marker::PhantomData;
|
||||
use core::pin::Pin;
|
||||
|
||||
// Caches the output of a given Node and acts as a proxy
|
||||
/// Caches the output of a given Node and acts as a proxy
|
||||
#[derive(Default)]
|
||||
pub struct MemoNode<T, CachedNode> {
|
||||
cache: Cell<Option<T>>,
|
||||
@@ -45,6 +45,53 @@ impl<T, CachedNode> MemoNode<T, CachedNode> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Caches the output of a given Node and acts as a proxy.
|
||||
/// In contrast to the relgular `MemoNode`. This node ignores all input.
|
||||
/// Using this node might result in the document not updating properly,
|
||||
/// use with caution.
|
||||
#[derive(Default)]
|
||||
pub struct ImpureMemoNode<I, T, CachedNode> {
|
||||
cache: Cell<Option<T>>,
|
||||
node: CachedNode,
|
||||
_phantom: std::marker::PhantomData<I>,
|
||||
}
|
||||
|
||||
impl<'i, 'o: 'i, I: 'i, T: 'i + Clone + 'o, CachedNode: 'i> Node<'i, I> for ImpureMemoNode<I, T, CachedNode>
|
||||
where
|
||||
CachedNode: for<'any_input> Node<'any_input, I>,
|
||||
for<'a> <CachedNode as Node<'a, I>>::Output: core::future::Future<Output = T> + 'a,
|
||||
{
|
||||
// TODO: This should return a reference to the cached cached_value
|
||||
// but that requires a lot of lifetime magic <- This was suggested by copilot but is pretty accurate xD
|
||||
type Output = Pin<Box<dyn Future<Output = T> + 'i>>;
|
||||
fn eval(&'i self, input: I) -> Pin<Box<dyn Future<Output = T> + 'i>> {
|
||||
Box::pin(async move {
|
||||
if let Some(cached_value) = self.cache.take() {
|
||||
self.cache.set(Some(cached_value.clone()));
|
||||
cached_value
|
||||
} else {
|
||||
let value = self.node.eval(input).await;
|
||||
self.cache.set(Some(value.clone()));
|
||||
value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn reset(&self) {
|
||||
self.cache.set(None);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I, CachedNode> ImpureMemoNode<I, T, CachedNode> {
|
||||
pub const fn new(node: CachedNode) -> ImpureMemoNode<I, T, CachedNode> {
|
||||
ImpureMemoNode {
|
||||
cache: Cell::new(None),
|
||||
node,
|
||||
_phantom: core::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores both what a node was called with and what it returned.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IORecord<I, O> {
|
||||
|
||||
Reference in New Issue
Block a user