I was wondering if I am doing something wrong (most likely) or if there is an issue with LibGDX SkinLoader regarding additional resource dependencies.
According to the documentation of SkinLoader.SkinParameter you can pass an additional ObjectMap to define resources that the skin depends on.
I wanted to use that for bitmap fonts because I am creating them at runtime out of a .ttf file to be able to create the correct font sizes for the correct density/size of the target device's display.
Here is an example program that causes the issue:
public class Test extends Game {
private AssetManager assetManager;
private Skin skin;
private Batch batch;
@Override
public void create() {
this.assetManager = new AssetManager();
final FileHandleResolver resolver = new InternalFileHandleResolver();
assetManager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));
final ObjectMap<String, Object> resources = new ObjectMap<String, Object>();
final FreetypeFontLoader.FreeTypeFontLoaderParameter fontParam = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
fontParam.fontFileName = "ui/font.ttf";
fontParam.fontParameters.size = (int) (16 * Gdx.graphics.getDensity());
assetManager.load("font16.ttf", BitmapFont.class, fontParam);
assetManager.finishLoading();
resources.put("font_16", assetManager.get("font16.ttf", BitmapFont.class));
assetManager.load("ui/ui.json", Skin.class, new SkinLoader.SkinParameter(resources));
assetManager.finishLoading();
skin = assetManager.get("ui/ui.json", Skin.class);
batch = new SpriteBatch();
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
skin.get("font_16", BitmapFont.class).draw(batch, "Test123", 10, 10);
batch.end();
}
@Override
public void dispose() {
super.dispose();
// enabling the next line will get rid of the Pixmap already disposed exception
// skin.remove("font_16", BitmapFont.class);
assetManager.dispose();
batch.dispose();
}
}
Now when disposing the assetManager at the end of the program then I got an exception "Pixmap already disposed" because the bitmap fonts got disposed multiple times (once when the Skin gets disposed and once when the Bitmap font itself gets disposed).
To solve that for now I called skin.remove(fontName, BitMapFont.class) before assetManager.dispose() to release the bitmap fonts only once BUT imo this is not a nice way and I would expect that the dependency handling of the assetManager should take care of that.
I checked the code of the SkinLoader class and to me it seems like those passed resources are not added as a dependency of the Skin and that is why this error occurs.
My question now is: Did I do something wrong or does anyone have a working code for that to show how the resourcesmap should be used in the correct way?
Found a topic which is related to this but seems like it never got a real answer