czyzby/gdx-lml

[Autumn MVC] How to save lml dtd file?

Humberd opened this issue · 1 comments

How to save a dtd file inside @Initiate configuraiton method?

When I did a tutorial for LML it was pretty easy:

saveDtdSchema(Gdx.files.local("lml.dtd"))

But when I do this:

@Initiate
fun initiateConfiguration(appListener: LmlApplicationListener) {
    appListener.saveDtdSchema(Gdx.files.local("lml.dtd"))
}

I get a NullPointerException here:

public void saveDtdSchema(final FileHandle file) {
    try {
        final Writer appendable = file.writer(false, "UTF-8");
        final boolean strict = lmlParser.isStrict(); // <---- here, lmlParser is null
        lmlParser.setStrict(false); 
        createDtdSchema(lmlParser, appendable);
        appendable.close();
        lmlParser.setStrict(strict);
    } catch (final Exception exception) {
        throw new GdxRuntimeException("Unable to save DTD schema.", exception);
    }
}

Workaround
As a workaround I copied the whole method and supplied it with a proper lmlParser

@Initiate
fun initiatefConfiguration(interfaceService: InterfaceService) {
    saveDtdSchema(interfaceService.parser, Gdx.files.local("lml.dtd"))
}

fun saveDtdSchema(lmlParser: LmlParser, fileHandle: FileHandle) {
    try {
        val appendable = fileHandle.writer(false, "UTF-8")
        val strict = lmlParser.isStrict
        lmlParser.isStrict = false // Temporary setting to non-strict to generate as much tags as possible.
        Dtd.saveSchema(lmlParser, appendable)
        appendable.close()
        lmlParser.isStrict = strict
    } catch (exception: Exception) {
        throw GdxRuntimeException("Unable to save DTD schema.", exception)
    }

}

Is there a better way to achieve this result?

@Initiate has a priority setting that lets you control the order in which these methods are invoked. Tweaking this value might allow you to invoke your method after LmlParser is injected.

That said, DTD generation is basically dev-only code. "If it works, it works." You only need to do that when you modify the parser, e.g. you add new tags or macros - I don't think I'd even include it in the regular application on @Initiate, as it slows down its startup. Consider using a separate main that generates DTDs or convert your method to a LML action and add it as a button that you can click after the game is fully initiated.