Created
December 30, 2020 01:42
-
-
Save yongkyuns/859bf6f78d4a637f0caaf51d93c9a436 to your computer and use it in GitHub Desktop.
Modelling child that holds partial reference to parent's data using Rc,RefCell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::cell::RefCell; | |
use std::rc::Rc; | |
use std::rc::Weak; | |
pub type RefPoint = Rc<RefCell<Point>>; | |
pub type WeakPoint = Weak<RefCell<Point>>; | |
#[derive(Debug)] | |
pub struct Point { | |
x: f32, | |
y: f32, | |
} | |
#[derive(Debug)] | |
pub struct Object { | |
pub position: RefPoint, | |
pub origin: Option<WeakPoint>, | |
} | |
impl Object { | |
pub fn new() -> Self { | |
Self { | |
position: Rc::new(RefCell::new(Point { x: 0.0, y: 0.0 })), | |
origin: None, | |
} | |
} | |
pub fn set_origin(&mut self, parent: RefPoint) { | |
self.origin = Some(Rc::downgrade(&parent)); | |
} | |
pub fn move_by(&mut self, x: f32, y: f32) { | |
self.position.borrow_mut().x += x; | |
self.position.borrow_mut().y += y; | |
} | |
pub fn get_origin(&self) -> Option<Point> { | |
if let Some(origin) = &self.origin { | |
if let Some(point) = origin.upgrade() { | |
let p = point.borrow(); | |
Some(Point { x: p.x, y: p.y }) | |
} else { | |
None | |
} | |
} else { | |
None | |
} | |
} | |
} | |
impl HasRefPosition for Object { | |
fn position(&self) -> RefPoint { | |
Rc::clone(&self.position) | |
} | |
} | |
pub trait HasRefPosition { | |
fn position(&self) -> RefPoint; | |
fn move_by(&mut self, x: f32, y: f32) { | |
let point = self.position(); | |
let mut p = point.borrow_mut(); | |
p.x += x; | |
p.y += y; | |
} | |
} | |
fn main() { | |
let mut child = Object::new(); | |
{ | |
let mut parent = Object::new(); | |
child.set_origin(Rc::clone(&parent.position)); | |
parent.move_by(5.0, 5.0); | |
dbg!("{:?}", child.get_origin()); // Here, child's origin is properly pointing to parent's mutated position | |
} | |
dbg!("{:?}", child.get_origin()); // After parent goes out of scope, child's reference to parent becomes `None` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment