use crate::*;
impl Clone for RenderEffect {
fn clone(&self) -> Self {
*self
}
}
impl Copy for RenderEffect {}
impl RenderEffect {
pub fn new<F>(effect_fn: F) -> Self
where
F: FnMut() + 'static,
{
let inner: Box<RenderEffectInner> = Box::new(RenderEffectInner {
effect_fn: Box::new(effect_fn),
dependencies: Vec::new(),
running: false,
disposed: false,
});
let leaked: &mut RenderEffectInner = Box::leak(inner);
let effect: RenderEffect = RenderEffect {
inner: leaked as *mut RenderEffectInner as usize,
};
effect.run_once();
effect
}
pub(crate) fn run_once(&self) {
let effect_addr: usize = self.inner;
let inner: &mut RenderEffectInner = self.leak_mut();
if inner.get_disposed() {
return;
}
if inner.get_running() {
return;
}
inner.set_running(true);
cleanup_effect_dependencies(effect_addr, inner.get_mut_dependencies());
let prev: Option<usize> = swap_current_effect(Some(effect_addr));
let inner: &mut RenderEffectInner = self.leak_mut();
(inner.get_mut_effect_fn())();
set_current_effect(prev);
let inner: &mut RenderEffectInner = self.leak_mut();
inner.set_running(false);
}
pub fn dispose(&self) {
let effect_addr: usize = self.inner;
let inner: &mut RenderEffectInner = self.leak_mut();
if inner.get_disposed() {
return;
}
inner.set_disposed(true);
cleanup_effect_dependencies(effect_addr, inner.get_mut_dependencies());
}
pub(crate) fn leak_mut(&self) -> &'static mut RenderEffectInner {
unsafe { &mut *(self.inner as *mut RenderEffectInner) }
}
}