1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
use std::cell::{Ref, RefMut}; use std::marker::PhantomData; use super::{Link, Weak, WeakReference}; pub struct Reference<T> { instance_id: usize, reference_id: usize, marker: PhantomData<T>, } impl<T> Reference<T> where T: 'static, { pub(crate) fn new(instance_id: usize, reference_id: usize) -> Reference<T> { Reference { instance_id, reference_id, marker: PhantomData, } } pub fn get<'a, L>(&self, link: &'a L) -> Ref<'a, T> where L: Link, { assert_eq!(self.instance_id, link.instance().id); Ref::map(link.memory().reference(self.reference_id), |reference| { reference.downcast_ref().unwrap() }) } pub fn replace<L>(&self, link: &L, value: T) -> T where L: Link, { assert_eq!(self.instance_id, link.instance().id); let reference = link.memory().reference_mut(self.reference_id); let mut reference = RefMut::map(reference, |reference| reference.downcast_mut().unwrap()); std::mem::replace(&mut reference, value) } pub fn apply<L, F, O>(&self, link: &L, op: F) -> O where L: Link, F: FnOnce(&mut T) -> O, { assert_eq!(self.instance_id, link.instance().id); let reference = link.memory().reference_mut(self.reference_id); let mut reference = RefMut::map(reference, |reference| reference.downcast_mut().unwrap()); op(&mut reference) } pub fn weak<L>(self, link: &L) -> WeakReference<L::Platform, T> where L: Link, { assert_eq!(self.instance_id, link.instance().id); WeakReference::new(Weak::new(link.instance()), self) } } impl<T> Reference<T> where T: Default + 'static, { pub fn take<L>(&self, link: &L) -> T where L: Link, T: Default, { self.replace(link, Default::default()) } } impl<T> Clone for Reference<T> { fn clone(&self) -> Self { *self } } impl<T> Copy for Reference<T> {}