Skip to content

Instantly share code, notes, and snippets.

@rezich
Created January 5, 2017 20:46
Show Gist options
  • Save rezich/27595fd405c62a88348a60790b6b1b33 to your computer and use it in GitHub Desktop.
Save rezich/27595fd405c62a88348a60790b6b1b33 to your computer and use it in GitHub Desktop.
learning Rust by making a game
/*
I'm learning Rust by making a game.
This game would be very simple to make, unsafely, in C/C++,
and I'm hoping that by making it in Rust, I'll learn the core concepts
of ownership and such.
But right now, I'm stuck.
Here's what I'm *trying* to do, in C++:
struct Bar {
std::string title;
std::vector<Bar> bars;
Bar *parent;
Bar *add_bar();
}
struct Foo {
Bar root_bar;
Bar *current_bar;
void set_current_bar(Bar *bar);
void add_bar();
void process();
}
And here's what I have so far in Rust:
*/
// container object for the entire game
struct Foo {
root_bar: Bar,
current_bar: Option<&Bar>
}
impl Foo {
fn new() -> Self {
Foo {
root_bar: Bar {
title: "root".to_string(),
bars: Vec::new(),
parent: None
}
}
}
fn set_current_bar(&self, bar: &Bar) {
// change which Bar `current_bar` "points" at
// (it will be used internally in this Foo)
}
fn add_bar(&self) {
// add a Bar to `current_bar`'s `bars`,
// then call set_current_bar() w/ the new Bar
}
fn process(&self) {
// "game loop" goes in here
}
}
// thing inside game, only exists within the confines of a Foo
struct Bar {
title: String,
bars: Vec<Bar>,
parent: Option<&Bar>
}
impl Bar {
fn add_bar(&self) -> &Bar {
// create a new Bar
// set new Bar's `parent` to this,
// push new Bar to this Bar's `bars`
// return reference to the new Bar, in `bars`
}
}
fn main() {
// create the Foo container and run the game
Foo::new().process();
}
@ElectricCoffee
Copy link

Try this on for size.

What I did:

  1. I moved struct Bar up under Foo. This isn't required by any means, I just like to keep my data structures together.
  2. Foo was missing a lifetime specifier, why? Because there was no guarantee that the reference to Bar would live for as long as Foo itself. What if the reference got deallocated before Foo did? Then you'd have a dangling pointer, no bueno.
  3. I changed parent: Option<&Bar> to parent: Option<Box<Bar>>, a Box is a variable on the heap, which is required if you need nested data structures.
  4. I added current_bar: None to Foo::new(), because Rust won't let you initialise structs without filling in all the fields.
  5. I added unimplemented!() to Bar.add_bar() to keep the compiler from whining about the missing return value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment