From 6f0f7d1b40a8fa8d46a2d6f4317600001cdbbb18 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:57:27 +0200 Subject: Adding upstream version 43.5. Signed-off-by: Daniel Baumann --- lib/gs-category-manager.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 lib/gs-category-manager.c (limited to 'lib/gs-category-manager.c') diff --git a/lib/gs-category-manager.c b/lib/gs-category-manager.c new file mode 100644 index 0000000..0e37264 --- /dev/null +++ b/lib/gs-category-manager.c @@ -0,0 +1,151 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2021 Endless OS Foundation LLC + * + * Author: Philip Withnall + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/** + * SECTION:gs-category-manager + * @short_description: A container to store #GsCategory instances in + * + * #GsCategoryManager is a container object which stores #GsCategory instances, + * so that they can be consistently reused by other code, without creating + * multiple #GsCategory instances for the same category ID. + * + * It is intended to be used as a singleton, and typically accessed by calling + * gs_plugin_loader_get_category_manager(). + * + * Since: 40 + */ + +#include "config.h" + +#include +#include +#include + +#include "gs-category-manager.h" +#include "gs-desktop-data.h" + +struct _GsCategoryManager +{ + GObject parent; + + /* Array of #GsCategory instances corresponding to the entries in gs_desktop_get_data() + * The +1 is for a NULL terminator */ + GsCategory *categories[GS_DESKTOP_DATA_N_ENTRIES + 1]; +}; + +G_DEFINE_TYPE (GsCategoryManager, gs_category_manager, G_TYPE_OBJECT) + +static void +gs_category_manager_dispose (GObject *object) +{ + GsCategoryManager *self = GS_CATEGORY_MANAGER (object); + + for (gsize i = 0; i < G_N_ELEMENTS (self->categories); i++) + g_clear_object (&self->categories[i]); + + G_OBJECT_CLASS (gs_category_manager_parent_class)->dispose (object); +} + +static void +gs_category_manager_class_init (GsCategoryManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gs_category_manager_dispose; +} + +static void +gs_category_manager_init (GsCategoryManager *self) +{ + const GsDesktopData *msdata; + + /* Set up the category data, and check our expectations about the length + * of gs_desktop_get_data() match reality. */ + msdata = gs_desktop_get_data (); + for (gsize i = 0; msdata[i].id != NULL; i++) { + g_assert (i < G_N_ELEMENTS (self->categories) - 1); + self->categories[i] = gs_category_new_for_desktop_data (&msdata[i]); + } + + g_assert (self->categories[G_N_ELEMENTS (self->categories) - 2] != NULL); + g_assert (self->categories[G_N_ELEMENTS (self->categories) - 1] == NULL); +} + +/** + * gs_category_manager_new: + * + * Create a new #GsCategoryManager. It will contain all the categories, but + * their sizes will not be set until gs_category_increment_size() is called + * on them. + * + * Returns: (transfer full): a new #GsCategoryManager + * Since: 40 + */ +GsCategoryManager * +gs_category_manager_new (void) +{ + return g_object_new (GS_TYPE_CATEGORY_MANAGER, NULL); +} + +/** + * gs_category_manager_lookup: + * @self: a #GsCategoryManager + * @id: ID of the category to look up + * + * Look up a category by its ID. If the category is not found, %NULL is + * returned. + * + * Returns: (transfer full) (nullable): the #GsCategory, or %NULL + * Since: 40 + */ +GsCategory * +gs_category_manager_lookup (GsCategoryManager *self, + const gchar *id) +{ + g_return_val_if_fail (GS_IS_CATEGORY_MANAGER (self), NULL); + g_return_val_if_fail (id != NULL && *id != '\0', NULL); + + /* There are only on the order of 10 categories, so this is quick */ + for (gsize i = 0; i < G_N_ELEMENTS (self->categories) - 1; i++) { + if (g_str_equal (gs_category_get_id (self->categories[i]), id)) + return g_object_ref (self->categories[i]); + } + + return NULL; +} + +/** + * gs_category_manager_get_categories: + * @self: a #GsCategoryManager + * @out_n_categories: (optional) (out caller-allocates): return location for + * the number of categories in the return value, or %NULL to ignore + * + * Get the full list of categories from the category manager. The returned array + * is %NULL terminated and guaranteed to be non-%NULL (although it may be + * empty). + * + * If @out_n_categories is provided, it will be set to the number of #GsCategory + * objects in the return value, not including the %NULL terminator. + * + * Returns: (array length=out_n_categories) (transfer none) (not nullable): the + * categories; do not free this memory + * Since: 40 + */ +GsCategory * const * +gs_category_manager_get_categories (GsCategoryManager *self, + gsize *out_n_categories) +{ + g_return_val_if_fail (GS_IS_CATEGORY_MANAGER (self), NULL); + + if (out_n_categories != NULL) + *out_n_categories = G_N_ELEMENTS (self->categories) - 1; + + return self->categories; +} -- cgit v1.2.3