我使用外部C库从文件加载TTF字体。我实现了在地图中缓存字体的简单类:
map
std::map<std::string, std::future<stbtt_fontinfo> > fontCache;
包含有关已加载字体的内部信息。我还有其他三种方法。实际加载字体并在stbtt_fontinfo
的线程中启动的方法:
std::future
一种将新条目放入缓存的方法:
stbtt_fontinfo ShapeText::FontCache::loadFont(const std::string& fontPath)
{
// used to save parsed font
stbtt_fontinfo font;
std::ifstream input( fontPath, std::ios::binary );
if(input.is_open()) {
// do something to load the font
}
return font;
}
void ShapeText::FontCache::getFontLater(const std::string& fontPath)
{
std::map<std::string, std::future<stbtt_fontinfo>>::iterator pos = fontCache.find(fontPath);
if(pos==fontCache.end()) {
fontCache.insert(std::make_pair(fontPath, std::async(&ShapeText::FontCache::loadFont, this, fontPath)));
}
}
应该在新线程中启动加载函数并为其返回std::async(&ShapeText::FontCache::loadFont, this, fontPath)
。我确实验证了代码是否确实已启动。
最后一种方法用于加载字体,如果尚未加载字体则会阻止字体:
std::future
但我在stbtt_fontinfo ShapeText::FontCache::getFont(const std::string& fontPath)
{
// If the font is not in cache yet, start loading it
getFontLater(fontPath);
try {
// wait until the font is loaded
return fontCache[fontPath].get();
}
catch (const std::future_error& e) {
const char* msg = e.what();
const std::error_code code = e.code();
std::cout<<"ERROR: cannot read value from future font: "<<msg<<"\n";
// return invalid font
stbtt_fontinfo font;
font.cff.data = nullptr;
font.numGlyphs = 0;
return font;
}
}
块中收到错误:
try catch
您可以看到ERROR: cannot read value from future font: îţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţłjpYŹ
返回值已损坏。 what()
值为3.我在这里做错了什么?
答案 0 :(得分:0)
问题在于,未来不能像这样复制到地图中。相反,必须使用std::shared_future
。因此,期货的数组/地图必须如下所示:
std::map<std::string, std::shared_future<YourType> > futureCache;
附加到数组必须如下所示:
std::map<std::string, std::shared_future<YourType> >::iterator pos = cache.find(fontPath);
if(pos==cache.end()) {
std::shared_future<YourType> shared = std::async(&YourClass:callback, this, argument1).share();
cache.insert(std::make_pair(stringKey, shared));
}
此处的关键是std::future
的方法share()
,它使原始未来无效,而是提供共享的未来,可以无限制地复制。