/* ide-config-provider.c * * Copyright 2016 Matthew Leeds * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * SPDX-License-Identifier: GPL-3.0-or-later */ #define G_LOG_DOMAIN "ide-config-provider" #include "config.h" #include "ide-config.h" #include "ide-config-manager.h" #include "ide-config-provider.h" G_DEFINE_INTERFACE (IdeConfigProvider, ide_config_provider, IDE_TYPE_OBJECT) enum { ADDED, REMOVED, N_SIGNALS }; static guint signals [N_SIGNALS]; static void ide_config_provider_real_load_async (IdeConfigProvider *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_assert (IDE_IS_MAIN_THREAD ()); g_assert (IDE_IS_CONFIG_PROVIDER (self)); g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); g_task_report_new_error (self, callback, user_data, ide_config_provider_real_load_async, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "%s does not implement load_async", G_OBJECT_TYPE_NAME (self)); } static gboolean ide_config_provider_real_load_finish (IdeConfigProvider *self, GAsyncResult *result, GError **error) { g_assert (IDE_IS_MAIN_THREAD ()); g_assert (IDE_IS_CONFIG_PROVIDER (self)); g_assert (G_IS_TASK (result)); g_assert (g_task_is_valid (G_TASK (result), self)); return g_task_propagate_boolean (G_TASK (self), error); } static void ide_config_provider_real_duplicate (IdeConfigProvider *self, IdeConfig *config) { g_assert (IDE_IS_MAIN_THREAD ()); g_assert (IDE_IS_CONFIG_PROVIDER (self)); g_assert (IDE_IS_CONFIG (config)); } static void ide_config_provider_real_unload (IdeConfigProvider *self) { g_assert (IDE_IS_MAIN_THREAD ()); g_assert (IDE_IS_CONFIG_PROVIDER (self)); } static void ide_config_provider_real_save_async (IdeConfigProvider *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_assert (IDE_IS_MAIN_THREAD ()); g_assert (IDE_IS_CONFIG_PROVIDER (self)); g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); g_task_report_new_error (self, callback, user_data, ide_config_provider_real_save_async, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "%s does not implement save_async", G_OBJECT_TYPE_NAME (self)); } static gboolean ide_config_provider_real_save_finish (IdeConfigProvider *self, GAsyncResult *result, GError **error) { g_assert (IDE_IS_MAIN_THREAD ()); g_assert (IDE_IS_CONFIG_PROVIDER (self)); g_assert (G_IS_TASK (result)); g_assert (g_task_is_valid (G_TASK (result), self)); return g_task_propagate_boolean (G_TASK (self), error); } static void ide_config_provider_default_init (IdeConfigProviderInterface *iface) { iface->load_async = ide_config_provider_real_load_async; iface->load_finish = ide_config_provider_real_load_finish; iface->duplicate = ide_config_provider_real_duplicate; iface->unload = ide_config_provider_real_unload; iface->save_async = ide_config_provider_real_save_async; iface->save_finish = ide_config_provider_real_save_finish; /** * IdeConfigProvider:added: * @self: an #IdeConfigProvider * @config: an #IdeConfig * * The "added" signal is emitted when a configuration * has been added to a configuration provider. * * Since: 3.32 */ signals [ADDED] = g_signal_new ("added", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IdeConfigProviderInterface, added), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, IDE_TYPE_CONFIG); g_signal_set_va_marshaller (signals [ADDED], G_TYPE_FROM_INTERFACE (iface), g_cclosure_marshal_VOID__OBJECTv); /** * IdeConfigProvider:removed: * @self: an #IdeConfigProvider * @config: an #IdeConfig * * The "removed" signal is emitted when a configuration * has been removed from a configuration provider. * * Since: 3.32 */ signals [REMOVED] = g_signal_new ("removed", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IdeConfigProviderInterface, removed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, IDE_TYPE_CONFIG); g_signal_set_va_marshaller (signals [REMOVED], G_TYPE_FROM_INTERFACE (iface), g_cclosure_marshal_VOID__OBJECTv); } /** * ide_config_provider_load_async: * @self: a #IdeConfigProvider * @cancellable: (nullable): a #GCancellable or %NULL * @callback: a callback to execute upon completion * @user_data: closure data for @callback * * This function is called to initialize the configuration provider after * the plugin instance has been created. The provider should locate any * build configurations within the project and call * ide_config_provider_emit_added() before completing the * asynchronous function so that the configuration manager may be made * aware of the configurations. * * Since: 3.32 */ void ide_config_provider_load_async (IdeConfigProvider *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_return_if_fail (IDE_IS_MAIN_THREAD ()); g_return_if_fail (IDE_IS_CONFIG_PROVIDER (self)); g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); IDE_CONFIG_PROVIDER_GET_IFACE (self)->load_async (self, cancellable, callback, user_data); } /** * ide_config_provider_load_finish: * @self: a #IdeConfigProvider * @result: a #GAsyncResult * @error: a location for a #GError, or %NULL * * Completes an asynchronous request to ide_config_provider_load_async(). * * Returns: %TRUE if successful; otherwise %FALSE and @error is set. * * Since: 3.32 */ gboolean ide_config_provider_load_finish (IdeConfigProvider *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (IDE_IS_MAIN_THREAD (), FALSE); g_return_val_if_fail (IDE_IS_CONFIG_PROVIDER (self), FALSE); g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); return IDE_CONFIG_PROVIDER_GET_IFACE (self)->load_finish (self, result, error); } /** * ide_config_provider_unload: * @self: a #IdeConfigProvider * * Requests that the configuration provider unload any state. This is called * shortly before the configuration provider is finalized. * * Implementations of #IdeConfigProvider should emit removed * for every configuration they have registered so that the * #IdeConfigManager has correct information. * * Since: 3.32 */ void ide_config_provider_unload (IdeConfigProvider *self) { g_return_if_fail (IDE_IS_MAIN_THREAD ()); g_return_if_fail (IDE_IS_CONFIG_PROVIDER (self)); IDE_CONFIG_PROVIDER_GET_IFACE (self)->unload (self); } /** * ide_config_provider_save_async: * @self: a #IdeConfigProvider * @cancellable: (nullable): a #GCancellable or %NULL * @callback: a callback to execute upon completion * @user_data: closure data for @callback * * This function is called to request that the configuration provider * persist any changed configurations back to disk. * * This function will be called before unloading the configuration provider * so that it has a chance to persist any outstanding changes. * * Since: 3.32 */ void ide_config_provider_save_async (IdeConfigProvider *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_return_if_fail (IDE_IS_MAIN_THREAD ()); g_return_if_fail (IDE_IS_CONFIG_PROVIDER (self)); g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); IDE_CONFIG_PROVIDER_GET_IFACE (self)->save_async (self, cancellable, callback, user_data); } /** * ide_config_provider_save_finish: * @self: a #IdeConfigProvider * @result: a #GAsyncResult * @error: a location for a #GError, or %NULL * * Completes an asynchronous request to ide_config_provider_save_async(). * * Returns: %TRUE if successful; otherwise %FALSE and @error is set. * * Since: 3.32 */ gboolean ide_config_provider_save_finish (IdeConfigProvider *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (IDE_IS_MAIN_THREAD (), FALSE); g_return_val_if_fail (IDE_IS_CONFIG_PROVIDER (self), FALSE); g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); return IDE_CONFIG_PROVIDER_GET_IFACE (self)->save_finish (self, result, error); } /** * ide_config_provider_emit_added: * @self: an #IdeConfigProvider * @config: an #IdeConfig * * #IdeConfigProvider implementations should call this function with * a @config when it has discovered a new configuration. * * Since: 3.32 */ void ide_config_provider_emit_added (IdeConfigProvider *self, IdeConfig *config) { g_return_if_fail (IDE_IS_CONFIG_PROVIDER (self)); g_return_if_fail (IDE_IS_CONFIG (config)); g_signal_emit (self, signals [ADDED], 0, config); } /** * ide_config_provider_emit_removed: * @self: an #IdeConfigProvider * @config: an #IdeConfig * * #IdeConfigProvider implementations should call this function with * a @config when it has discovered it was removed. * * Since: 3.32 */ void ide_config_provider_emit_removed (IdeConfigProvider *self, IdeConfig *config) { g_return_if_fail (IDE_IS_CONFIG_PROVIDER (self)); g_return_if_fail (IDE_IS_CONFIG (config)); g_signal_emit (self, signals [REMOVED], 0, config); } /** * ide_config_provider_delete: * @self: a #IdeConfigProvider * @config: an #IdeConfig owned by the provider * * Requests that the configuration provider delete the configuration. * * ide_config_provider_save_async() will be called by the * #IdeConfigManager after calling this function. * * Since: 3.32 */ void ide_config_provider_delete (IdeConfigProvider *self, IdeConfig *config) { g_return_if_fail (IDE_IS_MAIN_THREAD ()); g_return_if_fail (IDE_IS_CONFIG_PROVIDER (self)); g_return_if_fail (IDE_IS_CONFIG (config)); if (IDE_CONFIG_PROVIDER_GET_IFACE (self)->delete) IDE_CONFIG_PROVIDER_GET_IFACE (self)->delete (self, config); else g_warning ("Cannot delete configuration %s", ide_config_get_id (config)); } /** * ide_config_provider_duplicate: * @self: an #IdeConfigProvider * @config: an #IdeConfig * * Requests that the configuration provider duplicate the configuration. * * This is useful when the user wants to experiment with alternate settings * without breaking a previous configuration. * * The configuration provider does not need to persist the configuration * in this function, ide_config_provider_save_async() will be called * afterwards to persist configurations to disk. * * It is expected that the #IdeConfigProvider will emit * #IdeConfigProvider::added with the new configuration. * * Since: 3.32 */ void ide_config_provider_duplicate (IdeConfigProvider *self, IdeConfig *config) { g_return_if_fail (IDE_IS_MAIN_THREAD ()); g_return_if_fail (IDE_IS_CONFIG_PROVIDER (self)); g_return_if_fail (IDE_IS_CONFIG (config)); IDE_CONFIG_PROVIDER_GET_IFACE (self)->duplicate (self, config); }