225 lines
6.7 KiB
C
225 lines
6.7 KiB
C
|
/* ide-foundry-init.c
|
||
|
*
|
||
|
* Copyright 2018-2019 Christian Hergert <chergert@redhat.com>
|
||
|
*
|
||
|
* 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 <http://www.gnu.org/licenses/>.
|
||
|
*
|
||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
*/
|
||
|
|
||
|
#define G_LOG_DOMAIN "ide-foundry-init"
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
#include <libide-threading.h>
|
||
|
|
||
|
#include "ide-build-manager.h"
|
||
|
#include "ide-device-manager.h"
|
||
|
#include "ide-config-manager.h"
|
||
|
#include "ide-foundry-init.h"
|
||
|
#include "ide-run-manager.h"
|
||
|
#include "ide-runtime-manager.h"
|
||
|
#include "ide-test-manager.h"
|
||
|
#include "ide-toolchain-manager.h"
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
GQueue to_init;
|
||
|
} FoundryInit;
|
||
|
|
||
|
static void
|
||
|
foundry_init_free (FoundryInit *state)
|
||
|
{
|
||
|
g_queue_foreach (&state->to_init, (GFunc)g_object_unref, NULL);
|
||
|
g_queue_clear (&state->to_init);
|
||
|
g_slice_free (FoundryInit, state);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ide_foundry_init_async_cb (GObject *init_object,
|
||
|
GAsyncResult *result,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
GAsyncInitable *initable = (GAsyncInitable *)init_object;
|
||
|
g_autoptr(IdeTask) task = user_data;
|
||
|
g_autoptr(GError) error = NULL;
|
||
|
FoundryInit *state;
|
||
|
GCancellable *cancellable;
|
||
|
|
||
|
g_assert (G_IS_ASYNC_INITABLE (initable));
|
||
|
g_assert (G_IS_ASYNC_RESULT (result));
|
||
|
g_assert (IDE_IS_TASK (task));
|
||
|
|
||
|
if (!g_async_initable_init_finish (initable, result, &error))
|
||
|
g_warning ("Failed to init %s: %s",
|
||
|
G_OBJECT_TYPE_NAME (initable), error->message);
|
||
|
|
||
|
state = ide_task_get_task_data (task);
|
||
|
cancellable = ide_task_get_cancellable (task);
|
||
|
|
||
|
while (state->to_init.head)
|
||
|
{
|
||
|
g_autoptr(IdeObject) object = g_queue_pop_head (&state->to_init);
|
||
|
|
||
|
if (G_IS_ASYNC_INITABLE (object))
|
||
|
{
|
||
|
g_async_initable_init_async (G_ASYNC_INITABLE (object),
|
||
|
G_PRIORITY_DEFAULT,
|
||
|
cancellable,
|
||
|
ide_foundry_init_async_cb,
|
||
|
g_steal_pointer (&task));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (G_IS_INITABLE (object))
|
||
|
g_initable_init (G_INITABLE (object), NULL, NULL);
|
||
|
}
|
||
|
|
||
|
ide_task_return_boolean (task, TRUE);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
_ide_foundry_init_async (IdeContext *context,
|
||
|
GCancellable *cancellable,
|
||
|
GAsyncReadyCallback callback,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
g_autoptr(IdeTask) task = NULL;
|
||
|
FoundryInit *state;
|
||
|
GType foundry_types[] = {
|
||
|
IDE_TYPE_DEVICE_MANAGER,
|
||
|
IDE_TYPE_RUNTIME_MANAGER,
|
||
|
IDE_TYPE_TOOLCHAIN_MANAGER,
|
||
|
IDE_TYPE_CONFIG_MANAGER,
|
||
|
IDE_TYPE_BUILD_MANAGER,
|
||
|
IDE_TYPE_RUN_MANAGER,
|
||
|
IDE_TYPE_TEST_MANAGER,
|
||
|
};
|
||
|
|
||
|
g_return_if_fail (IDE_IS_CONTEXT (context));
|
||
|
|
||
|
state = g_slice_new0 (FoundryInit);
|
||
|
g_queue_init (&state->to_init);
|
||
|
|
||
|
task = ide_task_new (context, cancellable, callback, user_data);
|
||
|
ide_task_set_source_tag (task, _ide_foundry_init_async);
|
||
|
ide_task_set_task_data (task, state, foundry_init_free);
|
||
|
|
||
|
for (guint i = 0; i < G_N_ELEMENTS (foundry_types); i++)
|
||
|
{
|
||
|
g_autoptr(IdeObject) object = NULL;
|
||
|
|
||
|
/* Skip if plugins already forced this subsystem to load */
|
||
|
if ((object = ide_object_get_child_typed (IDE_OBJECT (context), foundry_types[i])))
|
||
|
continue;
|
||
|
|
||
|
object = g_object_new (foundry_types[i], NULL);
|
||
|
ide_object_append (IDE_OBJECT (context), object);
|
||
|
g_queue_push_tail (&state->to_init, g_steal_pointer (&object));
|
||
|
}
|
||
|
|
||
|
while (state->to_init.head)
|
||
|
{
|
||
|
g_autoptr(IdeObject) object = g_queue_pop_head (&state->to_init);
|
||
|
|
||
|
if (G_IS_ASYNC_INITABLE (object))
|
||
|
{
|
||
|
g_async_initable_init_async (G_ASYNC_INITABLE (object),
|
||
|
G_PRIORITY_DEFAULT,
|
||
|
NULL,
|
||
|
ide_foundry_init_async_cb,
|
||
|
g_steal_pointer (&task));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (G_IS_INITABLE (object))
|
||
|
g_initable_init (G_INITABLE (object), NULL, NULL);
|
||
|
}
|
||
|
|
||
|
ide_task_return_boolean (task, TRUE);
|
||
|
}
|
||
|
|
||
|
gboolean
|
||
|
_ide_foundry_init_finish (GAsyncResult *result,
|
||
|
GError **error)
|
||
|
{
|
||
|
g_return_val_if_fail (IDE_IS_MAIN_THREAD (), FALSE);
|
||
|
g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
|
||
|
|
||
|
return ide_task_propagate_boolean (IDE_TASK (result), error);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ide_foundry_init_unload_config_manager_cb (GObject *object,
|
||
|
GAsyncResult *result,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
IdeConfigManager *config_manager = (IdeConfigManager *)object;
|
||
|
g_autoptr(IdeTask) task = user_data;
|
||
|
g_autoptr(GError) error = NULL;
|
||
|
|
||
|
IDE_ENTRY;
|
||
|
|
||
|
g_assert (IDE_IS_CONFIG_MANAGER (config_manager));
|
||
|
g_assert (G_IS_ASYNC_RESULT (result));
|
||
|
g_assert (IDE_IS_TASK (task));
|
||
|
|
||
|
if (!ide_config_manager_save_finish (config_manager, result, &error))
|
||
|
g_warning ("Failed to save build configs: %s", error->message);
|
||
|
|
||
|
ide_task_return_boolean (task, TRUE);
|
||
|
|
||
|
IDE_EXIT;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
_ide_foundry_unload_async (IdeContext *context,
|
||
|
GCancellable *cancellable,
|
||
|
GAsyncReadyCallback callback,
|
||
|
gpointer user_data)
|
||
|
{
|
||
|
g_autoptr(IdeTask) task = NULL;
|
||
|
IdeConfigManager *config_manager;
|
||
|
|
||
|
IDE_ENTRY;
|
||
|
|
||
|
g_return_if_fail (IDE_IS_CONTEXT (context));
|
||
|
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
|
||
|
|
||
|
task = ide_task_new (context, cancellable, callback, user_data);
|
||
|
ide_task_set_source_tag (task, _ide_foundry_unload_async);
|
||
|
|
||
|
if (!(config_manager = ide_context_peek_child_typed (context, IDE_TYPE_CONFIG_MANAGER)))
|
||
|
{
|
||
|
ide_task_return_boolean (task, TRUE);
|
||
|
IDE_EXIT;
|
||
|
}
|
||
|
|
||
|
ide_config_manager_save_async (config_manager,
|
||
|
cancellable,
|
||
|
ide_foundry_init_unload_config_manager_cb,
|
||
|
g_steal_pointer (&task));
|
||
|
|
||
|
IDE_EXIT;
|
||
|
}
|
||
|
|
||
|
gboolean
|
||
|
_ide_foundry_unload_finish (GAsyncResult *result,
|
||
|
GError **error)
|
||
|
{
|
||
|
g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
|
||
|
|
||
|
return ide_task_propagate_boolean (IDE_TASK (result), error);
|
||
|
}
|