changeset 205:eb5b0f480d63

Irccd: store config and format in a hidden object
author David Demelier <markand@malikania.fr>
date Wed, 15 Jun 2016 20:59:55 +0200
parents 751ac58d7747
children 11808e98218f
files lib/irccd/mod-plugin.cpp lib/irccd/plugin-dynlib.cpp lib/irccd/plugin-dynlib.hpp lib/irccd/plugin-js.cpp lib/irccd/plugin-js.hpp lib/irccd/plugin.hpp
diffstat 6 files changed, 101 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/lib/irccd/mod-plugin.cpp	Fri Jun 10 11:54:13 2016 +0200
+++ b/lib/irccd/mod-plugin.cpp	Wed Jun 15 20:59:55 2016 +0200
@@ -197,9 +197,9 @@
 	duk_get_global_string(plugin->context(), "Irccd");
 	duk_push_object(plugin->context());
 	duk_put_function_list(plugin->context(), -1, functions);
-	duk_push_object(plugin->context());
+	duk_get_global_string(plugin->context(), "\xff""\xff""irccd-plugin-config");
 	duk_put_prop_string(plugin->context(), -2, "config");
-	duk_push_object(plugin->context());
+	duk_get_global_string(plugin->context(), "\xff""\xff""irccd-plugin-format");
 	duk_put_prop_string(plugin->context(), -2, "format");
 	duk_put_prop_string(plugin->context(), -2, "Plugin");
 	duk_pop(plugin->context());
--- a/lib/irccd/plugin-dynlib.cpp	Fri Jun 10 11:54:13 2016 +0200
+++ b/lib/irccd/plugin-dynlib.cpp	Wed Jun 15 20:59:55 2016 +0200
@@ -41,8 +41,8 @@
 
 } // !namespace
 
-DynlibPlugin::DynlibPlugin(std::string name, std::string path, PluginConfig config)
-	: Plugin(name, path, std::move(config))
+DynlibPlugin::DynlibPlugin(std::string name, std::string path)
+	: Plugin(name, path)
 	, m_dso(std::move(path))
 	, m_onCommand(sym<OnCommand>(m_dso, "irccd_onCommand"))
 	, m_onConnect(sym<OnConnect>(m_dso, "irccd_onConnect"))
--- a/lib/irccd/plugin-dynlib.hpp	Fri Jun 10 11:54:13 2016 +0200
+++ b/lib/irccd/plugin-dynlib.hpp	Wed Jun 15 20:59:55 2016 +0200
@@ -80,16 +80,19 @@
 	OnUnload m_onUnload;
 	OnWhois m_onWhois;
 
+	// Configuration and formats.
+	PluginConfig m_config;
+	PluginFormats m_formats;
+
 public:
 	/**
 	 * Construct the plugin.
 	 *
 	 * \param name the name
 	 * \param path the fully resolved path (must be absolute)
-	 * \param config the optional configuration
 	 * \throw std::exception on failures
 	 */
-	DynlibPlugin(std::string name, std::string path, PluginConfig config = PluginConfig());
+	DynlibPlugin(std::string name, std::string path);
 
 	/**
 	 * \copydoc Plugin::onCommand
--- a/lib/irccd/plugin-js.cpp	Fri Jun 10 11:54:13 2016 +0200
+++ b/lib/irccd/plugin-js.cpp	Wed Jun 15 20:59:55 2016 +0200
@@ -30,10 +30,46 @@
 #include "mod-server.hpp"
 #include "plugin-js.hpp"
 #include "service-module.hpp"
+#include "service-plugin.hpp"
 #include "timer.hpp"
 
 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);
+	std::unordered_map<std::string, std::string> result;
+
+	duk_get_global_string(m_context, name);
+	dukx_enumerate(m_context, -1, 0, true, [&] (auto ctx) {
+		result.emplace(duk_to_string(ctx, -2), duk_to_string(ctx, -1));
+	});
+	duk_pop(m_context);
+
+	return result;
+}
+
+void JsPlugin::putTable(const char *name, const std::unordered_map<std::string, std::string> &vars)
+{
+	StackAssert sa(m_context);
+
+	duk_get_global_string(m_context, name);
+
+	for (const auto &pair : vars) {
+		dukx_push_std_string(m_context, pair.second);
+		duk_put_prop_string(m_context, -2, pair.first.c_str());
+	}
+
+	duk_pop(m_context);
+}
+
 void JsPlugin::call(const std::string &name, unsigned nargs)
 {
 	duk_get_global_string(m_context, name.c_str());
@@ -100,46 +136,42 @@
 	duk_pop_2(m_context);
 }
 
-void JsPlugin::putConfig(const PluginConfig &config)
+JsPlugin::JsPlugin(std::string name, std::string path)
+	: Plugin(name, path)
 {
-	StackAssert sa(m_context);
-
-	// TODO: override dataPath, configPath, cachePath.
-	// TODO: verify more that these values still exist.
-
-	// Store plugin configuration into Irccd.Plugin.config.
-	duk_get_global_string(m_context, "Irccd");
-	duk_get_prop_string(m_context, -1, "Plugin");
-	duk_get_prop_string(m_context, -1, "config");
-
-	for (const auto &pair : config) {
-		dukx_push_std_string(m_context, pair.second);
-		duk_put_prop_string(m_context, -2, pair.first.c_str());
-	}
-
-	duk_put_prop_string(m_context, -2, "config");
-	duk_pop_n(m_context, 2);
+	/*
+	 * Create two special tables for configuration and formats, they are referenced later as
+	 *
+	 *   - Irccd.Plugin.config
+	 *   - Irccd.Plugin.format
+	 *
+	 * In mod-plugin.cpp.
+	 */
+	duk_push_object(m_context);
+	duk_put_global_string(m_context, ConfigGlobal);
+	duk_push_object(m_context);
+	duk_put_global_string(m_context, FormatGlobal);
 }
 
-void JsPlugin::putFormats()
+PluginConfig JsPlugin::config()
 {
-	StackAssert sa(m_context);
-
-	duk_get_global_string(m_context, "Irccd");
-	duk_get_prop_string(m_context, -1, "Plugin");
-	duk_get_prop_string(m_context, -1, "format");
-
-	for (const auto &pair : formats()) {
-		dukx_push_std_string(m_context, pair.second);
-		duk_put_prop_string(m_context, -2, pair.first.c_str());
-	}
-
-	duk_pop_n(m_context, 3);
+	return getTable(ConfigGlobal);
 }
 
-JsPlugin::JsPlugin(std::string name, std::string path, const PluginConfig &config)
-	: Plugin(name, path, config)
+void JsPlugin::setConfig(PluginConfig config)
 {
+	printf("%s\n", config["collaborative"].c_str());
+	putTable(ConfigGlobal, config);
+}
+
+PluginFormats JsPlugin::formats()
+{
+	return getTable(FormatGlobal);
+}
+
+void JsPlugin::setFormats(PluginFormats formats)
+{
+	putTable(FormatGlobal, formats);
 }
 
 void JsPlugin::onChannelMode(Irccd &,
@@ -265,8 +297,12 @@
 
 	duk_pop(m_context);
 
-	putConfig(config());
-	putFormats();
+	/*
+	 * We put configuration and formats after loading the file and before calling onLoad to allow the plugin adding configuration
+	 * to Irccd.Plugin.(config|format) before the user.
+	 */
+	setConfig(irccd.pluginService().config(name()));
+	setFormats(irccd.pluginService().formats(name()));
 
 	// Read metadata .
 	duk_get_global_string(m_context, "info");
--- a/lib/irccd/plugin-js.hpp	Fri Jun 10 11:54:13 2016 +0200
+++ b/lib/irccd/plugin-js.hpp	Wed Jun 15 20:59:55 2016 +0200
@@ -45,13 +45,13 @@
 	// Store loaded modules.
 	std::vector<std::shared_ptr<Module>> m_modules;
 
-	// Private helpers
+	// Private helpers.
+	std::unordered_map<std::string, std::string> getTable(const char *name) const;
+	void putTable(const char *name, const std::unordered_map<std::string, std::string> &vars);
 	void call(const std::string &name, unsigned nargs = 0);
 	void putModules(Irccd &irccd);
 	void putVars();
 	void putPath(const std::string &varname, const std::string &append, path::Path type);
-	void putConfig(const PluginConfig &config);
-	void putFormats();
 
 public:
 	/**
@@ -59,9 +59,8 @@
 	 *
 	 * \param name the plugin name
 	 * \param path the path to the plugin
-	 * \param config the configuration
 	 */
-	IRCCD_EXPORT JsPlugin(std::string name, std::string path, const PluginConfig &config = PluginConfig());
+	IRCCD_EXPORT JsPlugin(std::string name, std::string path);
 
 	/**
 	 * Access the Duktape context.
@@ -73,6 +72,14 @@
 		return m_context;
 	}
 
+	IRCCD_EXPORT PluginConfig config() override;
+
+	IRCCD_EXPORT void setConfig(PluginConfig) override;
+
+	IRCCD_EXPORT PluginFormats formats() override;
+
+	IRCCD_EXPORT void setFormats(PluginFormats formats) override;
+
 	/**
 	 * \copydoc Plugin::onCommand
 	 */
--- a/lib/irccd/plugin.hpp	Fri Jun 10 11:54:13 2016 +0200
+++ b/lib/irccd/plugin.hpp	Wed Jun 15 20:59:55 2016 +0200
@@ -71,23 +71,17 @@
 	std::string m_summary{"unknown"};
 	std::string m_version{"unknown"};
 
-	// Configuration and formats.
-	PluginConfig m_config;
-	PluginFormats m_formats;
-
 public:
 	/**
 	 * Constructor.
 	 *
 	 * \param name the plugin id
 	 * \param path the fully resolved path to the plugin
-	 * \param config the plugin configuration
 	 * \throws std::runtime_error on errors
 	 */
-	inline Plugin(std::string name, std::string path, PluginConfig config = PluginConfig()) noexcept
+	inline Plugin(std::string name, std::string path) noexcept
 		: m_name(std::move(name))
 		, m_path(std::move(path))
-		, m_config(std::move(config))
 	{
 	}
 
@@ -202,19 +196,9 @@
 	 *
 	 * \return the config
 	 */
-	inline const PluginConfig &config() const noexcept
+	virtual PluginConfig config()
 	{
-		return m_config;
-	}
-
-	/**
-	 * Overloaded function.
-	 *
-	 * \return the config
-	 */
-	inline PluginConfig &config() noexcept
-	{
-		return m_config;
+		return {};
 	}
 
 	/**
@@ -222,9 +206,9 @@
 	 *
 	 * \param config the configuration
 	 */
-	inline void setConfig(PluginConfig config) noexcept
+	virtual void setConfig(PluginConfig config)
 	{
-		m_config = std::move(config);
+		(void)config;
 	}
 
 	/**
@@ -232,19 +216,9 @@
 	 *
 	 * \return the format
 	 */
-	inline const PluginFormats &formats() const noexcept
+	virtual PluginFormats formats()
 	{
-		return m_formats;
-	}
-
-	/**
-	 * Overloaded function.
-	 *
-	 * \return the formats
-	 */
-	inline PluginFormats &formats() noexcept
-	{
-		return m_formats;
+		return {};
 	}
 
 	/**
@@ -252,9 +226,9 @@
 	 *
 	 * \param formats the formats
 	 */
-	inline void setFormats(PluginFormats formats) noexcept
+	virtual void setFormats(PluginFormats formats)
 	{
-		m_formats = std::move(formats);
+		(void)formats;
 	}
 
 	/**