diff --git a/include/mgba/core/config.h b/include/mgba/core/config.h index aca655976..6dbc73dc4 100644 --- a/include/mgba/core/config.h +++ b/include/mgba/core/config.h @@ -19,6 +19,12 @@ struct mCoreConfig { char* port; }; +enum mCoreConfigLevel { + mCONFIG_LEVEL_DEFAULT = 0, + mCONFIG_LEVEL_CUSTOM, + mCONFIG_LEVEL_OVERRIDE, +}; + struct mCoreOptions { char* bios; bool skipBios; @@ -90,6 +96,8 @@ void mCoreConfigCopyValue(struct mCoreConfig* config, const struct mCoreConfig* void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts); void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptions* opts); +void mCoreConfigEnumerate(const struct mCoreConfig* config, const char* prefix, void (*handler)(const char* key, const char* value, enum mCoreConfigLevel type, void* user), void* user); + struct Configuration* mCoreConfigGetInput(struct mCoreConfig*); struct Configuration* mCoreConfigGetOverrides(struct mCoreConfig*); const struct Configuration* mCoreConfigGetOverridesConst(const struct mCoreConfig*); diff --git a/src/core/config.c b/src/core/config.c index ceca2bdfd..b4d654c54 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -29,6 +29,13 @@ #define SECTION_NAME_MAX 128 +struct mCoreConfigEnumerateData { + void (*handler)(const char* key, const char* value, enum mCoreConfigLevel type, void* user); + const char* prefix; + void* user; + enum mCoreConfigLevel level; +}; + static const char* _lookupValue(const struct mCoreConfig* config, const char* key) { const char* value; if (config->port) { @@ -393,6 +400,22 @@ void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptio ConfigurationSetIntValue(&config->defaultsTable, 0, "suspendScreensaver", opts->suspendScreensaver); } +static void _configEnum(const char* key, const char* value, void* user) { + struct mCoreConfigEnumerateData* data = user; + if (!data->prefix || startswith(key, data->prefix)) { + data->handler(key, value, data->level, data->user); + } +} + +void mCoreConfigEnumerate(const struct mCoreConfig* config, const char* prefix, void (*handler)(const char* key, const char* value, enum mCoreConfigLevel type, void* user), void* user) { + struct mCoreConfigEnumerateData handlerData = { handler, prefix, user, mCONFIG_LEVEL_DEFAULT }; + ConfigurationEnumerate(&config->defaultsTable, config->port, _configEnum, &handlerData); + handlerData.level = mCONFIG_LEVEL_CUSTOM; + ConfigurationEnumerate(&config->configTable, config->port, _configEnum, &handlerData); + handlerData.level = mCONFIG_LEVEL_OVERRIDE; + ConfigurationEnumerate(&config->overridesTable, config->port, _configEnum, &handlerData); +} + // These two are basically placeholders in case the internal layout changes, e.g. for loading separate files struct Configuration* mCoreConfigGetInput(struct mCoreConfig* config) { return &config->configTable;