1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 anjuta-c-plugin-factory.c
4 Copyright (C) 2007 Sebastien Granjoux <seb.sfo@free.fr>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * SECTION:anjuta-c-plugin-factory
23 * @title: AnjutaCPluginFactory
24 * @short_description: Anjuta C plugin factory
25 * @see_also: #AnjutaCModule, #AnjutaPluginManager
26 * @stability: Unstable
27 * @include: libanjuta/anjuta-c-plugin-factory.h
29 * #AnjutaCPluginFactory implements the #IAnjutaPluginFactory interface. This
30 * interface is used to create new plugin objects in Anjuta.
32 * This plugin factory creates new plugin objects which have a source code
33 * written in C. This factory is always available in Anjuta. Other plugin
34 * factories can be implemented as Anjuta plugins.
36 * This plugin factory uses the GLib dynamic type support implemented in
37 * #AnjutaCModule object to allow loading and unloading of plugins code. But
38 * if the plugins itself can be unloaded, the #AnjutaCModule object must stay.
39 * If the plugin is needed later, it must be registed with the same
40 * module object. The factory take care of this and of creating the plugin
46 #include "anjuta-c-plugin-factory.h"
48 #include "anjuta-c-module.h"
50 #include <libanjuta/interfaces/ianjuta-plugin-factory.h>
57 *---------------------------------------------------------------------------*/
59 struct _AnjutaCPluginFactoryClass
64 struct _AnjutaCPluginFactory
68 GHashTable
* loaded_plugins
;
71 static void ianjuta_c_plugin_factory_iface_init (IAnjutaPluginFactoryIface
*iface
);
72 G_DEFINE_TYPE_WITH_CODE (AnjutaCPluginFactory
, anjuta_c_plugin_factory
, G_TYPE_OBJECT
, \
73 G_IMPLEMENT_INTERFACE (IANJUTA_TYPE_PLUGIN_FACTORY
, ianjuta_c_plugin_factory_iface_init
))
76 *---------------------------------------------------------------------------*/
79 anjuta_c_plugin_factory_create_plugin (AnjutaCPluginFactory
*factory
,
80 AnjutaPluginHandle
*handle
,
85 GHashTable
*plugin_in_path
;
87 AnjutaCModule
*module
;
91 g_return_val_if_fail (handle
!= NULL
, NULL
);
92 g_return_val_if_fail (shell
!= NULL
, NULL
);
94 path
= anjuta_plugin_handle_get_path (handle
);
95 plugin_in_path
= g_hash_table_lookup (factory
->loaded_plugins
, path
);
96 if (plugin_in_path
== NULL
)
98 /* No loaded plugin with this path, create sub hash */
99 plugin_in_path
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, g_object_unref
);
100 g_hash_table_insert (plugin_in_path
, g_strdup (path
), plugin_in_path
);
103 pieces
= g_strsplit (anjuta_plugin_handle_get_id (handle
), ":", -1);
104 if ((pieces
== NULL
) || (pieces
[0] == NULL
))
106 g_set_error (error
, IANJUTA_PLUGIN_FACTORY_ERROR
,
107 IANJUTA_PLUGIN_FACTORY_MISSING_LOCATION
,
108 _("Missing location of plugin %s"), anjuta_plugin_handle_get_name (handle
));
111 module
= g_hash_table_lookup (plugin_in_path
, pieces
[0]);
114 /* Plugin is not loaded */
115 module
= anjuta_c_module_new (path
, pieces
[0]);
116 g_return_val_if_fail (module
!= NULL
, NULL
);
119 g_type_module_use (G_TYPE_MODULE (module
));
121 if (anjuta_c_module_get_last_error (module
, error
))
123 /* Avoid memory leak in case of error*/
128 g_hash_table_insert (plugin_in_path
, g_strdup (pieces
[0]), module
);
135 /* Find plugin type */
136 if (pieces
[1] == NULL
)
139 g_set_error (error
, IANJUTA_PLUGIN_FACTORY_ERROR
,
140 IANJUTA_PLUGIN_FACTORY_MISSING_TYPE
,
141 _("Missing type defined by plugin %s"), anjuta_plugin_handle_get_name (handle
));
144 type
= g_type_from_name (pieces
[1]);
145 if (type
== G_TYPE_INVALID
)
147 g_set_error (error
, IANJUTA_PLUGIN_FACTORY_ERROR
,
148 IANJUTA_PLUGIN_FACTORY_INVALID_TYPE
,
149 _("plugin %s fails to register type %s"), anjuta_plugin_handle_get_name (handle
), pieces
[1]);
157 plugin
= (AnjutaPlugin
*)g_object_new (type
, "shell", shell
, NULL
);
159 if ((module
!= NULL
) && (anjuta_plugin_handle_get_resident(handle
) == FALSE
))
161 /* This module can be unloaded when not needed */
162 g_type_module_unuse (G_TYPE_MODULE (module
));
168 /* IAnjutaPluginFactory interface
169 *---------------------------------------------------------------------------*/
172 ianjuta_c_plugin_factory_new_plugin (IAnjutaPluginFactory
*ifactory
, AnjutaPluginHandle
*handle
, AnjutaShell
*shell
, GError
**error
)
174 AnjutaCPluginFactory
*factory
= ANJUTA_C_PLUGIN_FACTORY (ifactory
);
176 return anjuta_c_plugin_factory_create_plugin (factory
, handle
, shell
, error
);
180 ianjuta_c_plugin_factory_iface_init (IAnjutaPluginFactoryIface
*iface
)
182 iface
->new_plugin
= ianjuta_c_plugin_factory_new_plugin
;
187 *---------------------------------------------------------------------------*/
189 /* dispose is the first destruction step. It is used to unref object created
190 * with instance_init in order to break reference counting cycles. This
191 * function could be called several times. All function should still work
192 * after this call. It has to called its parents.*/
195 anjuta_c_plugin_factory_dispose (GObject
*object
)
197 AnjutaCPluginFactory
*factory
= ANJUTA_C_PLUGIN_FACTORY (object
);
199 g_hash_table_unref (factory
->loaded_plugins
);
200 factory
->loaded_plugins
= NULL
;
202 G_OBJECT_CLASS (anjuta_c_plugin_factory_parent_class
)->dispose (object
);
206 anjuta_c_plugin_factory_class_init (AnjutaCPluginFactoryClass
*klass
)
208 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
210 gobject_class
->dispose
= anjuta_c_plugin_factory_dispose
;
214 anjuta_c_plugin_factory_init (AnjutaCPluginFactory
*factory
)
216 factory
->loaded_plugins
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
)g_hash_table_unref
);
219 /* Creation and Destruction
220 *---------------------------------------------------------------------------*/
222 * anjuta_c_plugin_factory_new:
224 * Create a new #AnjutaCPluginFactory object.
226 * Return value: a new #AnjutaCPluginFactory object.
228 AnjutaCPluginFactory
*
229 anjuta_c_plugin_factory_new (void)
231 AnjutaCPluginFactory
*factory
;
233 factory
= g_object_new (ANJUTA_TYPE_C_PLUGIN_FACTORY
, NULL
);
239 * anjuta_c_plugin_factory_free:
240 * @factory: a #AnjutaCPluginFactory
242 * Delete a #AnjutaCPluginFactory object.
245 anjuta_c_plugin_factory_free (AnjutaCPluginFactory
*factory
)
247 g_object_unref (G_OBJECT(factory
));