Implementating texture cache


#1

Hello, I’m learning Rust and I’m stuck with a problem. I understood why the compiler is complaining about it but I don’t know how to resolve it.

extern crate sfml;

use sfml::graphics::Sprite;
use sfml::graphics::Texture;
use std::collections::HashMap;

struct TextureHolder {
    textures: HashMap<String, Texture>
}

impl TextureHolder {
    fn new() -> TextureHolder {
        TextureHolder {
            textures: HashMap::new()
        }
    }

    fn get_texture(&mut self, file_name: String) -> &Texture {
        self.textures.entry(file_name.clone()).or_insert(
            Texture::from_file(file_name.as_str()).unwrap()
        )
    }
}

struct Engine<'a> {
    texture_holder: TextureHolder,
    background_sprite: Sprite<'a>,
}

impl<'a> Engine<'a> {
    fn new() -> Engine<'a> {
        let mut texture_holder = TextureHolder::new();
        let background_sprite = (& mut texture_holder).get_texture("graphics/background.png".to_string());
        Engine {
            texture_holder,
            background_sprite: Sprite::with_texture(background_sprite),
        }
    }
}

fn main() {
    let engine = Engine::new();
}

How I can create the TextureHolder and use it in the same method?

Any help is appreciated!


#2

You’ll have to take TextureHolder as a reference to new(), otherwise you have the problem of a self-referential struct.

Alternatively, you have to redesign TextureHolder to use Rc for each texture and return owned objects instead of references.


#3

Thanks for the answer, I tried with both but unfortunately I don’t have so much experience so the problem remains, TextureHolder is not living enough inside the Engine::new. How I should rewrite the struct or the new method in the TextureHolder?


#4

Generally, it’s not possible to return a reference to anything created in the function. Functions can only return references to objects created outside of them.

If you make textures Rc<Texture>, then you won’t need to use references, and the problem with references will disappear.