[gnome-menus/wip-gobject-rebase2: 4/5] Remove GMenuTreeItem from public API
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-menus/wip-gobject-rebase2: 4/5] Remove GMenuTreeItem from public API
- Date: Wed, 20 Apr 2011 21:48:45 +0000 (UTC)
commit d3ed1f9e54d9237b6c46b68209391c0e9898fde6
Author: Colin Walters <walters verbum org>
Date: Wed Apr 20 17:42:39 2011 -0400
Remove GMenuTreeItem from public API
gmenu_tree_directory_get_contents() wasn't actually bindable because
there's no way to express to introspection the inheritance hierarchy
(and to do the runtime type checking necessary via
gmenu_tree_item_get_item_type()).
Therefore, drop it, and instead add explicit functions where each type
is needed. So for gmenu_tree_directory_get_contents(), we instead
add an explicit typesafe iterator object.
The only other instance was gmenu_tree_alias.
Note that gmenu_tree_item_ref() and gmenu_tree_item_unref() remain;
they're C only, and already just took "gpointer".
libmenu/gmenu-tree.c | 244 +++++++++++++++++++++++++++++++++++++++++++-----
libmenu/gmenu-tree.h | 32 ++++---
util/test-menu-spec.c | 44 +++++----
3 files changed, 263 insertions(+), 57 deletions(-)
---
diff --git a/libmenu/gmenu-tree.c b/libmenu/gmenu-tree.c
index 12306bd..8498d2a 100644
--- a/libmenu/gmenu-tree.c
+++ b/libmenu/gmenu-tree.c
@@ -29,6 +29,15 @@
#include "menu-util.h"
#include "canonicalize.h"
+/* private */
+typedef struct GMenuTreeItem GMenuTreeItem;
+#define GMENU_TREE_ITEM(i) ((GMenuTreeItem *)(i))
+#define GMENU_TREE_DIRECTORY(i) ((GMenuTreeDirectory *)(i))
+#define GMENU_TREE_ENTRY(i) ((GMenuTreeEntry *)(i))
+#define GMENU_TREE_SEPARATOR(i) ((GMenuTreeSeparator *)(i))
+#define GMENU_TREE_HEADER(i) ((GMenuTreeHeader *)(i))
+#define GMENU_TREE_ALIAS(i) ((GMenuTreeAlias *)(i))
+
enum {
PROP_0,
@@ -76,6 +85,17 @@ struct GMenuTreeItem
gint refcount;
};
+struct GMenuTreeIter
+{
+ gint refcount;
+
+ gint tree_serial;
+
+ GMenuTreeItem *item;
+ GSList *contents;
+ GSList *contents_iter;
+};
+
struct GMenuTreeDirectory
{
GMenuTreeItem item;
@@ -660,7 +680,7 @@ find_path (GMenuTreeDirectory *directory,
{
GMenuTreeItem *item = tmp->data;
- if (gmenu_tree_item_get_item_type (item) != GMENU_TREE_ITEM_DIRECTORY)
+ if (item->type != GMENU_TREE_ITEM_DIRECTORY)
{
tmp = tmp->next;
continue;
@@ -713,14 +733,6 @@ gmenu_tree_invoke_monitors (GMenuTree *tree)
g_signal_emit (tree, gmenu_tree_signals[CHANGED], 0);
}
-GMenuTreeItemType
-gmenu_tree_item_get_item_type (GMenuTreeItem *item)
-{
- g_return_val_if_fail (item != NULL, 0);
-
- return item->type;
-}
-
/**
* gmenu_tree_directory_get_parent:
* @entry: a #GMenuTreeDirectory
@@ -760,26 +772,158 @@ gmenu_tree_item_set_parent (GMenuTreeItem *item,
item->parent = parent;
}
-GSList *
-gmenu_tree_directory_get_contents (GMenuTreeDirectory *directory)
+/**
+ * gmenu_tree_iter_ref: (skip)
+ * @iter: iter
+ *
+ * Increment the reference count of @iter
+ */
+GMenuTreeIter *
+gmenu_tree_iter_ref (GMenuTreeIter *iter)
{
- GSList *retval;
- GSList *tmp;
+ g_atomic_int_inc (&iter->refcount);
+ return iter;
+}
+
+/**
+ * gmenu_tree_iter_unref: (skip)
+ * @iter: iter
+ *
+ * Decrement the reference count of @iter
+ */
+void
+gmenu_tree_iter_unref (GMenuTreeIter *iter)
+{
+ if (!g_atomic_int_dec_and_test (&iter->refcount))
+ return;
+
+ g_slist_foreach (iter->contents, (GFunc)gmenu_tree_item_unref, NULL);
+ g_slist_free (iter->contents);
+
+ g_slice_free (GMenuTreeIter, iter);
+}
+
+/**
+ * gmenu_tree_directory_iter:
+ * @directory: directory
+ *
+ * Returns: (transfer full): A new iterator over the directory contents
+ */
+GMenuTreeIter *
+gmenu_tree_directory_iter (GMenuTreeDirectory *directory)
+{
+ GMenuTreeIter *iter;
g_return_val_if_fail (directory != NULL, NULL);
- retval = NULL;
+ iter = g_slice_new0 (GMenuTreeIter);
+ iter->refcount = 1;
- tmp = directory->contents;
- while (tmp != NULL)
- {
- retval = g_slist_prepend (retval,
- gmenu_tree_item_ref (tmp->data));
+ iter->contents = g_slist_copy (directory->contents);
+ iter->contents_iter = iter->contents;
+ g_slist_foreach (iter->contents, (GFunc) gmenu_tree_item_ref, NULL);
- tmp = tmp->next;
+ return iter;
+}
+
+/**
+ * gmenu_tree_iter_next:
+ * @iter: iter
+ *
+ * Change the iterator to the next item, and return its type. If
+ * there are no more items, %GMENU_TREE_ITEM_INVALID is returned.
+ *
+ * Returns: The type of the next item that can be retrived from the iterator
+ */
+GMenuTreeItemType
+gmenu_tree_iter_next (GMenuTreeIter *iter)
+{
+ g_return_val_if_fail (iter != NULL, GMENU_TREE_ITEM_INVALID);
+
+ if (iter->contents_iter)
+ {
+ iter->item = iter->contents_iter->data;
+ iter->contents_iter = iter->contents_iter->next;
+ return iter->item->type;
}
+ else
+ return GMENU_TREE_ITEM_INVALID;
+}
+
+/**
+ * gmenu_tree_iter_get_directory:
+ * @iter: iter
+ *
+ * This method may only be called if gmenu_tree_iter_get_next_type()
+ * returned GMENU_TREE_ITEM_DIRECTORY.
+ *
+ * Returns: (transfer full): A directory
+ */
+GMenuTreeDirectory *
+gmenu_tree_iter_get_directory (GMenuTreeIter *iter)
+{
+ g_return_val_if_fail (iter != NULL, NULL);
+ g_return_val_if_fail (iter->item != NULL, NULL);
+ g_return_val_if_fail (iter->item->type == GMENU_TREE_ITEM_DIRECTORY, NULL);
+
+ return (GMenuTreeDirectory*)gmenu_tree_item_ref (iter->item);
+}
+
+/**
+ * gmenu_tree_iter_get_entry:
+ * @iter: iter
+ *
+ * This method may only be called if gmenu_tree_iter_get_next_type()
+ * returned GMENU_TREE_ITEM_ENTRY.
+ *
+ * Returns: (transfer full): An entry
+ */
+GMenuTreeEntry *
+gmenu_tree_iter_get_entry (GMenuTreeIter *iter)
+{
+ g_return_val_if_fail (iter != NULL, NULL);
+ g_return_val_if_fail (iter->item != NULL, NULL);
+ g_return_val_if_fail (iter->item->type == GMENU_TREE_ITEM_ENTRY, NULL);
+
+ return (GMenuTreeEntry*)gmenu_tree_item_ref (iter->item);
+}
+
+/**
+ * gmenu_tree_iter_get_header:
+ * @iter: iter
+ *
+ * This method may only be called if gmenu_tree_iter_get_next_type()
+ * returned GMENU_TREE_ITEM_HEADER.
+ *
+ * Returns: (transfer full): A header
+ */
+GMenuTreeHeader *
+gmenu_tree_iter_get_header (GMenuTreeIter *iter)
+{
+ g_return_val_if_fail (iter != NULL, NULL);
+ g_return_val_if_fail (iter->item != NULL, NULL);
+ g_return_val_if_fail (iter->item->type == GMENU_TREE_ITEM_HEADER, NULL);
+
+ return (GMenuTreeHeader*)gmenu_tree_item_ref (iter->item);
+}
- return g_slist_reverse (retval);
+/**
+ * gmenu_tree_iter_get_alias:
+ * @iter: iter
+ *
+ * This method may only be called if gmenu_tree_iter_get_next_type()
+ * returned GMENU_TREE_ITEM_ALIAS.
+ *
+ * Returns: (transfer full): An alias
+ */
+GMenuTreeAlias *
+gmenu_tree_iter_get_alias (GMenuTreeIter *iter)
+{
+ g_return_val_if_fail (iter != NULL, NULL);
+ g_return_val_if_fail (iter->item != NULL, NULL);
+ g_return_val_if_fail (iter->item->type == GMENU_TREE_ITEM_ALIAS, NULL);
+
+ return (GMenuTreeAlias*)gmenu_tree_item_ref (iter->item);
}
const char *
@@ -924,6 +1068,16 @@ gmenu_tree_header_get_directory (GMenuTreeHeader *header)
return gmenu_tree_item_ref (header->directory);
}
+GMenuTreeItemType
+gmenu_tree_alias_get_item_type (GMenuTreeAlias *alias)
+{
+ g_return_val_if_fail (alias != NULL, GMENU_TREE_ITEM_INVALID);
+
+ g_assert (alias->aliased_item != NULL);
+ return alias->aliased_item->type;
+}
+
+
GMenuTreeDirectory *
gmenu_tree_alias_get_directory (GMenuTreeAlias *alias)
{
@@ -932,12 +1086,34 @@ gmenu_tree_alias_get_directory (GMenuTreeAlias *alias)
return gmenu_tree_item_ref (alias->directory);
}
-GMenuTreeItem *
-gmenu_tree_alias_get_item (GMenuTreeAlias *alias)
+/**
+ * gmenu_tree_alias_get_aliased_directory:
+ * @alias: alias
+ *
+ * Returns: (transfer full): The aliased directory entry
+ */
+GMenuTreeDirectory *
+gmenu_tree_alias_get_aliased_directory (GMenuTreeAlias *alias)
{
g_return_val_if_fail (alias != NULL, NULL);
+ g_return_val_if_fail (((GMenuTreeItem*)alias->aliased_item)->type == GMENU_TREE_ITEM_DIRECTORY, NULL);
- return gmenu_tree_item_ref (alias->aliased_item);
+ return (GMenuTreeDirectory*)gmenu_tree_item_ref (alias->aliased_item);
+}
+/**
+
+ * gmenu_tree_alias_get_aliased_entry:
+ * @alias: alias
+ *
+ * Returns: (transfer full): The aliased entry
+ */
+GMenuTreeEntry *
+gmenu_tree_alias_get_aliased_entry (GMenuTreeAlias *alias)
+{
+ g_return_val_if_fail (alias != NULL, NULL);
+ g_return_val_if_fail (((GMenuTreeItem*)alias->aliased_item)->type == GMENU_TREE_ITEM_ENTRY, NULL);
+
+ return (GMenuTreeEntry*)gmenu_tree_item_ref (alias->aliased_item);
}
static GMenuTreeDirectory *
@@ -1107,7 +1283,10 @@ gmenu_tree_alias_new (GMenuTreeDirectory *parent,
if (item->type != GMENU_TREE_ITEM_ALIAS)
retval->aliased_item = gmenu_tree_item_ref (item);
else
- retval->aliased_item = gmenu_tree_item_ref (gmenu_tree_alias_get_item (GMENU_TREE_ALIAS (item)));
+ {
+ GMenuTreeAlias *alias = GMENU_TREE_ALIAS (item);
+ retval->aliased_item = gmenu_tree_item_ref (alias->aliased_item);
+ }
gmenu_tree_item_set_parent (GMENU_TREE_ITEM (retval->directory), NULL);
gmenu_tree_item_set_parent (retval->aliased_item, NULL);
@@ -3881,7 +4060,7 @@ merge_subdirs_and_entries (GMenuTree *tree,
GMenuTreeItem *item = tmp->data;
GMenuTreeItemType type;
- type = gmenu_tree_item_get_item_type (item);
+ type = item->type;
if (type == GMENU_TREE_ITEM_ALIAS)
{
@@ -4188,6 +4367,19 @@ gmenu_tree_force_rebuild (GMenuTree *tree)
}
GType
+gmenu_tree_iter_get_type (void)
+{
+ static GType gtype = G_TYPE_INVALID;
+ if (gtype == G_TYPE_INVALID)
+ {
+ gtype = g_boxed_type_register_static ("GMenuTreeIter",
+ (GBoxedCopyFunc)gmenu_tree_iter_ref,
+ (GBoxedFreeFunc)gmenu_tree_iter_unref);
+ }
+ return gtype;
+}
+
+GType
gmenu_tree_directory_get_type (void)
{
static GType gtype = G_TYPE_INVALID;
diff --git a/libmenu/gmenu-tree.h b/libmenu/gmenu-tree.h
index 061cc6d..14716b8 100644
--- a/libmenu/gmenu-tree.h
+++ b/libmenu/gmenu-tree.h
@@ -45,7 +45,7 @@ struct _GMenuTreeClass
GType gmenu_tree_get_type (void) G_GNUC_CONST;
-typedef struct GMenuTreeItem GMenuTreeItem;
+typedef struct GMenuTreeIter GMenuTreeIter;
typedef struct GMenuTreeDirectory GMenuTreeDirectory;
typedef struct GMenuTreeEntry GMenuTreeEntry;
typedef struct GMenuTreeSeparator GMenuTreeSeparator;
@@ -62,12 +62,7 @@ typedef enum
GMENU_TREE_ITEM_ALIAS
} GMenuTreeItemType;
-#define GMENU_TREE_ITEM(i) ((GMenuTreeItem *)(i))
-#define GMENU_TREE_DIRECTORY(i) ((GMenuTreeDirectory *)(i))
-#define GMENU_TREE_ENTRY(i) ((GMenuTreeEntry *)(i))
-#define GMENU_TREE_SEPARATOR(i) ((GMenuTreeSeparator *)(i))
-#define GMENU_TREE_HEADER(i) ((GMenuTreeHeader *)(i))
-#define GMENU_TREE_ALIAS(i) ((GMenuTreeAlias *)(i))
+GType gmenu_tree_iter_get_type (void);
/* Explicitly skip item, it's a "hidden" base class */
GType gmenu_tree_directory_get_type (void);
@@ -101,10 +96,8 @@ GMenuTreeDirectory *gmenu_tree_get_directory_from_path (GMenuTree *tree,
gpointer gmenu_tree_item_ref (gpointer item);
void gmenu_tree_item_unref (gpointer item);
-GMenuTreeItemType gmenu_tree_item_get_item_type (GMenuTreeItem *item);
GMenuTreeDirectory *gmenu_tree_directory_get_parent (GMenuTreeDirectory *directory);
-GSList *gmenu_tree_directory_get_contents (GMenuTreeDirectory *directory);
const char *gmenu_tree_directory_get_name (GMenuTreeDirectory *directory);
const char *gmenu_tree_directory_get_comment (GMenuTreeDirectory *directory);
const char *gmenu_tree_directory_get_icon (GMenuTreeDirectory *directory);
@@ -113,12 +106,23 @@ const char *gmenu_tree_directory_get_menu_id (GMenuTreeDirectory *dire
gboolean gmenu_tree_directory_get_is_nodisplay (GMenuTreeDirectory *directory);
+GMenuTreeIter *gmenu_tree_directory_iter (GMenuTreeDirectory *directory);
+
+GMenuTreeIter *gmenu_tree_iter_ref (GMenuTreeIter *iter);
+void gmenu_tree_iter_unref (GMenuTreeIter *iter);
+
+GMenuTreeItemType gmenu_tree_iter_next (GMenuTreeIter *iter);
+GMenuTreeDirectory *gmenu_tree_iter_get_directory (GMenuTreeIter *iter);
+GMenuTreeEntry *gmenu_tree_iter_get_entry (GMenuTreeIter *iter);
+GMenuTreeHeader *gmenu_tree_iter_get_header (GMenuTreeIter *iter);
+GMenuTreeAlias *gmenu_tree_iter_get_alias (GMenuTreeIter *iter);
+
char *gmenu_tree_directory_make_path (GMenuTreeDirectory *directory,
GMenuTreeEntry *entry);
-GDesktopAppInfo *gmenu_tree_entry_get_app_info (GMenuTreeEntry *entry);
-GMenuTreeDirectory *gmenu_tree_entry_get_parent (GMenuTreeEntry *entry);
+GDesktopAppInfo *gmenu_tree_entry_get_app_info (GMenuTreeEntry *entry);
+GMenuTreeDirectory *gmenu_tree_entry_get_parent (GMenuTreeEntry *entry);
const char *gmenu_tree_entry_get_desktop_file_path (GMenuTreeEntry *entry);
const char *gmenu_tree_entry_get_desktop_file_id (GMenuTreeEntry *entry);
@@ -128,8 +132,10 @@ gboolean gmenu_tree_entry_get_is_nodisplay (GMenuTreeEntry *entry);
GMenuTreeDirectory *gmenu_tree_header_get_directory (GMenuTreeHeader *header);
-GMenuTreeDirectory *gmenu_tree_alias_get_directory (GMenuTreeAlias *alias);
-GMenuTreeItem *gmenu_tree_alias_get_item (GMenuTreeAlias *alias);
+GMenuTreeDirectory *gmenu_tree_alias_get_directory (GMenuTreeAlias *alias);
+GMenuTreeItemType gmenu_tree_alias_get_item_type (GMenuTreeAlias *alias);
+GMenuTreeDirectory *gmenu_tree_alias_get_aliased_directory (GMenuTreeAlias *alias);
+GMenuTreeEntry *gmenu_tree_alias_get_aliased_entry (GMenuTreeAlias *alias);
G_END_DECLS
diff --git a/util/test-menu-spec.c b/util/test-menu-spec.c
index cb0d032..3320033 100644
--- a/util/test-menu-spec.c
+++ b/util/test-menu-spec.c
@@ -106,8 +106,7 @@ print_entry (GMenuTreeEntry *entry,
static void
print_directory (GMenuTreeDirectory *directory)
{
- GSList *items;
- GSList *tmp;
+ GMenuTreeIter *iter;
const char *path;
char *freeme;
@@ -117,34 +116,42 @@ print_directory (GMenuTreeDirectory *directory)
else
path = freeme + 1;
- items = gmenu_tree_directory_get_contents (directory);
+ iter = gmenu_tree_directory_iter (directory);
- tmp = items;
- while (tmp != NULL)
+ while (TRUE)
{
- GMenuTreeItem *item = tmp->data;
+ gpointer item;
- switch (gmenu_tree_item_get_item_type (item))
+ switch (gmenu_tree_iter_next (iter))
{
+ case GMENU_TREE_ITEM_INVALID:
+ goto done;
+
case GMENU_TREE_ITEM_ENTRY:
- print_entry (GMENU_TREE_ENTRY (item), path);
+ item = gmenu_tree_iter_get_entry (iter);
+ print_entry ((GMenuTreeEntry*)item, path);
break;
case GMENU_TREE_ITEM_DIRECTORY:
- print_directory (GMENU_TREE_DIRECTORY (item));
+ item = gmenu_tree_iter_get_directory (iter);
+ print_directory ((GMenuTreeDirectory*)item);
break;
case GMENU_TREE_ITEM_HEADER:
case GMENU_TREE_ITEM_SEPARATOR:
+ item = NULL;
break;
case GMENU_TREE_ITEM_ALIAS:
{
- GMenuTreeItem *aliased_item;
-
- aliased_item = gmenu_tree_alias_get_item (GMENU_TREE_ALIAS (item));
- if (gmenu_tree_item_get_item_type (aliased_item) == GMENU_TREE_ITEM_ENTRY)
- print_entry (GMENU_TREE_ENTRY (aliased_item), path);
+ item = gmenu_tree_iter_get_alias (iter);
+
+ if (gmenu_tree_alias_get_item_type (item) == GMENU_TREE_ITEM_ENTRY)
+ {
+ GMenuTreeEntry *entry = gmenu_tree_alias_get_aliased_entry (item);
+ print_entry (entry, path);
+ gmenu_tree_item_unref (entry);
+ }
}
break;
@@ -153,12 +160,13 @@ print_directory (GMenuTreeDirectory *directory)
break;
}
- gmenu_tree_item_unref (tmp->data);
-
- tmp = tmp->next;
+ gmenu_tree_item_unref (item);
+ continue;
+ done:
+ break;
}
- g_slist_free (items);
+ gmenu_tree_iter_unref (iter);
g_free (freeme);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]