Hexworks / zircon

Zircon is an extensible and user-friendly, multiplatform tile engine.
https://hexworks.org/projects/zircon/
Apache License 2.0
755 stars 138 forks source link

AppConfig extensible custom properties API #380

Closed nanodeath closed 3 years ago

nanodeath commented 3 years ago

Is your feature request related to a problem? Please describe.

Most configuration in Zircon is done through the AppConfig object (and its buddy, AppConfigBuilder). However, all the configuration here is generic -- applicable to all (or most) Zircon programs.

However, there's some configuration that's going to be specific to a particular extension, platform, or implementation, and it'd be convenient for that to still be managed via the central AppConfig object. So, we need some kind of API that's exposed to plugin authors and, inevitably, minimally exposed to end-users.

Describe the solution you'd like

I'm proposing the following new APIs:

AppConfigBuilder

fun <T> withProperty(key: AppConfigKey<T>, value: T): AppConfigBuilder

AppConfig

fun <T> getProperty(key: AppConfigKey<T>): T

AppConfigKey<T> would be a simple interface that looks like this:

interface AppConfigKey<T>

In both cases, properties are represented internally in a simple map.

Usage

These APIs would primarily be used by plugin authors and non-core code. For example, to support custom tileset loaders (which are specific to a particular rendering module), the zircon.jvm.swing module could contain these extension functions:

internal object SwingTilesetLoaders : AppConfigKey<List<TilesetLoader<Graphics2D>>>

fun AppConfigBuilder.withCustomTilesetLoaders(vararg tilesetLoaders: TilesetLoader<Graphics2D>) =
    withProperty(SwingTilesetLoaders, tilesetLoaders.toList())

internal fun AppConfig.getCustomTilesetLoaders(): List<TilesetLoader<Graphics2D>> = 
    getProperty(SwingTilesetLoaders).orEmpty()

As you can see, the end user is easily able to set the custom tileset loaders and (if desired) the ability to retrieve them is limited to the library author.

Describe alternatives you've considered

End users would have little use for this API, so we should dissuade them from using it.

Additional context This is a blocker for custom tileset loaders.

adam-arold commented 3 years ago

I dig this AppConfigKey approach! It keeps type safety while retaining the flexibility of a Map. I've added this to the board!