gplugin/gplugin

Merge develop into default for the release
v0.29.0
2019-11-07, Gary Kramlich
fc9c95c883ae
Merge develop into default for the release
/*
* Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <gplugin/gplugin-plugin.h>
#include <gplugin/gplugin-enums.h>
#include <gplugin/gplugin-private.h>
/**
* SECTION:gplugin-plugin
* @Title: Plugin Objects
* @Short_description: abstract plugin implementation
*
* #GPluginPlugin is an abstract class that tracks the state of a plugin. It
* is subclassed by each loader for them to add additional data for their
* implementation.
*/
/**
* GPluginPluginState:
* @GPLUGIN_PLUGIN_STATE_UNKNOWN: The state of the plugin is unknown
* @GPLUGIN_PLUGIN_STATE_ERROR: There was an error loading or unloading the
* plugin
* @GPLUGIN_PLUGIN_STATE_QUERIED: The plugin has been queried but not loaded
* @GPLUGIN_PLUGIN_STATE_REQUERY: The plugin should be requeried
* @GPLUGIN_PLUGIN_STATE_LOADED: The plugin is loaded
* @GPLUGIN_PLUGIN_STATE_LOAD_FAILED: The plugin failed to load
*
* The expected states of a plugin.
*/
/**
* GPLUGIN_TYPE_PLUGIN:
*
* The standard _get_type macro for #GPluginPlugin.
*/
/**
* GPluginPlugin:
*
* #GPluginPlugin is an opaque data structure and should not be used directly.
*/
/**
* GPluginPluginInterface:
* @state_changed: The class closure for the #GPluginPlugin::state-changed signal.
*
* The interface that defines the behavior of plugins, including properties and
* signals.
*/
/******************************************************************************
* Enums
*****************************************************************************/
enum {
SIG_STATE_CHANGED,
SIG_LAST,
};
static guint signals[SIG_LAST] = {0, };
G_DEFINE_INTERFACE(GPluginPlugin, gplugin_plugin, G_TYPE_INVALID);
/******************************************************************************
* Object Stuff
*****************************************************************************/
static void
gplugin_plugin_default_init(GPluginPluginInterface *iface) {
GParamSpec *pspec = NULL;
/**
* GPluginPlugin:filename:
*
* The absolute path to the plugin on disk.
*/
pspec = g_param_spec_string(
"filename", "filename",
"The filename of the plugin",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
);
g_object_interface_install_property(iface, pspec);
/**
* GPluginPlugin:loader:
*
* The #GPluginLoader that loaded this plugin.
*/
pspec = g_param_spec_object(
"loader", "loader",
"The loader for this plugin",
GPLUGIN_TYPE_LOADER,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
);
g_object_interface_install_property(iface, pspec);
/**
* GPluginPlugin:info:
*
* The #GPluginPluginInfo from this plugin.
*/
pspec = g_param_spec_object(
"info", "info",
"The information for the plugin",
GPLUGIN_TYPE_PLUGIN_INFO,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
);
g_object_interface_install_property(iface, pspec);
/**
* GPluginPlugin:state:
*
* The #GPluginPluginState that this plugin is in.
*/
pspec = g_param_spec_enum(
"state", "state",
"The state of the plugin",
GPLUGIN_TYPE_PLUGIN_STATE,
GPLUGIN_PLUGIN_STATE_UNKNOWN,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT
);
g_object_interface_install_property(iface, pspec);
/**
* GPluginPlugin::state-changed:
* @plugin: The #GPluginPlugin that changed states.
* @oldstate: The old #GPluginPluginState.
* @newstate: The new state of @plugin.
*
* Emitted when @plugin changes state.
*/
signals[SIG_STATE_CHANGED] =
g_signal_new("state-changed",
GPLUGIN_TYPE_PLUGIN,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GPluginPluginInterface, state_changed),
NULL,
NULL,
NULL,
G_TYPE_NONE,
2,
GPLUGIN_TYPE_PLUGIN_STATE,
GPLUGIN_TYPE_PLUGIN_STATE);
}
/******************************************************************************
* GPluginPlugin API
*****************************************************************************/
/**
* gplugin_plugin_get_filename:
* @plugin: #GPluginPlugin instance
*
* Returns the filename that @plugin was loaded from.
*
* Returns: (transfer full): The filename of @plugin
*/
gchar *
gplugin_plugin_get_filename(GPluginPlugin *plugin) {
gchar *filename = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
g_object_get(G_OBJECT(plugin), "filename", &filename, NULL);
return filename;
}
/**
* gplugin_plugin_get_loader:
* @plugin: #GPluginPlugin instance
*
* Returns the #GPluginLoader that loaded @plugin.
*
* Returns: (transfer full): The #GPluginLoader that loaded @plugin
*/
GPluginLoader *
gplugin_plugin_get_loader(GPluginPlugin *plugin) {
GPluginLoader *loader = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
g_object_get(G_OBJECT(plugin), "loader", &loader, NULL);
return loader;
}
/**
* gplugin_plugin_get_info:
* @plugin: #GPluginPlugin instance
*
* Returns the #GPluginPluginInfo for @plugin.
*
* Returns: (transfer full): The #GPluginPluginInfo instance for @plugin
*/
GPluginPluginInfo *
gplugin_plugin_get_info(GPluginPlugin *plugin) {
GPluginPluginInfo *info = NULL;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), NULL);
g_object_get(G_OBJECT(plugin), "info", &info, NULL);
return info;
}
/**
* gplugin_plugin_get_state:
* @plugin: #GPluginPlugin instance
*
* Gets the current state of @plugin
*
* Returns: (transfer full): The current state of @plugin
*/
GPluginPluginState
gplugin_plugin_get_state(GPluginPlugin *plugin) {
GPluginPluginState state = GPLUGIN_PLUGIN_STATE_UNKNOWN;
g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), GPLUGIN_PLUGIN_STATE_UNKNOWN);
g_object_get(G_OBJECT(plugin), "state", &state, NULL);
return state;
}
/**
* gplugin_plugin_set_state:
* @plugin: #GPluginPlugin instance
* @state: new #GPluginPluginState for @plugin
*
* Changes the state of @plugin to @state. This function should only be called
* by loaders.
*/
void
gplugin_plugin_set_state(GPluginPlugin *plugin, GPluginPluginState state) {
GPluginPluginState oldstate = GPLUGIN_PLUGIN_STATE_UNKNOWN;
g_return_if_fail(GPLUGIN_IS_PLUGIN(plugin));
oldstate = gplugin_plugin_get_state(plugin);
g_object_set(G_OBJECT(plugin), "state", state, NULL);
g_signal_emit(plugin, signals[SIG_STATE_CHANGED], 0,
oldstate, state);
}