///|
pub(all) struct ComponentEffect {
key : String
cleanup : (() -> Unit)?
cleanup_with_reason : ((ComponentEffectCancelReason) -> Unit)?
mut status : ComponentEffectStatus
mut cancel_reason : ComponentEffectCancelReason?
mut reused : Bool
}
///|
pub(all) enum ComponentEffectStatus {
EffectActive
EffectCancelled
} derive(Eq, Debug, ToJson)
///|
pub(all) enum ComponentEffectCancelReason {
EffectKeyChanged
EffectUnmounted
EffectRuntimeDestroyed
} derive(Eq, Debug, ToJson)
///|
pub fn ComponentEffect::new(
key~ : String,
cleanup? : (() -> Unit)? = None,
cleanup_with_reason? : ((ComponentEffectCancelReason) -> Unit)? = None,
) -> ComponentEffect {
{
key,
cleanup,
cleanup_with_reason,
status: ComponentEffectStatus::EffectActive,
cancel_reason: None,
reused: false,
}
}
///|
pub fn ComponentEffect::cancel(self : ComponentEffect) -> Unit {
self.cancel_with_reason(ComponentEffectCancelReason::EffectUnmounted)
}
///|
pub fn ComponentEffect::cancel_with_reason(
self : ComponentEffect,
reason : ComponentEffectCancelReason,
) -> Unit {
self.status = ComponentEffectStatus::EffectCancelled
self.cancel_reason = Some(reason)
match self.cleanup_with_reason {
Some(cleanup) => cleanup(reason)
None => ()
}
match self.cleanup {
Some(cleanup) => cleanup()
None => ()
}
}
///|
pub fn BuildContext::run_effect(
self : BuildContext,
key~ : String,
effect : () -> (() -> Unit)?,
) -> Unit {
match self.take_old_effect(key) {
Some(existing) => {
existing.reused = true
self.effects.push(existing)
}
None => self.effects.push(ComponentEffect::new(key~, cleanup=effect()))
}
}
///|
pub fn BuildContext::run_effect_with_reason(
self : BuildContext,
key~ : String,
effect : () -> ((ComponentEffectCancelReason) -> Unit)?,
) -> Unit {
match self.take_old_effect(key) {
Some(existing) => {
existing.reused = true
self.effects.push(existing)
}
None =>
self.effects.push(
ComponentEffect::new(key~, cleanup_with_reason=effect()),
)
}
}
///|
fn cancel_component_effects(
effects : Array[ComponentEffect],
reason? : ComponentEffectCancelReason = ComponentEffectCancelReason::EffectUnmounted,
) -> Unit {
for effect in effects {
effect.cancel_with_reason(reason)
}
}