Assetmanager and Skin dispose of Font(/Skin)

冷暖自知 提交于 2019-12-24 05:54:54

问题


I am using the libgdx AssetManager to load a skin with a custom font.

When I call assetmanager.dispose() it throws an Exception:

com.badlogic.gdx.utils.GdxRuntimeException: Pixmap already disposed!    
at com.badlogic.gdx.graphics.Pixmap.dispose(Pixmap.java:315)
at com.badlogic.gdx.graphics.g2d.PixmapPacker$Page$1.dispose(PixmapPacker.java:384)
at com.badlogic.gdx.graphics.g2d.BitmapFont.dispose(BitmapFont.java:315)
at com.badlogic.gdx.scenes.scene2d.ui.Skin.dispose(Skin.java:416)
at com.badlogic.gdx.assets.AssetManager.unload(AssetManager.java:211)
at com.badlogic.gdx.assets.AssetManager.clear(AssetManager.java:653)
at com.badlogic.gdx.assets.AssetManager.dispose(AssetManager.java:621)

while trying to dispose the custom font i added. I think that this is because the AssetManager disposes the BitmapFont first and the skin afterwards. But the skin is also trying to dispose the BitmapFont. Switching the order of loading the skin and the BitmapFont is not possible, because the skin needs the BitmapFont in its loading process.

This is where I load the skin and font:

    FileHandleResolver resolver = new InternalFileHandleResolver();
    app.assetManager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
    app.assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));
    FreetypeFontLoader.FreeTypeFontLoaderParameter params = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params.fontFileName = "font/stay_writer.ttf";
    params.fontParameters.size = 25;
    app.assetManager.load("stay_writer_25.ttf", BitmapFont.class, params);
    app.assetManager.finishLoading();
    // Queue Skin
    app.assetManager.load("skins/uiskin.atlas", TextureAtlas.class);
    ObjectMap<String, Object> resources = new ObjectMap<String, Object>();
    resources.put("default-font", app.assetManager.get("stay_writer_25.ttf", BitmapFont.class));
    app.assetManager.load("skins/uiskin.json", Skin.class, new SkinLoader.SkinParameter("skins/uiskin.atlas", resources));

I am continiously calling assetmanager.update() and made sure that the skin gets loaded.

I dispose the AssetManager with:

assetManager.dispose();

This gives me the Pixmap already disposed! error.
I debugged the calls of BitmapFont.dispose(). The stacktrace of the first call shows me that the call comes from assetManager.unload(), and the second call from Skin.dispose() which is called from the assetManager.unload() method.

Now i want to know if there is a way to dispose of the skin and the BitmapFont, without them conflicting each other.


回答1:


It looks like SkinLoader does not tell AssetManager that the passed in resources are dependencies, so if one of those resources is also a managed asset, it can lead to the problem you're getting.

So if you don't need the font to be managed by AssetManager, you could simply load it independently so AssetManager won't dispose of it.

Otherwise, I think you will need to remove the resource from the Skin before you unload or dispose of the Skin:

skin.remove("stay_writer_25.ttf", BitmapFont.class);


来源:https://stackoverflow.com/questions/39408448/assetmanager-and-skin-dispose-of-font-skin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!