2017-05-18 4 views
-3

Ich benutze externe C-Bibliothek, um TTF-Schriftart aus Datei zu laden. Ich implementiert einfache Klasse, die Schriften in einer Karte Caches:Std :: Zukunft gibt mir Fehler 3, was mache ich falsch?

std::map<std::string, std::future<stbtt_fontinfo> > fontCache; 

Die stbtt_fontinfo enthält die internen Informationen über geladene Schriftart. Ich habe drei andere Methoden. Verfahren, die tatsächlich die Schriftart geladen und innerhalb std::future ‚s Thread gestartet:

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; 
} 

und ein Verfahren neuen Eintrag im Cache setzen:

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))); 
    } 
} 

Die std::async(&ShapeText::FontCache::loadFont, this, fontPath) sollte die Ladefunktion in neuem Thread starten und gib eine std::future dafür zurück. Ich habe überprüft, dass der Code tatsächlich gestartet wird.

Last-Methode dient die Schriftarten für das Laden, die Blöcke, wenn die Schrift noch nicht geladen ist:

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; 
    } 
} 

Aber ich habe einen Fehler in der try catch Block:

ERROR: cannot read value from future font: îţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţîţłjpYŹ 

können Sie sehen, dass Der what() Rückgabewert ist fehlerhaft. Der error_code Wert ist 3. Was mache ich hier falsch?

+0

wäre es schön, wenn Sie Ihre Frage ändern könnten, um eine viel kleinere Reproduzierer – blue

+0

welchen Compiler verwenden Sie verwenden? – didiz

+1

Ich benutze GCC. Ich habe den Fehler bereits gefunden, er ist im obigen Code deutlich sichtbar und wurde verursacht, weil ich Futures falsch einsetze. –

Antwort

0

Das Problem war einfach, dass die Zukunft nicht in die Karte kopiert werden kann. Stattdessen muss std::shared_future verwendet werden. Daher muss die Array/Karte von Futures wie folgen aussehen:

std::map<std::string, std::shared_future<YourType> > futureCache; 

Und auf das Array anhängt wie folgt aussehen muss:

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)); 
} 

Der Schlüssel hier ist std::future ‚s Methode share(), die die ursprünglichen entkräften Zukunft und bietet stattdessen eine gemeinsame Zukunft, die ohne Einschränkungen kopiert werden kann.