/soc/2013/ankitkv/gobjectification: 07d5c0892315: Added macros P...

Ankit Vani a at nevitus.org
Thu Aug 29 20:20:35 EDT 2013


Changeset: 07d5c0892315f28659846354b257064ef6311dd8
Author:	 Ankit Vani <a at nevitus.org>
Date:	 2013-08-30 04:33 +0530
Branch:	 soc.2013.gobjectification.plugins
URL: https://hg.pidgin.im/soc/2013/ankitkv/gobjectification/rev/07d5c0892315

Description:

Added macros PURPLE_PLUGIN_INIT_VAL, PURPLE_PROTOCOL_DEFINE_{STATIC,DYNAMIC}.
Added a plugin argument to PURPLE_PLUGIN_DEFINE* except for PURPLE_PLUGIN_DEFINE_STATIC.

diffstat:

 libpurple/plugins.h  |  36 +++++++++++++++++++++-
 libpurple/protocol.h |  86 +++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 107 insertions(+), 15 deletions(-)

diffs (161 lines):

diff --git a/libpurple/plugins.h b/libpurple/plugins.h
--- a/libpurple/plugins.h
+++ b/libpurple/plugins.h
@@ -163,7 +163,9 @@ struct _PurplePluginAction {
                                                      PURPLE_MINOR_VERSION)
 
 /**
- * Handles the initialization of modules.
+ * PURPLE_PLUGIN_INIT:
+ *
+ * Defines the plugin's entry points.
  */
 #if !defined(PURPLE_PLUGINS) || defined(PURPLE_STATIC_PROTOCOL)
 #define PURPLE_PLUGIN_INIT(pluginname,pluginquery,pluginload,pluginunload) \
@@ -201,6 +203,38 @@ struct _PurplePluginAction {
 	}
 #endif
 
+/**
+ * PURPLE_PLUGIN_INIT_VAL:
+ *
+ * Defines the plugin's entry points and makes a PurplePlugin pointer hold this
+ * plugin's reference while the plugin is loaded.
+ */
+#if !defined(PURPLE_PLUGINS) || defined(PURPLE_STATIC_PROTOCOL)
+#define PURPLE_PLUGIN_INIT_VAL(plugin,pluginname,pluginquery,pluginload,pluginunload) \
+	void pluginname##_plugin_initval(void); \
+	void pluginname##_plugin_initval(void) { \
+		plugin = NULL; \
+	} \
+	PURPLE_PLUGIN_INIT(pluginname,pluginquery,pluginload,pluginunload)
+#else /* PURPLE_PLUGINS  && !PURPLE_STATIC_PROTOCOL */
+#define PURPLE_PLUGIN_INIT_VAL(plugin,pluginname,pluginquery,pluginload,pluginunload) \
+	G_MODULE_EXPORT GPluginPluginInfo *gplugin_plugin_query(GError **e); \
+	G_MODULE_EXPORT GPluginPluginInfo *gplugin_plugin_query(GError **e) { \
+		plugin = NULL; \
+		return GPLUGIN_PLUGIN_INFO(pluginquery(e)); \
+	} \
+	G_MODULE_EXPORT gboolean gplugin_plugin_load(GPluginNativePlugin *p, GError **e); \
+	G_MODULE_EXPORT gboolean gplugin_plugin_load(GPluginNativePlugin *p, GError **e) { \
+		plugin = PURPLE_PLUGIN(p); \
+		return pluginload(plugin, e); \
+	} \
+	G_MODULE_EXPORT gboolean gplugin_plugin_unload(GPluginNativePlugin *p, GError **e); \
+	G_MODULE_EXPORT gboolean gplugin_plugin_unload(GPluginNativePlugin *p, GError **e) { \
+		plugin = NULL; \
+		return pluginunload(PURPLE_PLUGIN(p), e); \
+	}
+#endif
+
 G_BEGIN_DECLS
 
 /**************************************************************************/
diff --git a/libpurple/protocol.h b/libpurple/protocol.h
--- a/libpurple/protocol.h
+++ b/libpurple/protocol.h
@@ -524,23 +524,46 @@ struct _PurpleProtocolInterface
 };
 
 /**
- * Defines a protocol type using the CamelCase type name of the protocol and
- * the function prefix for the *_get_type(), *_base_init(), *_base_finalize()
- * and *_interface_init() functions of the protocol.
+ * PURPLE_PROTOCOL_DEFINE:
+ *
+ * Defines a protocol type in a plugin (given as a PurplePlugin *) by using the
+ * CamelCase type name of the protocol and the function prefix for the
+ * *_get_type(), *_base_init(), *_base_finalize() and *_interface_init()
+ * functions of the protocol.
+ *
+ * The type may be registered statically or dynamically.
  */
-#define PURPLE_PROTOCOL_DEFINE(TypeName, func_prefix) \
-	PURPLE_PROTOCOL_DEFINE_EXTENDED(TypeName, func_prefix, \
+#define PURPLE_PROTOCOL_DEFINE(plugin, TypeName, func_prefix) \
+	PURPLE_PROTOCOL_DEFINE_EXTENDED(plugin, TypeName, func_prefix, \
 	                                PURPLE_TYPE_PROTOCOL, 0)
 
-/** TODO register type dynamically (or statically if configured so)
- * Defines a protocol type using the CamelCase type name of the protocol, the
- * function prefix for the *_get_type(), *_base_init(), *_base_finalize() and
- * *_interface_init() functions, the base type, and the type flags.
+/**
+ * PURPLE_PROTOCOL_DEFINE_EXTENDED:
+ *
+ * Defines a protocol type similar to PURPLE_PROTOCOL_DEFINE, by additionally
+ * specifying the base type and the type flags.
+ *
+ * The type may be registered statically or dynamically.
  */
-#define PURPLE_PROTOCOL_DEFINE_EXTENDED(TypeName, func_prefix, BaseType, TypeFlags) \
-	GType func_prefix##_get_type(void) { \
+#if !defined(PURPLE_PLUGINS) || defined(PURPLE_STATIC_PROTOCOL)
+#define PURPLE_PROTOCOL_DEFINE_EXTENDED(plugin, TypeName, func_prefix, BaseType, TypeFlags) \
+	PURPLE_PROTOCOL_DEFINE_STATIC(TypeName, func_prefix, BaseType, TypeFlags)
+#else
+#define PURPLE_PROTOCOL_DEFINE_EXTENDED(plugin, TypeName, func_prefix, BaseType, TypeFlags) \
+	PURPLE_PROTOCOL_DEFINE_DYNAMIC(plugin, TypeName, func_prefix, BaseType, TypeFlags)
+#endif
+
+/**
+ * PURPLE_PROTOCOL_DEFINE_STATIC:
+ *
+ * Defines a protocol type statically using the type name, function prefix,
+ * base type and type flags.
+ */
+#define PURPLE_PROTOCOL_DEFINE_STATIC(TypeName, func_prefix, BaseType, TypeFlags) \
+	GType func_prefix##_get_type(void) \
+	{ \
 		static GType type = 0; \
-		if (type == 0) { \
+		if (G_UNLIKELY(type == 0)) { \
 			static const GTypeInfo info = { \
 				.instance_size = sizeof(TypeName), \
 				.class_size = sizeof(TypeName##Class), \
@@ -551,8 +574,43 @@ struct _PurpleProtocolInterface
 				.interface_init = (GInterfaceInitFunc)func_prefix##_interface_init, \
 			}; \
 			type = g_type_register_static(BaseType, #TypeName, \
-				                          &info, TypeFlags); \
-			g_type_add_interface_static(type, PURPLE_TYPE_PROTOCOL, &iface_info); \
+					                      &info, TypeFlags); \
+			if (type != G_TYPE_INVALID) \
+				g_type_add_interface_static(type, PURPLE_TYPE_PROTOCOL, &iface_info); \
+		} \
+		return type; \
+	}
+
+/**
+ * PURPLE_PROTOCOL_DEFINE_DYNAMIC:
+ *
+ * Defines a protocol type dynamically using the plugin, type name,
+ * function prefix, base type and type flags.
+ */
+#define PURPLE_PROTOCOL_DEFINE_DYNAMIC(plugin, TypeName, func_prefix, BaseType, TypeFlags) \
+	GType func_prefix##_get_type(void) \
+	{ \
+		static GType type = 0; \
+		if (G_UNLIKELY(type == 0)) { \
+			static const GTypeInfo info = { \
+				.instance_size = sizeof(TypeName), \
+				.class_size = sizeof(TypeName##Class), \
+				.base_init = (GBaseInitFunc)func_prefix##_base_init, \
+				.base_finalize = (GBaseFinalizeFunc)func_prefix##_base_finalize, \
+			}; \
+			static const GInterfaceInfo iface_info = { \
+				.interface_init = (GInterfaceInitFunc)func_prefix##_interface_init, \
+			}; \
+			if (plugin == NULL) { \
+				purple_debug_error(#TypeName, "Failed to use the type " #TypeName \
+					               " as it's plugin has not been loaded"); \
+				return G_TYPE_INVALID; \
+			} \
+			type = purple_plugin_register_type(plugin, BaseType, #TypeName, \
+				                               &info, TypeFlags); \
+			if (type != G_TYPE_INVALID) \
+				purple_plugin_add_interface(plugin, type, PURPLE_TYPE_PROTOCOL, \
+					                        &iface_info); \
 		} \
 		return type; \
 	}



More information about the Commits mailing list