Skip to content

Instantly share code, notes, and snippets.

@haudan
Last active June 7, 2017 09:03
Show Gist options
  • Save haudan/af45593a7a1374ceb8c5e1e233c29fa6 to your computer and use it in GitHub Desktop.
Save haudan/af45593a7a1374ceb8c5e1e233c29fa6 to your computer and use it in GitHub Desktop.
Rust shared widgets
use std::collections::HashSet;
use std::cell::RefCell;
use std::rc::Rc;
struct WidgetRef(Rc<RefCell<Box<Widget>>>);
impl WidgetRef {
fn new(inner: Rc<RefCell<Box<Widget>>>) -> Self {
WidgetRef(inner)
}
fn pointer_usize(&self) -> usize {
&(*(&self.0).borrow()) as *const _ as usize
}
}
impl std::cmp::PartialEq for WidgetRef {
fn eq(&self, other: &Self) -> bool {
self.pointer_usize() == other.pointer_usize()
}
}
impl std::cmp::Eq for WidgetRef {}
impl std::hash::Hash for WidgetRef {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.pointer_usize().hash(state);
}
}
impl std::ops::Deref for WidgetRef {
type Target = Rc<RefCell<Box<Widget>>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
trait Widget {
fn update(&mut self);
fn draw(&self);
}
struct Button;
struct TextBox;
impl Widget for Button {
fn update(&mut self) {
println!("Updating button");
}
fn draw(&self) {
println!("Drawing button");
}
}
impl Widget for TextBox {
fn update(&mut self) {
println!("Updating textbox");
}
fn draw(&self) {
println!("Drawing textbox");
}
}
fn main() {
let button = Rc::new(RefCell::new(Box::new(Button) as Box<Widget>));
let text_box = Rc::new(RefCell::new(Box::new(TextBox) as Box<Widget>));
let mut widgets = HashSet::new();
widgets.insert(WidgetRef::new(button.clone()));
widgets.insert(WidgetRef::new(text_box.clone()));
for mut w in widgets.iter().map(|w| w.borrow_mut()) {
w.update();
w.draw();
}
widgets.remove(&WidgetRef::new(button.clone()));
println!("------------");
for mut w in widgets.iter().map(|w| w.borrow_mut()) {
w.update();
w.draw();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment