1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module peas.Engine; 26 27 private import glib.ConstructionException; 28 private import glib.ListG; 29 private import glib.Str; 30 private import gobject.ObjectG; 31 private import gobject.Signals; 32 private import peas.PluginInfo; 33 private import peasc.peas; 34 public import peasc.peastypes; 35 private import std.algorithm; 36 37 38 /** 39 * The #PeasEngine structure contains only private data and should only be 40 * accessed using the provided API. 41 */ 42 public class Engine : ObjectG 43 { 44 /** the main Gtk struct */ 45 protected PeasEngine* peasEngine; 46 47 /** Get the main Gtk struct */ 48 public PeasEngine* getEngineStruct(bool transferOwnership = false) 49 { 50 if (transferOwnership) 51 ownedRef = false; 52 return peasEngine; 53 } 54 55 /** the main Gtk struct as a void* */ 56 protected override void* getStruct() 57 { 58 return cast(void*)peasEngine; 59 } 60 61 protected override void setStruct(GObject* obj) 62 { 63 peasEngine = cast(PeasEngine*)obj; 64 super.setStruct(obj); 65 } 66 67 /** 68 * Sets our main struct and passes it to the parent class. 69 */ 70 public this (PeasEngine* peasEngine, bool ownedRef = false) 71 { 72 this.peasEngine = peasEngine; 73 super(cast(GObject*)peasEngine, ownedRef); 74 } 75 76 /** 77 * Return a new instance of Engine. 78 * If no default Engine has been instantiated yet, 79 * the first call of this function will set the default 80 * engine as the new instance of Engine. 81 * 82 * Params: 83 * global = Weather to return a global plugin loader 84 * 85 * Return: a new instance of Engine. 86 * 87 * Throws: ConstructionException GTK+ fails to create the object. 88 */ 89 public this(bool global = true) 90 { 91 PeasEngine* p; 92 93 if (global) 94 p = peas_engine_new(); 95 else 96 p = peas_engine_new_with_nonglobal_loaders(); 97 98 if(p is null) 99 { 100 throw new ConstructionException("null returned by new"); 101 } 102 103 this(p, true); 104 } 105 106 /** 107 */ 108 109 /** */ 110 public static GType getType() 111 { 112 return peas_engine_get_type(); 113 } 114 115 /** 116 * Return the existing instance of #PeasEngine or a subclass of it. 117 * If no #PeasEngine subclass has been instantiated yet, the first call 118 * of this function will return a new instance of #PeasEngine. 119 * 120 * Note: this function should never be used when multiple threads are 121 * using libpeas API as it is not thread-safe. 122 * 123 * Returns: the existing instance of #PeasEngine. 124 */ 125 public static Engine getDefault() 126 { 127 auto p = peas_engine_get_default(); 128 129 if(p is null) 130 { 131 return null; 132 } 133 134 return ObjectG.getDObject!(Engine)(cast(PeasEngine*) p); 135 } 136 137 /** 138 * This function appends a search path to the list of paths where to 139 * look for plugins. 140 * 141 * A so-called "search path" actually consists of both a 142 * module directory (where the shared libraries or language modules 143 * lie) and a data directory (where the plugin data is). 144 * 145 * The plugin will be able to use a correct data dir depending on 146 * where it is installed, hence allowing to keep the plugin agnostic 147 * when it comes to installation location: the same plugin can be 148 * installed either in the system path or in the user's home directory, 149 * without taking other special care than using 150 * peas_plugin_info_get_data_dir() when looking for its data files. 151 * 152 * If @data_dir is %NULL, then it is set to the same value as 153 * @module_dir. 154 * 155 * Params: 156 * moduleDir = the plugin module directory. 157 * dataDir = the plugin data directory. 158 */ 159 public void addSearchPath(string moduleDir, string dataDir) 160 { 161 peas_engine_add_search_path(peasEngine, Str.toStringz(moduleDir), Str.toStringz(dataDir)); 162 } 163 164 /** 165 * If the plugin identified by @info implements the @extension_type interface, 166 * then this function will return a new instance of this implementation, 167 * wrapped in a new #PeasExtension instance. Otherwise, it will return %NULL. 168 * 169 * See peas_engine_create_extension() for more information. 170 * 171 * Params: 172 * info = A loaded #PeasPluginInfo. 173 * extensionType = The implemented extension #GType. 174 * firstProperty = the name of the first property. 175 * varArgs = the value of the first property, followed optionally by more 176 * name/value pairs, followed by %NULL. 177 * 178 * Returns: a new instance of #PeasExtension wrapping 179 * the @extension_type instance, or %NULL. 180 */ 181 public PeasExtension* createExtensionValist(PluginInfo info, GType extensionType, string firstProperty, void* varArgs) 182 { 183 return peas_engine_create_extension_valist(peasEngine, (info is null) ? null : info.getPluginInfoStruct(), extensionType, Str.toStringz(firstProperty), varArgs); 184 } 185 186 /** 187 * If the plugin identified by @info implements the @extension_type interface, 188 * then this function will return a new instance of this implementation, 189 * wrapped in a new #PeasExtension instance. Otherwise, it will return %NULL. 190 * 191 * See peas_engine_create_extension() for more information. 192 * 193 * Params: 194 * info = A loaded #PeasPluginInfo. 195 * extensionType = The implemented extension #GType. 196 * nParameters = the length of the @parameters array. 197 * parameters = an array of #GParameter. 198 * 199 * Returns: a new instance of #PeasExtension wrapping 200 * the @extension_type instance, or %NULL. 201 */ 202 public PeasExtension* createExtensionv(PluginInfo info, GType extensionType, GParameter[] parameters) 203 { 204 return peas_engine_create_extensionv(peasEngine, (info is null) ? null : info.getPluginInfoStruct(), extensionType, cast(uint)parameters.length, parameters.ptr); 205 } 206 207 /** 208 * Enable a loader, enables a loader for plugins. 209 * The C plugin loader is always enabled. The other plugin 210 * loaders are: lua5.1, python and python3. 211 * 212 * For instance, the following code will enable Python 2 plugins 213 * to be loaded: 214 * |[ 215 * peas_engine_enable_loader (engine, "python"); 216 * ]| 217 * 218 * Note: plugin loaders used to be shared across #PeasEngines so enabling 219 * a loader on one #PeasEngine would enable it on all #PeasEngines. 220 * This behavior has been kept to avoid breaking applications, 221 * however a warning has been added to help applications transition. 222 * 223 * Params: 224 * loaderName = The name of the loader to enable. 225 */ 226 public void enableLoader(string loaderName) 227 { 228 peas_engine_enable_loader(peasEngine, Str.toStringz(loaderName)); 229 } 230 231 /** 232 * This function triggers garbage collection on all the loaders currently 233 * owned by the #PeasEngine. This can be used to force the loaders to destroy 234 * managed objects that still hold references to objects that are about to 235 * disappear. 236 */ 237 public void garbageCollect() 238 { 239 peas_engine_garbage_collect(peasEngine); 240 } 241 242 /** 243 * Returns the list of the names of all the loaded plugins, or an array 244 * containing a single %NULL element if there is no plugin currently loaded. 245 * 246 * Please note that the returned array is a newly allocated one: you will need 247 * to free it using g_strfreev(). 248 * 249 * Returns: A newly-allocated 250 * %NULL-terminated array of strings. 251 */ 252 public string[] getLoadedPlugins() 253 { 254 auto retStr = peas_engine_get_loaded_plugins(peasEngine); 255 256 scope(exit) Str.freeStringArray(retStr); 257 return Str.toStringArray(retStr); 258 } 259 260 /** 261 * Gets the #PeasPluginInfo corresponding with @plugin_name, 262 * or %NULL if @plugin_name was not found. 263 * 264 * Params: 265 * pluginName = A plugin name. 266 * 267 * Returns: the #PeasPluginInfo corresponding with 268 * a given plugin module name. 269 */ 270 public PluginInfo getPluginInfo(string pluginName) 271 { 272 auto p = peas_engine_get_plugin_info(peasEngine, Str.toStringz(pluginName)); 273 274 if(p is null) 275 { 276 return null; 277 } 278 279 return ObjectG.getDObject!(PluginInfo)(cast(PeasPluginInfo*) p); 280 } 281 282 /** 283 * Returns the list of #PeasPluginInfo known to the engine. 284 * 285 * Returns: a #GList of 286 * #PeasPluginInfo. Note that the list belongs to the engine and should 287 * not be freed. 288 */ 289 public ListG getPluginList() 290 { 291 auto p = peas_engine_get_plugin_list(peasEngine); 292 293 if(p is null) 294 { 295 return null; 296 } 297 298 return new ListG(cast(GList*) p); 299 } 300 301 /** 302 * Loads the plugin corresponding to @info if it's not currently loaded. 303 * Emits the "load-plugin" signal; loading the plugin 304 * actually occurs in the default signal handler. 305 * 306 * Params: 307 * info = A #PeasPluginInfo. 308 * 309 * Returns: whether the plugin has been successfully loaded. 310 */ 311 public bool loadPlugin(PluginInfo info) 312 { 313 return peas_engine_load_plugin(peasEngine, (info is null) ? null : info.getPluginInfoStruct()) != 0; 314 } 315 316 /** 317 * This function prepends a search path to the list of paths where to 318 * look for plugins. 319 * 320 * See Also: peas_engine_add_search_path() 321 * 322 * Params: 323 * moduleDir = the plugin module directory. 324 * dataDir = the plugin data directory. 325 * 326 * Since: 1.6 327 */ 328 public void prependSearchPath(string moduleDir, string dataDir) 329 { 330 peas_engine_prepend_search_path(peasEngine, Str.toStringz(moduleDir), Str.toStringz(dataDir)); 331 } 332 333 /** 334 * Returns if @info provides an extension for @extension_type. 335 * If the @info is not loaded than %FALSE will always be returned. 336 * 337 * Params: 338 * info = A #PeasPluginInfo. 339 * extensionType = The extension #GType. 340 * 341 * Returns: if @info provides an extension for @extension_type. 342 */ 343 public bool providesExtension(PluginInfo info, GType extensionType) 344 { 345 return peas_engine_provides_extension(peasEngine, (info is null) ? null : info.getPluginInfoStruct(), extensionType) != 0; 346 } 347 348 /** 349 * Rescan all the registered directories to find new or updated plugins. 350 * 351 * Calling this function will make the newly installed plugin infos 352 * be loaded by the engine, so the new plugins can be used without 353 * restarting the application. 354 */ 355 public void rescanPlugins() 356 { 357 peas_engine_rescan_plugins(peasEngine); 358 } 359 360 /** 361 * Sets the list of loaded plugins for @engine. When this function is called, 362 * the #PeasEngine will load all the plugins whose names are in @plugin_names, 363 * and ensures all other active plugins are unloaded. 364 * 365 * If @plugin_names is %NULL, all plugins will be unloaded. 366 * 367 * Params: 368 * pluginNames = A %NULL-terminated 369 * array of plugin names, or %NULL. 370 */ 371 public void setLoadedPlugins(string[] pluginNames) 372 { 373 peas_engine_set_loaded_plugins(peasEngine, Str.toStringzArray(pluginNames)); 374 } 375 376 /** 377 * Unloads the plugin corresponding to @info. 378 * Emits the "unload-plugin" signal; unloading the plugin 379 * actually occurs in the default signal handler. 380 * 381 * Params: 382 * info = A #PeasPluginInfo. 383 * 384 * Returns: whether the plugin has been successfully unloaded. 385 */ 386 public bool unloadPlugin(PluginInfo info) 387 { 388 return peas_engine_unload_plugin(peasEngine, (info is null) ? null : info.getPluginInfoStruct()) != 0; 389 } 390 391 protected class OnLoadPluginDelegateWrapper 392 { 393 static OnLoadPluginDelegateWrapper[] listeners; 394 void delegate(PluginInfo, Engine) dlg; 395 gulong handlerId; 396 397 this(void delegate(PluginInfo, Engine) dlg) 398 { 399 this.dlg = dlg; 400 this.listeners ~= this; 401 } 402 403 void remove(OnLoadPluginDelegateWrapper source) 404 { 405 foreach(index, wrapper; listeners) 406 { 407 if (wrapper.handlerId == source.handlerId) 408 { 409 listeners[index] = null; 410 listeners = std.algorithm.remove(listeners, index); 411 break; 412 } 413 } 414 } 415 } 416 417 /** 418 * The load-plugin signal is emitted when a plugin is being loaded. 419 * 420 * The plugin is being loaded in the default handler. Hence, if you want to 421 * perform some action before the plugin is loaded, you should use 422 * g_signal_connect(), but if you want to perform some action *after* the 423 * plugin is loaded (the most common case), you should use 424 * g_signal_connect_after(). 425 * 426 * Params: 427 * info = A #PeasPluginInfo. 428 */ 429 gulong addOnLoadPlugin(void delegate(PluginInfo, Engine) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 430 { 431 auto wrapper = new OnLoadPluginDelegateWrapper(dlg); 432 wrapper.handlerId = Signals.connectData( 433 this, 434 "load-plugin", 435 cast(GCallback)&callBackLoadPlugin, 436 cast(void*)wrapper, 437 cast(GClosureNotify)&callBackLoadPluginDestroy, 438 connectFlags); 439 return wrapper.handlerId; 440 } 441 442 extern(C) static void callBackLoadPlugin(PeasEngine* engineStruct, PeasPluginInfo* info, OnLoadPluginDelegateWrapper wrapper) 443 { 444 wrapper.dlg(ObjectG.getDObject!(PluginInfo)(info), wrapper.outer); 445 } 446 447 extern(C) static void callBackLoadPluginDestroy(OnLoadPluginDelegateWrapper wrapper, GClosure* closure) 448 { 449 wrapper.remove(wrapper); 450 } 451 452 protected class OnUnloadPluginDelegateWrapper 453 { 454 static OnUnloadPluginDelegateWrapper[] listeners; 455 void delegate(PluginInfo, Engine) dlg; 456 gulong handlerId; 457 458 this(void delegate(PluginInfo, Engine) dlg) 459 { 460 this.dlg = dlg; 461 this.listeners ~= this; 462 } 463 464 void remove(OnUnloadPluginDelegateWrapper source) 465 { 466 foreach(index, wrapper; listeners) 467 { 468 if (wrapper.handlerId == source.handlerId) 469 { 470 listeners[index] = null; 471 listeners = std.algorithm.remove(listeners, index); 472 break; 473 } 474 } 475 } 476 } 477 478 /** 479 * The unload-plugin signal is emitted when a plugin is being unloaded. 480 * 481 * The plugin is being unloaded in the default handler. Hence, if you want 482 * to perform some action before the plugin is unloaded (the most common 483 * case), you should use g_signal_connect(), but if you want to perform some 484 * action after the plugin is unloaded (the most common case), you should 485 * use g_signal_connect_after(). 486 * 487 * Params: 488 * info = A #PeasPluginInfo. 489 */ 490 gulong addOnUnloadPlugin(void delegate(PluginInfo, Engine) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 491 { 492 auto wrapper = new OnUnloadPluginDelegateWrapper(dlg); 493 wrapper.handlerId = Signals.connectData( 494 this, 495 "unload-plugin", 496 cast(GCallback)&callBackUnloadPlugin, 497 cast(void*)wrapper, 498 cast(GClosureNotify)&callBackUnloadPluginDestroy, 499 connectFlags); 500 return wrapper.handlerId; 501 } 502 503 extern(C) static void callBackUnloadPlugin(PeasEngine* engineStruct, PeasPluginInfo* info, OnUnloadPluginDelegateWrapper wrapper) 504 { 505 wrapper.dlg(ObjectG.getDObject!(PluginInfo)(info), wrapper.outer); 506 } 507 508 extern(C) static void callBackUnloadPluginDestroy(OnUnloadPluginDelegateWrapper wrapper, GClosure* closure) 509 { 510 wrapper.remove(wrapper); 511 } 512 }