diff --git a/src/animation.rs b/src/animation.rs index 9849109..93a0a60 100644 --- a/src/animation.rs +++ b/src/animation.rs @@ -1,6 +1,5 @@ use std::fmt; -use std::rc::{Rc, Weak}; -use std::cell::RefCell; +use std::sync::{Arc, Weak, Mutex, RwLock}; use futures_core::Async; use futures_core::future::Future; use futures_core::task::{Context, Waker}; @@ -51,12 +50,12 @@ impl Drop for Raf { struct TimestampsInner { raf: Option, // TODO make this more efficient - states: Vec>>, + states: Vec>>, } struct TimestampsGlobal { - inner: RefCell, - value: Rc>>, + inner: Mutex, + value: Arc>>, } enum TimestampsEnum { @@ -71,9 +70,9 @@ struct TimestampsState { } pub struct Timestamps { - state: Rc>, - // TODO verify that there aren't any Rc cycles - value: Rc>>, + state: Arc>, + // TODO verify that there aren't any Arc cycles + value: Arc>>, } impl Signal for Timestamps { @@ -81,12 +80,12 @@ impl Signal for Timestamps { // TODO implement Async::Ready(None) fn poll_change(&mut self, cx: &mut Context) -> Async> { - let mut lock = self.state.borrow_mut(); + let mut lock = self.state.lock().unwrap(); match lock.state { TimestampsEnum::Changed => { lock.state = TimestampsEnum::NotChanged; - Async::Ready(Some(*self.value.borrow())) + Async::Ready(Some(*self.value.read().unwrap())) }, TimestampsEnum::First => { lock.state = TimestampsEnum::NotChanged; @@ -100,69 +99,67 @@ impl Signal for Timestamps { } } -thread_local! { - static TIMESTAMPS: Rc = Rc::new(TimestampsGlobal { - inner: RefCell::new(TimestampsInner { +lazy_static! { + static ref TIMESTAMPS: Arc = Arc::new(TimestampsGlobal { + inner: Mutex::new(TimestampsInner { raf: None, states: vec![], }), - value: Rc::new(RefCell::new(None)), + value: Arc::new(RwLock::new(None)), }); } pub fn timestamps() -> Timestamps { - TIMESTAMPS.with(|global| { - let timestamps = Timestamps { - state: Rc::new(RefCell::new(TimestampsState { - state: TimestampsEnum::First, - waker: None, - })), - value: global.value.clone(), - }; + let timestamps = Timestamps { + state: Arc::new(Mutex::new(TimestampsState { + state: TimestampsEnum::First, + waker: None, + })), + value: TIMESTAMPS.value.clone(), + }; - { - let mut lock = global.inner.borrow_mut(); + { + let mut lock = TIMESTAMPS.inner.lock().unwrap(); - lock.states.push(Rc::downgrade(×tamps.state)); + lock.states.push(Arc::downgrade(×tamps.state)); - if let None = lock.raf { - let global = global.clone(); + if let None = lock.raf { + let global = TIMESTAMPS.clone(); - lock.raf = Some(Raf::new(move |time| { - let mut lock = global.inner.borrow_mut(); - let mut value = global.value.borrow_mut(); + lock.raf = Some(Raf::new(move |time| { + let mut lock = global.inner.lock().unwrap(); + let mut value = global.value.write().unwrap(); - *value = Some(time); + *value = Some(time); - lock.states.retain(|state| { - if let Some(state) = state.upgrade() { - let mut lock = state.borrow_mut(); + lock.states.retain(|state| { + if let Some(state) = state.upgrade() { + let mut lock = state.lock().unwrap(); - lock.state = TimestampsEnum::Changed; + lock.state = TimestampsEnum::Changed; - if let Some(waker) = lock.waker.take() { - drop(lock); - waker.wake(); - } - - true - - } else { - false + if let Some(waker) = lock.waker.take() { + drop(lock); + waker.wake(); } - }); - if lock.states.len() == 0 { - lock.raf = None; - // TODO is this a good idea ? - lock.states = vec![]; + true + + } else { + false } - })); - } - } + }); - timestamps - }) + if lock.states.len() == 0 { + lock.raf = None; + // TODO is this a good idea ? + lock.states = vec![]; + } + })); + } + } + + timestamps } @@ -497,17 +494,17 @@ struct MutableAnimationState { } struct MutableAnimationInner { - state: RefCell, + state: Mutex, value: Mutable, } pub struct MutableAnimation { - inner: Rc, + inner: Arc, } impl fmt::Debug for MutableAnimation { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let state = self.inner.state.borrow(); + let state = self.inner.state.lock().unwrap(); fmt.debug_struct("MutableAnimation") .field("playing", &state.playing) @@ -524,8 +521,8 @@ impl MutableAnimation { debug_assert!(duration >= 0.0); Self { - inner: Rc::new(MutableAnimationInner { - state: RefCell::new(MutableAnimationState { + inner: Arc::new(MutableAnimationInner { + state: Mutex::new(MutableAnimationState { playing: true, duration: duration, end: initial, @@ -578,7 +575,7 @@ impl MutableAnimation { // TODO don't update if the new value is the same as the old value if diff >= 1.0 { { - let mut lock = state.inner.state.borrow_mut(); + let mut lock = state.inner.state.lock().unwrap(); Self::stop_animating(&mut lock); } state.inner.value.set(Percentage::new_unchecked(end)); @@ -607,7 +604,7 @@ impl MutableAnimation { pub fn set_duration(&self, duration: f64) { debug_assert!(duration >= 0.0); - let mut lock = self.inner.state.borrow_mut(); + let mut lock = self.inner.state.lock().unwrap(); if lock.duration != duration { lock.duration = duration; @@ -617,7 +614,7 @@ impl MutableAnimation { #[inline] pub fn pause(&self) { - let mut lock = self.inner.state.borrow_mut(); + let mut lock = self.inner.state.lock().unwrap(); if lock.playing { lock.playing = false; @@ -627,7 +624,7 @@ impl MutableAnimation { #[inline] pub fn play(&self) { - let mut lock = self.inner.state.borrow_mut(); + let mut lock = self.inner.state.lock().unwrap(); if !lock.playing { lock.playing = true; @@ -647,13 +644,13 @@ impl MutableAnimation { } pub fn jump_to(&self, end: Percentage) { - let mut lock = self.inner.state.borrow_mut(); + let mut lock = self.inner.state.lock().unwrap(); Self::_jump_to(&mut lock, &self.inner.value, end); } pub fn animate_to(&self, end: Percentage) { - let mut lock = self.inner.state.borrow_mut(); + let mut lock = self.inner.state.lock().unwrap(); if lock.end != end { if lock.duration <= 0.0 { diff --git a/src/operations.rs b/src/operations.rs index 8fb5cbf..43aba49 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -1,5 +1,4 @@ -use std::rc::Rc; -use std::cell::RefCell; +use std::sync::{Arc, Mutex}; use std::mem::ManuallyDrop; use stdweb::PromiseFuture; use discard::{Discard, DiscardOnDrop}; @@ -143,8 +142,8 @@ pub fn insert_children_signal_vec(element: &A, callbacks: &mut Callbacks, children: Vec, } - // TODO use two separate Rcs ? - let state = Rc::new(RefCell::new(State { + // TODO use two separate Arcs ? + let state = Arc::new(Mutex::new(State { is_inserted: false, children: vec![], })); @@ -153,7 +152,7 @@ pub fn insert_children_signal_vec(element: &A, callbacks: &mut Callbacks, let state = state.clone(); callbacks.after_insert(move |_| { - let mut state = state.borrow_mut(); + let mut state = state.lock().unwrap(); if !state.is_inserted { state.is_inserted = true; @@ -167,7 +166,7 @@ pub fn insert_children_signal_vec(element: &A, callbacks: &mut Callbacks, // TODO verify that this will drop `children` callbacks.after_remove(for_each_vec(signal.into_signal_vec(), move |change| { - let mut state = state.borrow_mut(); + let mut state = state.lock().unwrap(); match change { VecDiff::Replace { values } => {