Skip to content

Instantly share code, notes, and snippets.

@wdevore
Created February 10, 2019 19:30
Show Gist options
  • Save wdevore/1069bd87d9ce5ef4c496c0ef436ec86c to your computer and use it in GitHub Desktop.
Save wdevore/1069bd87d9ce5ef4c496c0ef436ec86c to your computer and use it in GitHub Desktop.
An example of Interior mutability for Ranger engine
use std::cell::{Cell, RefCell};
use std::rc::Rc;
type RefNode = Rc<NodeTrait>;
trait NodeTrait {
fn id(&self) -> usize {
0
}
fn set_id(&self, id: usize);
fn name(&self) -> &RefCell<String>;
fn set_name(&self, name: String);
fn paused(&self) -> bool;
fn pause(&self, pause: bool);
fn enter(&self, sch: &Scheduler);
fn exit(&self, sch: &Scheduler);
fn set_position(&self, x: f32, y: f32);
fn position(&self) -> &RefCell<Transform>;
}
struct Transform {
x: f32,
y: f32,
}
impl Transform {
fn new() -> Self {
Self {
x: 0.0,
y: 0.0,
}
}
fn translate(&mut self, x: f32, y: f32) {
self.x = x;
self.y = y;
}
}
// ======================================================
struct BootScene {
id: RefCell<usize>,
paused: Cell<bool>,
trans: RefCell<Transform>,
name: RefCell<String>,
}
impl BootScene {
fn new() -> RefNode {
Rc::new(Self {
id: RefCell::new(0),
paused: Cell::new(true),
trans: RefCell::new(Transform::new()),
name: RefCell::new(String::from("Hello")),
})
}
}
impl NodeTrait for BootScene {
fn id(&self) -> usize {
*self.id.borrow()
}
fn set_id(&self, id: usize) {
*self.id.borrow_mut() = id;
}
fn name(&self) -> &RefCell<String> {
&self.name
}
fn set_name(&self, name: String) {
let mut n = self.name.borrow_mut(); {
n.replace_range(.., &name);
}
// self.name.borrow_mut().replace_range(.., &name);
}
fn paused(&self) -> bool {
self.paused.get()
}
fn pause(&self, pause: bool) {
self.paused.set(pause);
}
fn enter(&self, sch: &Scheduler) {
println!("enter---------------------");
sch.print();
sch.schedule_timing_target(self.id());
sch.print();
println!("---------------------");
}
fn exit(&self, sch: &Scheduler) {
println!("exit---------------------");
sch.print();
sch.unschedule_timing_target(self.id());
sch.print();
println!("---------------------");
}
fn set_position(&self, x: f32, y: f32) {
self.trans.borrow_mut().translate(x, y);
}
fn position(&self) -> &RefCell<Transform> {
&self.trans
}
}
struct Scheduler {
scenes: Vec<RefNode>,
}
impl Scheduler {
fn new() -> Self {
Self { scenes: Vec::new() }
}
fn register_timing_target(&mut self, target: RefNode) {
self.scenes.push(target);
}
fn schedule_timing_target(&self, target_id: usize) {
for t in &self.scenes {
if t.id() == target_id {
t.pause(false);
return;
}
}
}
fn unschedule_timing_target(&self, target_id: usize) {
for target in &self.scenes {
if target.id() == target_id {
target.pause(true);
return;
}
}
}
fn print(&self) {
// let mut c = 0;
for target in &self.scenes {
// println!("c: {}", c);
println!("id: {}, paused: {}, pos: ({}, {})",
target.id(), target.paused(),
target.position().borrow().x, target.position().borrow().y,
);
// c += 1;
}
// println!("###########################");
}
}
fn main() {
let mut sch = Scheduler::new();
let s1 = BootScene::new();
println!("name: {}", s1.name().borrow());
s1.set_name(String::from("Bob"));
println!("name: {}", s1.name().borrow());
// s1.set_name(String::from("Jim"));
s1.set_id(1);
s1.set_position(2.2, 3.3);
sch.register_timing_target(s1.clone());
let s2 = BootScene::new();
s2.set_id(3);
sch.register_timing_target(s2.clone());
s2.enter(&sch);
s2.exit(&sch);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment