Hexworks / zircon

Zircon is an extensible and user-friendly, multiplatform tile engine.

Home Page:https://hexworks.org/projects/zircon/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

AppConfig extensible custom properties API

nanodeath opened this issue · comments

commented

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

  • Make AppConfig open and provide subclasses with the necessary methods. However, this means the end user can only pick a single specific subclass, making supporting multiple extensions impossible.
  • We could create additional AppConfig-like objects that get passed into the main Zircon constructors, but this seems needlessly complicated.

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.

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