[gtk+] Add GtkTreeModelRefCount, only to be used in unit tests
- From: Kristian Rietveld <kristian src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] Add GtkTreeModelRefCount, only to be used in unit tests
- Date: Mon, 22 Aug 2011 19:41:28 +0000 (UTC)
commit 1cb14a16b761a8a415b9271233d938ffdbd7ddeb
Author: Kristian Rietveld <kris gtk org>
Date: Sat May 28 16:41:49 2011 +0200
Add GtkTreeModelRefCount, only to be used in unit tests
gtk/tests/gtktreemodelrefcount.c | 273 ++++++++++++++++++++++++++++++++++++++
gtk/tests/gtktreemodelrefcount.h | 65 +++++++++
2 files changed, 338 insertions(+), 0 deletions(-)
---
diff --git a/gtk/tests/gtktreemodelrefcount.c b/gtk/tests/gtktreemodelrefcount.c
new file mode 100644
index 0000000..b494540
--- /dev/null
+++ b/gtk/tests/gtktreemodelrefcount.c
@@ -0,0 +1,273 @@
+/* gtktreemodelrefcount.c
+ * Copyright (C) 2011 Kristian Rietveld <kris gtk org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "gtktreemodelrefcount.h"
+
+
+/* The purpose of this GtkTreeModel is to keep record of the reference count
+ * of each node. The reference count does not effect the functioning of
+ * the model in any way. Because this model is a subclass of GtkTreeStore,
+ * the GtkTreeStore API should be used to add to and remove nodes from
+ * this model. We depend on the iter format of GtkTreeStore, which means
+ * that this model needs to be revised in case the iter format of
+ * GtkTreeStore is modified. Currently, we make use of the fact that
+ * the value stored in the user_data field is unique for each node.
+ */
+
+struct _GtkTreeModelRefCountPrivate
+{
+ GHashTable *node_hash;
+};
+
+typedef struct
+{
+ int ref_count;
+}
+NodeInfo;
+
+
+static void gtk_tree_model_ref_count_tree_model_init (GtkTreeModelIface *iface);
+static void gtk_tree_model_ref_count_finalize (GObject *object);
+
+static NodeInfo *node_info_new (void);
+static void node_info_free (NodeInfo *info);
+
+/* GtkTreeModel interface */
+static void gtk_tree_model_ref_count_ref_node (GtkTreeModel *model,
+ GtkTreeIter *iter);
+static void gtk_tree_model_ref_count_unref_node (GtkTreeModel *model,
+ GtkTreeIter *iter);
+
+
+G_DEFINE_TYPE_WITH_CODE (GtkTreeModelRefCount, gtk_tree_model_ref_count, GTK_TYPE_TREE_STORE,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
+ gtk_tree_model_ref_count_tree_model_init))
+
+static void
+gtk_tree_model_ref_count_init (GtkTreeModelRefCount *ref_model)
+{
+ ref_model->priv = G_TYPE_INSTANCE_GET_PRIVATE (ref_model,
+ GTK_TYPE_TREE_MODEL_REF_COUNT,
+ GtkTreeModelRefCountPrivate);
+
+ ref_model->priv->node_hash = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ NULL,
+ (GDestroyNotify)node_info_free);
+}
+
+static void
+gtk_tree_model_ref_count_class_init (GtkTreeModelRefCountClass *ref_model_class)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) ref_model_class;
+
+ object_class->finalize = gtk_tree_model_ref_count_finalize;
+
+ g_type_class_add_private (object_class, sizeof (GtkTreeModelRefCountPrivate));
+}
+
+static void
+gtk_tree_model_ref_count_tree_model_init (GtkTreeModelIface *iface)
+{
+ iface->ref_node = gtk_tree_model_ref_count_ref_node;
+ iface->unref_node = gtk_tree_model_ref_count_unref_node;
+}
+
+static void
+gtk_tree_model_ref_count_finalize (GObject *object)
+{
+ GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (object);
+
+ if (ref_model->priv->node_hash)
+ {
+ g_hash_table_destroy (ref_model->priv->node_hash);
+ ref_model->priv->node_hash = NULL;
+ }
+
+ G_OBJECT_CLASS (gtk_tree_model_ref_count_parent_class)->finalize (object);
+}
+
+
+static NodeInfo *
+node_info_new (void)
+{
+ NodeInfo *info = g_slice_new (NodeInfo);
+ info->ref_count = 0;
+
+ return info;
+}
+
+static void
+node_info_free (NodeInfo *info)
+{
+ g_slice_free (NodeInfo, info);
+}
+
+static void
+gtk_tree_model_ref_count_ref_node (GtkTreeModel *model,
+ GtkTreeIter *iter)
+{
+ NodeInfo *info;
+ GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+ info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
+ if (!info)
+ {
+ info = node_info_new ();
+
+ g_hash_table_insert (ref_model->priv->node_hash, iter->user_data, info);
+ }
+
+ info->ref_count++;
+}
+
+static void
+gtk_tree_model_ref_count_unref_node (GtkTreeModel *model,
+ GtkTreeIter *iter)
+{
+ NodeInfo *info;
+ GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+ info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
+ g_assert (info != NULL);
+ g_assert (info->ref_count > 0);
+
+ info->ref_count--;
+}
+
+
+GtkTreeModel *
+gtk_tree_model_ref_count_new (void)
+{
+ GtkTreeModel *retval;
+
+ retval = g_object_new (gtk_tree_model_ref_count_get_type (), NULL);
+
+ return retval;
+}
+
+static void
+dump_iter (GtkTreeModelRefCount *ref_model,
+ GtkTreeIter *iter)
+{
+ gchar *path_str;
+ NodeInfo *info;
+ GtkTreePath *path;
+
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (ref_model), iter);
+ path_str = gtk_tree_path_to_string (path);
+ gtk_tree_path_free (path);
+
+ info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
+ if (!info)
+ g_print ("%-16s ref_count=0\n", path_str);
+ else
+ g_print ("%-16s ref_count=%d\n", path_str, info->ref_count);
+
+ g_free (path_str);
+}
+
+static void
+gtk_tree_model_ref_count_dump_recurse (GtkTreeModelRefCount *ref_model,
+ GtkTreeIter *iter)
+{
+ do
+ {
+ GtkTreeIter child;
+
+ dump_iter (ref_model, iter);
+
+ if (gtk_tree_model_iter_children (GTK_TREE_MODEL (ref_model),
+ &child, iter))
+ gtk_tree_model_ref_count_dump_recurse (ref_model, &child);
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ref_model), iter));
+}
+
+void
+gtk_tree_model_ref_count_dump (GtkTreeModelRefCount *ref_model)
+{
+ GtkTreeIter iter;
+
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ref_model), &iter))
+ return;
+
+ gtk_tree_model_ref_count_dump_recurse (ref_model, &iter);
+}
+
+static gboolean
+check_iter (GtkTreeModelRefCount *ref_model,
+ GtkTreeIter *iter,
+ gint expected_ref_count)
+{
+ NodeInfo *info;
+
+ info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
+ if (!info)
+ {
+ if (expected_ref_count == 0)
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ return expected_ref_count == info->ref_count;
+}
+
+gboolean
+gtk_tree_model_ref_count_check_level (GtkTreeModelRefCount *ref_model,
+ GtkTreeIter *parent,
+ gint expected_ref_count,
+ gboolean recurse)
+{
+ GtkTreeIter iter;
+
+ if (!gtk_tree_model_iter_children (GTK_TREE_MODEL (ref_model),
+ &iter, parent))
+ return TRUE;
+
+ do
+ {
+ if (!check_iter (ref_model, &iter, expected_ref_count))
+ return FALSE;
+
+ if (recurse &&
+ gtk_tree_model_iter_has_child (GTK_TREE_MODEL (ref_model), &iter))
+ {
+ if (!gtk_tree_model_ref_count_check_level (ref_model, &iter,
+ expected_ref_count,
+ recurse))
+ return FALSE;
+ }
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ref_model), &iter));
+
+ return TRUE;
+}
+
+gboolean
+gtk_tree_model_ref_count_check_node (GtkTreeModelRefCount *ref_model,
+ GtkTreeIter *iter,
+ gint expected_ref_count)
+{
+ return check_iter (ref_model, iter, expected_ref_count);
+}
diff --git a/gtk/tests/gtktreemodelrefcount.h b/gtk/tests/gtktreemodelrefcount.h
new file mode 100644
index 0000000..c8c8e89
--- /dev/null
+++ b/gtk/tests/gtktreemodelrefcount.h
@@ -0,0 +1,65 @@
+/* gtktreemodelrefcount.h
+ * Copyright (C) 2011 Kristian Rietveld <kris gtk org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_TREE_MODEL_REF_COUNT_H__
+#define __GTK_TREE_MODEL_REF_COUNT_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_TREE_MODEL_REF_COUNT (gtk_tree_model_ref_count_get_type ())
+#define GTK_TREE_MODEL_REF_COUNT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCount))
+#define GTK_TREE_MODEL_REF_COUNT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCountClass))
+#define GTK_IS_TREE_MODEL_REF_COUNT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT))
+#define GTK_IS_TREE_MODEL_REF_COUNT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), GTK_TYPE_TREE_MODEL_REF_COUNT))
+#define GTK_TREE_MODEL_REF_COUNT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCountClass))
+
+
+typedef struct _GtkTreeModelRefCount GtkTreeModelRefCount;
+typedef struct _GtkTreeModelRefCountClass GtkTreeModelRefCountClass;
+typedef struct _GtkTreeModelRefCountPrivate GtkTreeModelRefCountPrivate;
+
+struct _GtkTreeModelRefCount
+{
+ GtkTreeStore parent;
+
+ /* < private > */
+ GtkTreeModelRefCountPrivate *priv;
+};
+
+struct _GtkTreeModelRefCountClass
+{
+ GtkTreeStoreClass parent_class;
+};
+
+
+GType gtk_tree_model_ref_count_get_type (void) G_GNUC_CONST;
+GtkTreeModel *gtk_tree_model_ref_count_new (void);
+
+void gtk_tree_model_ref_count_dump (GtkTreeModelRefCount *ref_model);
+gboolean gtk_tree_model_ref_count_check_level (GtkTreeModelRefCount *ref_model,
+ GtkTreeIter *parent,
+ gint expected_ref_count,
+ gboolean recurse);
+gboolean gtk_tree_model_ref_count_check_node (GtkTreeModelRefCount *ref_model,
+ GtkTreeIter *iter,
+ gint expected_ref_count);
+
+#endif /* __GTK_TREE_MODEL_REF_COUNT_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]