Search code examples
rustrust-piston

Why does Piston text() require a mutable reference to the glyph cache?


I'm curious why text() takes a mutable borrow of the glyph cache:

cache: &mut C

My understanding is that the glyphe cache represented the static characters (glyphs) loaded from the font file. Why would those need to be able to be mutated by the underlying graphics system?


Solution

  • Because if you follow the code from Text all the way down, it appears that it loads each character on demand on a per-font-size basis. If you ask it for a character of a size it doesn't have cached, it will load it in - which requires a mutable reference in order to modify its internal state. Really, its the very first part where it uses the entry API - which requires a mutable reference: fn entry(&mut self, key: K) -> Entry<K, V>

    The code in question though:

    impl<'a> graphics::character::CharacterCache for GlyphCache<'a> {
        type Texture = Texture;
    
        fn character(&mut self, size: FontSize, ch: char) -> &Character {
            match {
                match self.data.entry(size) { // <----- BAM!
                    Vacant(entry) => entry.insert(HashMap::new()), 
                    Occupied(entry) => entry.into_mut(),
                }
            }.contains_key(&ch) {
                true => &self.data[&size][&ch],
                false => { self.load_character(size, ch); &self.data[&size][&ch] }
                // ^^^^ BAM!
            }
        }
    }