use std::sync::{Arc, Weak};
use graphrefly_core::{Core, HandleId, NodeId};
use crate::producer::{ProducerBinding, ProducerBuildFn, ProducerCtx};
#[must_use]
pub fn from_iter(
core: &Core,
binding: &Arc<dyn ProducerBinding>,
handles: Vec<HandleId>,
) -> NodeId {
let core_weak = core.weak_handle();
let binding_weak: Weak<dyn ProducerBinding> = Arc::downgrade(binding);
let build: ProducerBuildFn = Box::new(move |ctx: ProducerCtx<'_>| {
let (Some(core_s), Some(binding_s)) = (core_weak.upgrade(), binding_weak.upgrade()) else {
return;
};
let pid = ctx.node_id();
for &h in &handles {
binding_s.retain_handle(h);
core_s.emit_or_defer(pid, h);
}
for &h in &handles {
binding_s.release_handle(h);
}
core_s.complete_or_defer(pid);
});
let fn_id = binding.register_producer_build(build);
core.register_producer(fn_id)
.expect("invariant: register_producer has no deps; no error variants reachable")
}
#[must_use]
pub fn of(core: &Core, binding: &Arc<dyn ProducerBinding>, handles: Vec<HandleId>) -> NodeId {
from_iter(core, binding, handles)
}
#[must_use]
pub fn empty(core: &Core, binding: &Arc<dyn ProducerBinding>) -> NodeId {
let core_weak = core.weak_handle();
let build: ProducerBuildFn = Box::new(move |ctx: ProducerCtx<'_>| {
let Some(core_s) = core_weak.upgrade() else {
return;
};
core_s.complete_or_defer(ctx.node_id());
});
let fn_id = binding.register_producer_build(build);
core.register_producer(fn_id)
.expect("invariant: register_producer has no deps; no error variants reachable")
}
#[must_use]
pub fn never(core: &Core, binding: &Arc<dyn ProducerBinding>) -> NodeId {
let build: ProducerBuildFn = Box::new(|_ctx: ProducerCtx<'_>| {
});
let fn_id = binding.register_producer_build(build);
core.register_producer(fn_id)
.expect("invariant: register_producer has no deps; no error variants reachable")
}
#[must_use]
pub fn throw_error(
core: &Core,
binding: &Arc<dyn ProducerBinding>,
error_handle: HandleId,
) -> NodeId {
let core_weak = core.weak_handle();
let binding_weak: Weak<dyn ProducerBinding> = Arc::downgrade(binding);
let build: ProducerBuildFn = Box::new(move |ctx: ProducerCtx<'_>| {
let (Some(core_s), Some(binding_s)) = (core_weak.upgrade(), binding_weak.upgrade()) else {
return;
};
binding_s.retain_handle(error_handle);
core_s.error_or_defer(ctx.node_id(), error_handle);
binding_s.release_handle(error_handle);
});
let fn_id = binding.register_producer_build(build);
core.register_producer(fn_id)
.expect("invariant: register_producer has no deps; no error variants reachable")
}