5

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?

Stargateur
  • 24,473
  • 8
  • 65
  • 91
phoenix
  • 7,988
  • 6
  • 39
  • 45

1 Answers1

6

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!
        }
    }
}
Simon Whitehead
  • 63,300
  • 9
  • 114
  • 138
  • Note that the implementation presented here [has changed a lot in master](https://github.com/PistonDevelopers/opengl_graphics/blob/3ba372353405b3b28e90b5aec83673fa0e7ca169/src/glyph_cache.rs#L89-L166). Also, it's pretty strange as normally you would have something like `self.data.entry(size).or_insert_with(HashMap::new).entry(ch).or_insert_with(something_that_loads_the_char)`. – Shepmaster Dec 31 '16 at 04:37