Hello,
since this is my first post here I would first say hello to everybody : ). I am completely new to Rust and coming from a python / C background. Rust seems like a cool language to learn so I decided to give it a go. During my last vacation I managed to read the majority of the Rust book and now I wanted to experiment with a toy project. So I decided to create the (n+1)th clone of Snake. I started of with the SDL2 example code and managed to get a very basic implementation to work.
This is when I decided that I want to practice a bit more and tried to restructure the whole program and now I am stuck. I don't want to bore everyone with the lengthy ugly code so I just want to show the part that produces the problems (if anyone is interested just ping me and I can later push it to github ; )).
The first version of the code worked somehow like this
main {
//call sdl library functions to create all the required objects
loop {
handle events( sdl variables)
draw stuff ( sdl variables)
}
}
But now I would like to clean up my main function and create all those SDL specific structs in a function. Something like this:
main {
config = Config::new();
sdl_components = initialize(config);
loop {
handle events(sdl_components);
draw stuff (sdl_components);
}
}
Here is the "real" relevant code section:
pub struct Sdl2Components<'a> {
canvas: sdl2::render::WindowCanvas,
event_pump: sdl2::EventPump,
_ttf_context: Sdl2TtfContext,
font: Option<Font<'a, 'static>>,
}
impl <'a> Sdl2Components<'a> {
fn new_internal(window_width: u32, window_height: u32) -> Sdl2Components<'a> {
let sdl_context = sdl2::init().unwrap();
let event_pump = sdl_context.event_pump().unwrap();
let window = sdl_context.video().unwrap().window("snake demo", window_width, window_height)
.position_centered().build().unwrap();
let canvas = window.into_canvas().build().unwrap();
Sdl2Components {
canvas: canvas,
event_pump: event_pump,
_ttf_context: sdl2::ttf::init().map_err(|e| e.to_string()).unwrap(),
font: None
}
}
pub fn new(window_width: u32, window_height: u32) -> Sdl2Components<'a> {
let mut comp = Sdl2Components::new_internal(window_width, window_height);
comp.font = Some(comp._ttf_context.load_font("/usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf", 128).unwrap());
comp
}
}
Now I get this compiler error:
error[E0515]: cannot return value referencing local data `comp._ttf_context`
--> src/main.rs:142:9
|
141 | comp.font = Some(comp._ttf_context.load_font("/usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf", 128).unwrap());
| ----------------- `comp._ttf_context` is borrowed here
142 | comp
| ^^^^ returns a value referencing data owned by the current function
error[E0505]: cannot move out of `comp` because it is borrowed
--> src/main.rs:142:9
|
122 | impl <'a> Sdl2Components<'a> {
| -- lifetime `'a` defined here
...
141 | comp.font = Some(comp._ttf_context.load_font("/usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf", 128).unwrap());
| ----------------- borrow of `comp._ttf_context` occurs here
142 | comp
| ^^^^
| |
| move out of `comp` occurs here
| returning this value requires that `comp._ttf_context` is borrowed for `'a`
The problem I have is that I want to return the created font
from the init function but it needs to have a reference to the ttf_context
, which I would also return. Actually, I don't need to use the ttf_context
directly I just want to make it live until I don't need font
anymore...
Can somebody give me advice how to do this in rust?
Thanks : )
I uploaded the current state to github: GitHub - greeenway/snake_in_rust: A toy project to learn Rust
edit: some formatting fixes and added a github link