Mercurial > irccd
changeset 212:b224b85a6ebf
Irccd: change the way JavaScript plugin configuration is accessed
When user assign a new table to the Irccd.Plugin.config or format property,
we need to merge the old table with the new one so accessing them will
give a union of all properties.
Thus, using irccdctl plugin-config will return both plugin variables and
user variables.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 23 Jun 2016 07:35:41 +0200 |
parents | c8c831d9f4bf |
children | 68831a43b1ab |
files | lib/irccd/mod-plugin.cpp lib/irccd/mod-plugin.hpp lib/irccd/plugin-js.cpp |
diffstat | 3 files changed, 143 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/irccd/mod-plugin.cpp Wed Jun 22 13:02:39 2016 +0200 +++ b/lib/irccd/mod-plugin.cpp Thu Jun 23 07:35:41 2016 +0200 @@ -26,9 +26,12 @@ namespace { -const char *PluginGlobal("\xff""\xff""irccd-plugin-ptr"); +const char PluginGlobal[] = "\xff""\xff""irccd-plugin-ptr"; /* + * wrap + * ------------------------------------------------------------------ + * * Wrap function for these functions because they all takes the same arguments. * * - load, @@ -52,6 +55,115 @@ } /* + * set + * ------------------------------------------------------------------ + * + * This setter is used to replace the Irccd.Plugin.(config|format) property when the plugin assign a new one. + * + * Because the plugin configuration always has higher priority, when a new object is assigned to 'config' or to the 'format' property, + * the plugin configuration is merged to the assigned one, adding or replacing any values. + * + * Example: + * + * Plugin 'xyz' does: + * + * Irccd.Plugin.config = { + * mode: "simple", + * level: "123" + * }; + * + * The user configuration is: + * + * [plugin.xyz] + * mode = "hard" + * path = "/var" + * + * The final user table looks like this: + * + * Irccd.Plugin.config = { + * mode: "hard", + * level: "123", + * path: "/var" + */ +duk_ret_t set(duk_context *ctx, const char *name) +{ + if (!duk_is_object(ctx, 0)) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "'%s' property must be object", name); + + // Merge old table with new one. + duk_get_global_string(ctx, name); + duk_enum(ctx, -1, 0); + + while (duk_next(ctx, -1, true)) + duk_put_prop(ctx, 0); + + // Pop enum and old table. + duk_pop_2(ctx); + + // Replace the old table with the new assigned one. + duk_put_global_string(ctx, name); + + return 0; +} + +/* + * get + * ------------------------------------------------------------------ + * + * Get the Irccd.Plugin.(config|format) property. + */ +duk_ret_t get(duk_context *ctx, const char *name) +{ + duk_get_global_string(ctx, name); + + return 1; +} + +/* + * setConfig + * ------------------------------------------------------------------ + * + * Wrap setter for Irccd.Plugin.config property. + */ +duk_ret_t setConfig(duk_context *ctx) +{ + return set(ctx, PluginConfigProperty); +} + +/* + * getConfig + * ------------------------------------------------------------------ + * + * Wrap getter for Irccd.Plugin.config property. + */ +duk_ret_t getConfig(duk_context *ctx) +{ + return get(ctx, PluginConfigProperty); +} + +/* + * setFormat + * ------------------------------------------------------------------ + * + * Wrap setter for Irccd.Plugin.format property. + */ +duk_ret_t setFormat(duk_context *ctx) +{ + return set(ctx, PluginFormatProperty); +} + +/* + * getFormat + * ------------------------------------------------------------------ + * + * Wrap getter for Irccd.Plugin.format property. + */ +duk_ret_t getFormat(duk_context *ctx) +{ + return get(ctx, PluginFormatProperty); +} + +/* * Function: Irccd.Plugin.info([name]) * ------------------------------------------------------------------ * @@ -197,10 +309,19 @@ duk_get_global_string(plugin->context(), "Irccd"); duk_push_object(plugin->context()); duk_put_function_list(plugin->context(), -1, functions); - duk_get_global_string(plugin->context(), "\xff""\xff""irccd-plugin-config"); - duk_put_prop_string(plugin->context(), -2, "config"); - duk_get_global_string(plugin->context(), "\xff""\xff""irccd-plugin-format"); - duk_put_prop_string(plugin->context(), -2, "format"); + + // 'config' property. + duk_push_string(plugin->context(), "config"); + duk_push_c_function(plugin->context(), getConfig, 0); + duk_push_c_function(plugin->context(), setConfig, 1); + duk_def_prop(plugin->context(), -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); + + // 'format' property. + duk_push_string(plugin->context(), "format"); + duk_push_c_function(plugin->context(), getFormat, 0); + duk_push_c_function(plugin->context(), setFormat, 1); + duk_def_prop(plugin->context(), -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); + duk_put_prop_string(plugin->context(), -2, "Plugin"); duk_pop(plugin->context()); }
--- a/lib/irccd/mod-plugin.hpp Wed Jun 22 13:02:39 2016 +0200 +++ b/lib/irccd/mod-plugin.hpp Thu Jun 23 07:35:41 2016 +0200 @@ -30,6 +30,16 @@ namespace irccd { /** + * Global property where to read/write plugin configuration. + */ +const char PluginConfigProperty[] = "\xff""\xff""irccd-plugin-config"; + +/** + * Global property where to read/write plugin formats. + */ +const char PluginFormatProperty[] = "\xff""\xff""irccd-plugin-format"; + +/** * \brief Irccd.Plugin JavaScript API. * \ingroup modules */
--- a/lib/irccd/plugin-js.cpp Wed Jun 22 13:02:39 2016 +0200 +++ b/lib/irccd/plugin-js.cpp Thu Jun 23 07:35:41 2016 +0200 @@ -27,6 +27,7 @@ #include "fs.hpp" #include "irccd.hpp" #include "logger.hpp" +#include "mod-plugin.hpp" #include "mod-server.hpp" #include "plugin-js.hpp" #include "service-module.hpp" @@ -35,13 +36,6 @@ namespace irccd { -namespace { - -const char *ConfigGlobal("\xff""\xff""irccd-plugin-config"); -const char *FormatGlobal("\xff""\xff""irccd-plugin-format"); - -} // !namespace - std::unordered_map<std::string, std::string> JsPlugin::getTable(const char *name) const { StackAssert sa(m_context); @@ -148,30 +142,29 @@ * In mod-plugin.cpp. */ duk_push_object(m_context); - duk_put_global_string(m_context, ConfigGlobal); + duk_put_global_string(m_context, PluginConfigProperty); duk_push_object(m_context); - duk_put_global_string(m_context, FormatGlobal); + duk_put_global_string(m_context, PluginFormatProperty); } PluginConfig JsPlugin::config() { - return getTable(ConfigGlobal); + return getTable(PluginConfigProperty); } void JsPlugin::setConfig(PluginConfig config) { - printf("%s\n", config["collaborative"].c_str()); - putTable(ConfigGlobal, config); + putTable(PluginConfigProperty, config); } PluginFormats JsPlugin::formats() { - return getTable(FormatGlobal); + return getTable(PluginFormatProperty); } void JsPlugin::setFormats(PluginFormats formats) { - putTable(FormatGlobal, formats); + putTable(PluginFormatProperty, formats); } void JsPlugin::onChannelMode(Irccd &, const ChannelModeEvent &event)