]> Pileus Git - ~andy/gtk/blob - gtk/gtktreedatalist.c
Got rid of GtkTreeNode, and changed it to GtkTreeIter. Added iterators
[~andy/gtk] / gtk / gtktreedatalist.c
1 /* gtktreedatalist.h
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "gtktreedatalist.h"
21 #include "gobject/gvalue.h"
22 #include "gobject/gvaluetypes.h"
23
24 /* node allocation
25  */
26 struct _GAllocator /* from gmem.c */
27 {
28   gchar           *name;
29   guint16          n_preallocs;
30   guint            is_unused : 1;
31   guint            type : 4;
32   GAllocator      *last;
33   GMemChunk       *mem_chunk;
34   GtkTreeDataList *free_nodes;
35 };
36
37
38 G_LOCK_DEFINE_STATIC (current_allocator);
39 static GAllocator *current_allocator = NULL;
40
41 /* HOLDS: current_allocator_lock */
42 static void
43 gtk_tree_data_list_validate_allocator (GAllocator *allocator)
44 {
45   g_return_if_fail (allocator != NULL);
46   g_return_if_fail (allocator->is_unused == TRUE);
47
48   if (allocator->type != G_ALLOCATOR_NODE)
49     {
50       allocator->type = G_ALLOCATOR_NODE;
51       if (allocator->mem_chunk)
52         {
53           g_mem_chunk_destroy (allocator->mem_chunk);
54           allocator->mem_chunk = NULL;
55         }
56     }
57
58   if (!allocator->mem_chunk)
59     {
60       allocator->mem_chunk = g_mem_chunk_new (allocator->name,
61                                               sizeof (GtkTreeDataList),
62                                               sizeof (GtkTreeDataList) * allocator->n_preallocs,
63                                               G_ALLOC_ONLY);
64       allocator->free_nodes = NULL;
65     }
66
67   allocator->is_unused = FALSE;
68 }
69
70 void
71 gtk_tree_data_list_push_allocator (GAllocator *allocator)
72 {
73   G_LOCK (current_allocator);
74   gtk_tree_data_list_validate_allocator ( allocator );
75   allocator->last = current_allocator;
76   current_allocator = allocator;
77   G_UNLOCK (current_allocator);
78 }
79
80 void
81 gtk_tree_data_list_pop_allocator (void)
82 {
83   G_LOCK (current_allocator);
84   if (current_allocator)
85     {
86       GAllocator *allocator;
87
88       allocator = current_allocator;
89       current_allocator = allocator->last;
90       allocator->last = NULL;
91       allocator->is_unused = TRUE;
92     }
93   G_UNLOCK (current_allocator);
94 }
95
96 GtkTreeDataList *
97 gtk_tree_data_list_alloc (void)
98 {
99   GtkTreeDataList *list;
100
101   G_LOCK (current_allocator);
102   if (!current_allocator)
103     {
104        GAllocator *allocator = g_allocator_new ("GTK+ default GtkTreeDataList allocator",
105                                                 128);
106        gtk_tree_data_list_validate_allocator (allocator);
107        allocator->last = NULL;
108        current_allocator = allocator;
109     }
110   if (!current_allocator->free_nodes)
111     list = g_chunk_new (GtkTreeDataList, current_allocator->mem_chunk);
112   else
113     {
114       list = current_allocator->free_nodes;
115       current_allocator->free_nodes = list->next;
116     }
117   G_UNLOCK (current_allocator);
118
119   return list;
120 }
121
122 void
123 gtk_tree_data_list_free (GtkTreeDataList *list)
124 {
125   G_LOCK (current_allocator);
126   list->next = current_allocator->free_nodes;
127   current_allocator->free_nodes = list;
128   G_UNLOCK (current_allocator);
129 }
130
131 void
132 gtk_tree_data_list_node_to_value (GtkTreeDataList *list,
133                                   GType            type,
134                                   GValue          *value)
135 {
136   g_value_init (value, type);
137
138   switch (type)
139     {
140     case G_TYPE_BOOLEAN:
141       g_value_set_boolean (value, (gboolean) list->data.v_int);
142       break;
143     case G_TYPE_CHAR:
144       g_value_set_char (value, list->data.v_char);
145       break;
146     case G_TYPE_UCHAR:
147       g_value_set_uchar (value, list->data.v_uchar);
148       break;
149     case G_TYPE_INT:
150       g_value_set_int (value, list->data.v_int);
151       break;
152     case G_TYPE_UINT:
153       g_value_set_uint (value, list->data.v_uint);
154       break;
155     case G_TYPE_POINTER:
156       g_value_set_pointer (value, (gpointer) list->data.v_pointer);
157       break;
158     case G_TYPE_FLOAT:
159       g_value_set_float (value, list->data.v_float);
160       break;
161     case G_TYPE_STRING:
162       g_value_set_string (value, (gchar *) list->data.v_pointer);
163       break;
164     case G_TYPE_OBJECT:
165       g_value_set_object (value, (GObject *) list->data.v_pointer);
166       break;
167     default:
168       g_warning ("Unsupported type (%s) retrieved.", g_type_name (value->g_type));
169       return;
170     }
171 }
172
173 void
174 gtk_tree_data_list_value_to_node (GtkTreeDataList *list,
175                                   GValue          *value)
176 {
177   switch (value->g_type)
178     {
179     case G_TYPE_BOOLEAN:
180       list->data.v_int = g_value_get_boolean (value);
181       break;
182     case G_TYPE_CHAR:
183       list->data.v_char = g_value_get_char (value);
184       break;
185     case G_TYPE_UCHAR:
186       list->data.v_uchar = g_value_get_uchar (value);
187       break;
188     case G_TYPE_INT:
189       list->data.v_int = g_value_get_int (value);
190       break;
191     case G_TYPE_UINT:
192       list->data.v_uint = g_value_get_uint (value);
193       break;
194     case G_TYPE_POINTER:
195       list->data.v_pointer = g_value_get_pointer (value);
196       break;
197     case G_TYPE_FLOAT:
198       list->data.v_float = g_value_get_float (value);
199       break;
200     case G_TYPE_STRING:
201       list->data.v_pointer = g_value_dup_string (value);
202       break;
203     case G_TYPE_OBJECT:
204       list->data.v_pointer = g_value_dup_object (value);
205       break;
206     default:
207       g_warning ("Unsupported type (%s) stored.", g_type_name (value->g_type));
208       return;
209     }
210 }
211
212