Skip to content

Instantly share code, notes, and snippets.

@wdevore
Created February 10, 2019 19:32
Show Gist options
  • Save wdevore/4b5ff3cfacc4664fd077a563de90215f to your computer and use it in GitHub Desktop.
Save wdevore/4b5ff3cfacc4664fd077a563de90215f to your computer and use it in GitHub Desktop.
Another example of returning an option<> with using take()
use std::cell::RefCell;
use std::rc::Rc;
trait NodeTrait {
fn get_x(&self) -> f32;
fn add(&mut self, v: f32);
fn step(&mut self);
fn process(&mut self);
fn replacement(&self) -> &Option<RNode> {
&None
}
fn set_replacement_none(&mut self);
fn print(&self) {
println!("node: {}", self.get_x());
}
}
type RNode = Rc<RefCell<NodeTrait>>;
// --------------------------------------------
// Boot
// --------------------------------------------
struct BootScene {
replacement: Option<RNode>,
x: f32,
}
impl NodeTrait for BootScene {
fn get_x(&self) -> f32 {
self.x
}
fn add(&mut self, v: f32) {
self.x += v;
}
fn step(&mut self) {
println!("step: {}", self.x);
self.process();
}
fn process(&mut self) {
println!("process: {}", self.x);
self.x += 1.0;
}
fn replacement(&self) -> &Option<RNode> {
&self.replacement
}
fn set_replacement_none(&mut self) {
self.replacement = None;
}
}
impl BootScene {
fn new(v: f32, replacement: RNode) -> RNode {
Rc::new(RefCell::new(Self {
replacement: Some(replacement),
x: v,
}))
}
}
// --------------------------------------------
// Splash
// --------------------------------------------
struct SplashScene {
x: f32,
}
impl NodeTrait for SplashScene {
fn get_x(&self) -> f32 {
self.x
}
fn add(&mut self, v: f32) {
self.x += v;
}
fn step(&mut self) {
println!("step: {}", self.x);
self.process();
}
fn process(&mut self) {
println!("process: {}", self.x);
self.x += 1.0;
}
fn set_replacement_none(&mut self) {
}
}
impl SplashScene {
fn new(v: f32) -> RNode {
Rc::new(RefCell::new(Self { x: v }))
}
}
// --------------------------------------------
// Scene manager
// --------------------------------------------
struct SceneManager {
scenes: Vec<RNode>,
top: Option<RNode>,
}
impl SceneManager {
fn new() -> Self {
Self {
scenes: Vec::new(),
top: None,
}
}
fn add(&mut self, t: RNode) {
self.scenes.push(t);
}
fn print(&self) {
for t in &self.scenes {
t.borrow().print();
}
if let Some(top) = &self.top {
print!("top: ");
top.borrow().print();
} else {
println!("no top");
}
}
fn change(&mut self, _by: f32) {
for t in &mut self.scenes {
let mut n = t.borrow_mut();
// n.add(by);
n.step();
if let Some(replacement) = n.replacement() {
println!("replaced");
self.top = Some(replacement.clone());
n.set_replacement_none();
}
}
}
// fn replace(&self, _replacement: RNode) {}
}
type BuildCallback = fn(&mut World) -> bool;
// --------------------------------------------
// World
// --------------------------------------------
struct World {
sm: SceneManager,
}
impl World {
fn new() -> Self {
Self {
sm: SceneManager::new(),
}
}
fn get_sm_mut(&mut self) -> &mut SceneManager {
&mut self.sm
}
fn add_scene(&mut self, scene: RNode) {
self.sm.add(scene);
}
fn initialize(&mut self, build: BuildCallback) {
build(self);
}
fn print(&self) {
self.sm.print();
}
}
fn main() {
let mut w = World::new();
w.initialize(builder);
}
fn builder(world: &mut World) -> bool {
println!("builder called");
let splash = SplashScene::new(2.0);
let boot = BootScene::new(1.0, splash);
world.add_scene(boot);
// world.add_scene(splash);
world.print();
let sm = world.get_sm_mut();
sm.change(3.0);
println!("----------------");
world.print();
true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment