void FontManager::unload(InputSourceRef inputSource)
 {
     for (auto it = fonts.begin(); it != fonts.end();)
     {
         if (it->first.first == inputSource->getURI())
         {
             it = fonts.erase(it);
         }
         else
         {
             ++it;
         }
     }
     
     discardUnusedTextures();
 }
EffectRef SoundEngine::preloadEffect(InputSourceRef inputSource)
{
    string key = inputSource->getURI();
    auto it = effects.find(key);
    
    if (it == effects.end())
    {
        EffectRef effect = loadEffect(inputSource);
        effects[key] = effect;
        return effect;
    }
    else
    {
        return it->second;
    }
}
 std::shared_ptr<Font> FontManager::getCachedFont(InputSourceRef inputSource, const Font::Properties &properties)
 {
     auto uri = inputSource->getURI();
     
     auto key = make_pair(uri, properties);
     auto it1 = fonts.find(key);
     
     if (it1 != fonts.end())
     {
         return it1->second;
     }
     else
     {
         FontData *data;
         FontTexture *texture;
         auto it2 = fontDataAndTextures.find(uri);
         
         if (it2 == fontDataAndTextures.end())
         {
             FontAtlas *atlas;
             tie(data, atlas) = fetchFontDataAndAtlas(inputSource); // CAN THROW
             
             texture = new FontTexture(atlas, inputSource);
             delete atlas;
             
             fontDataAndTextures[uri] = make_pair(unique_ptr<FontData>(data), unique_ptr<FontTexture>(texture));
         }
         else
         {
             data = it2->second.first.get();
             texture = it2->second.second.get();
         }
         
         auto font = shared_ptr<Font>(new Font(*this, data, texture, properties)); // make_shared WON'T WORK WITH A PROTECTED CONSTRUCTOR
         fonts[key] = font;
         
         return font;
     }
 }