1 /* GTS - Library for the manipulation of triangulated surfaces
2 * Copyright (C) 1999 Stéphane Popinet
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.
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.
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.
24 static void containee_class_init (GtsContaineeClass
* klass
)
26 klass
->remove_container
= NULL
;
27 klass
->add_container
= NULL
;
28 klass
->foreach
= NULL
;
29 klass
->is_contained
= NULL
;
30 klass
->replace
= NULL
;
33 GtsContaineeClass
* gts_containee_class (void)
35 static GtsContaineeClass
* klass
= NULL
;
38 GtsObjectClassInfo containee_info
= {
40 sizeof (GtsContainee
),
41 sizeof (GtsContaineeClass
),
42 (GtsObjectClassInitFunc
) containee_class_init
,
43 (GtsObjectInitFunc
) NULL
,
47 klass
= gts_object_class_new (gts_object_class (),
54 GtsContainee
* gts_containee_new (GtsContaineeClass
* klass
)
56 GtsContainee
* object
;
58 object
= GTS_CONTAINEE (gts_object_new (GTS_OBJECT_CLASS (klass
)));
63 gboolean
gts_containee_is_contained (GtsContainee
* item
,
66 g_return_val_if_fail (item
!= NULL
, FALSE
);
67 g_return_val_if_fail (c
!= NULL
, FALSE
);
69 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->is_contained
)
71 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->is_contained
)
76 void gts_containee_replace (GtsContainee
* item
,
79 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->replace
)
80 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->replace
) (item
, with
);
81 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->foreach
) {
82 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->foreach
)
83 (item
, (GtsFunc
) gts_container_add
, with
);
84 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->foreach
)
85 (item
, (GtsFunc
) gts_container_remove
, item
);
89 /* GtsSListContainee */
91 static void slist_containee_destroy (GtsObject
* object
)
93 GtsSListContainee
* item
= GTS_SLIST_CONTAINEE (object
);
98 GSList
* next
= i
->next
;
100 gts_container_remove (i
->data
, GTS_CONTAINEE (item
));
103 g_assert (item
->containers
== NULL
);
105 (* GTS_OBJECT_CLASS (gts_slist_containee_class ())->parent_class
->destroy
)
109 static void slist_containee_remove_container (GtsContainee
* i
,
112 GtsSListContainee
* item
= GTS_SLIST_CONTAINEE (i
);
113 item
->containers
= g_slist_remove (item
->containers
, c
);
116 static void slist_containee_add_container (GtsContainee
* i
,
119 GtsSListContainee
* item
= GTS_SLIST_CONTAINEE (i
);
120 if (!g_slist_find (item
->containers
, c
))
121 item
->containers
= g_slist_prepend (item
->containers
, c
);
124 static void slist_containee_foreach (GtsContainee
* c
,
128 GSList
* i
= GTS_SLIST_CONTAINEE (c
)->containers
;
131 GSList
* next
= i
->next
;
133 (* func
) (i
->data
, data
);
138 static gboolean
slist_containee_is_contained (GtsContainee
* i
,
141 return g_slist_find (GTS_SLIST_CONTAINEE (i
)->containers
, c
) ? TRUE
: FALSE
;
144 static void slist_containee_class_init (GtsSListContaineeClass
* klass
)
146 GTS_CONTAINEE_CLASS (klass
)->remove_container
=
147 slist_containee_remove_container
;
148 GTS_CONTAINEE_CLASS (klass
)->add_container
=
149 slist_containee_add_container
;
150 GTS_CONTAINEE_CLASS (klass
)->foreach
=
151 slist_containee_foreach
;
152 GTS_CONTAINEE_CLASS (klass
)->is_contained
=
153 slist_containee_is_contained
;
155 GTS_OBJECT_CLASS (klass
)->destroy
= slist_containee_destroy
;
158 static void slist_containee_init (GtsSListContainee
* object
)
160 object
->containers
= NULL
;
163 GtsSListContaineeClass
* gts_slist_containee_class (void)
165 static GtsSListContaineeClass
* klass
= NULL
;
168 GtsObjectClassInfo slist_containee_info
= {
170 sizeof (GtsSListContainee
),
171 sizeof (GtsSListContaineeClass
),
172 (GtsObjectClassInitFunc
) slist_containee_class_init
,
173 (GtsObjectInitFunc
) slist_containee_init
,
174 (GtsArgSetFunc
) NULL
,
177 klass
= gts_object_class_new (GTS_OBJECT_CLASS (gts_containee_class ()),
178 &slist_containee_info
);
186 static void remove_container (GtsContainee
* item
, GtsContainer
* c
)
188 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->remove_container
)
189 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->remove_container
)
193 static void container_destroy (GtsObject
* object
)
195 GtsContainer
* c
= GTS_CONTAINER (object
);
197 gts_container_foreach (c
, (GtsFunc
) remove_container
, c
);
199 (* GTS_OBJECT_CLASS (gts_container_class ())->parent_class
->destroy
)
203 static void container_add (GtsContainer
* c
, GtsContainee
* item
)
205 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->add_container
)
206 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->add_container
)
210 static void container_remove (GtsContainer
* c
, GtsContainee
* item
)
212 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->remove_container
)
213 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item
)->klass
)->remove_container
)
217 static void container_clone_add (GtsContainee
* item
, GtsContainer
* clone
)
219 gts_container_add (clone
, item
);
222 static void container_clone (GtsObject
* clone
, GtsObject
* object
)
224 gts_object_init (clone
, object
->klass
);
225 gts_container_foreach (GTS_CONTAINER (object
),
226 (GtsFunc
) container_clone_add
, clone
);
229 static void container_class_init (GtsContainerClass
* klass
)
231 klass
->add
= container_add
;
232 klass
->remove
= container_remove
;
233 klass
->foreach
= NULL
;
236 GTS_OBJECT_CLASS (klass
)->destroy
= container_destroy
;
237 GTS_OBJECT_CLASS (klass
)->clone
= container_clone
;
240 GtsContainerClass
* gts_container_class (void)
242 static GtsContainerClass
* klass
= NULL
;
245 GtsObjectClassInfo container_info
= {
247 sizeof (GtsContainer
),
248 sizeof (GtsContainerClass
),
249 (GtsObjectClassInitFunc
) container_class_init
,
250 (GtsObjectInitFunc
) NULL
,
251 (GtsArgSetFunc
) NULL
,
255 gts_object_class_new (GTS_OBJECT_CLASS (gts_slist_containee_class ()),
262 GtsContainer
* gts_container_new (GtsContainerClass
* klass
)
264 GtsContainer
* object
;
266 object
= GTS_CONTAINER (gts_object_new (GTS_OBJECT_CLASS (klass
)));
271 void gts_container_add (GtsContainer
* c
,
274 g_return_if_fail (c
!= NULL
);
275 g_return_if_fail (item
!= NULL
);
277 g_assert (GTS_CONTAINER_CLASS (GTS_OBJECT (c
)->klass
)->add
);
278 (* GTS_CONTAINER_CLASS (GTS_OBJECT (c
)->klass
)->add
) (c
, item
);
281 void gts_container_remove (GtsContainer
* c
,
284 g_return_if_fail (c
!= NULL
);
285 g_return_if_fail (item
!= NULL
);
287 g_assert (GTS_CONTAINER_CLASS (GTS_OBJECT (c
)->klass
)->remove
);
288 (* GTS_CONTAINER_CLASS (GTS_OBJECT (c
)->klass
)->remove
) (c
, item
);
291 void gts_container_foreach (GtsContainer
* c
,
295 g_return_if_fail (c
!= NULL
);
296 g_return_if_fail (func
!= NULL
);
298 if (GTS_CONTAINER_CLASS (GTS_OBJECT (c
)->klass
)->foreach
)
299 (* GTS_CONTAINER_CLASS (GTS_OBJECT (c
)->klass
)->foreach
) (c
, func
, data
);
302 guint
gts_container_size (GtsContainer
* c
)
304 g_return_val_if_fail (c
!= NULL
, 0);
306 if (GTS_CONTAINER_CLASS (GTS_OBJECT (c
)->klass
)->size
)
307 return (* GTS_CONTAINER_CLASS (GTS_OBJECT (c
)->klass
)->size
) (c
);
311 /* GtsHashContainer */
313 static void hash_container_destroy (GtsObject
* object
)
315 GHashTable
* items
= GTS_HASH_CONTAINER (object
)->items
;
317 (* GTS_OBJECT_CLASS (gts_hash_container_class ())->parent_class
->destroy
)
320 g_hash_table_destroy (items
);
323 static void hash_container_add (GtsContainer
* c
, GtsContainee
* item
)
325 g_return_if_fail (GTS_HASH_CONTAINER (c
)->frozen
== FALSE
);
327 g_hash_table_insert (GTS_HASH_CONTAINER (c
)->items
, item
, NULL
);
329 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_hash_container_class ())->parent_class
)->add
) (c
, item
);
332 static void hash_container_remove (GtsContainer
* c
, GtsContainee
* item
)
334 g_return_if_fail (GTS_HASH_CONTAINER (c
)->frozen
== FALSE
);
336 g_hash_table_remove (GTS_HASH_CONTAINER (c
)->items
, item
);
338 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_hash_container_class ())->parent_class
)->remove
) (c
, item
);
341 static void hash_foreach (GtsContainee
* item
,
345 (* ((GtsFunc
) info
[0])) (item
, info
[1]);
348 static void hash_container_foreach (GtsContainer
* c
,
356 /* prevent removing or adding items */
357 GTS_HASH_CONTAINER (c
)->frozen
= TRUE
;
358 g_hash_table_foreach (GTS_HASH_CONTAINER (c
)->items
,
359 (GHFunc
) hash_foreach
, info
);
360 GTS_HASH_CONTAINER (c
)->frozen
= FALSE
;
363 static guint
hash_container_size (GtsContainer
* c
)
365 return g_hash_table_size (GTS_HASH_CONTAINER (c
)->items
);
368 static void hash_container_class_init (GtsHashContainerClass
* klass
)
370 GTS_CONTAINER_CLASS (klass
)->add
= hash_container_add
;
371 GTS_CONTAINER_CLASS (klass
)->remove
= hash_container_remove
;
372 GTS_CONTAINER_CLASS (klass
)->foreach
= hash_container_foreach
;
373 GTS_CONTAINER_CLASS (klass
)->size
= hash_container_size
;
375 GTS_OBJECT_CLASS (klass
)->destroy
= hash_container_destroy
;
378 static void hash_container_init (GtsHashContainer
* object
)
380 object
->items
= g_hash_table_new (NULL
, NULL
);
381 object
->frozen
= FALSE
;
384 GtsHashContainerClass
* gts_hash_container_class (void)
386 static GtsHashContainerClass
* klass
= NULL
;
389 GtsObjectClassInfo hash_container_info
= {
391 sizeof (GtsHashContainer
),
392 sizeof (GtsHashContainerClass
),
393 (GtsObjectClassInitFunc
) hash_container_class_init
,
394 (GtsObjectInitFunc
) hash_container_init
,
395 (GtsArgSetFunc
) NULL
,
398 klass
= gts_object_class_new (GTS_OBJECT_CLASS (gts_container_class ()),
399 &hash_container_info
);
405 /* GtsSListContainer */
407 static void slist_container_destroy (GtsObject
* object
)
409 GSList
* items
= GTS_SLIST_CONTAINER (object
)->items
;
411 (* GTS_OBJECT_CLASS (gts_slist_container_class ())->parent_class
->destroy
)
414 g_slist_free (items
);
417 static void slist_container_add (GtsContainer
* c
, GtsContainee
* item
)
419 g_return_if_fail (GTS_SLIST_CONTAINER (c
)->frozen
== FALSE
);
421 if (!g_slist_find (GTS_SLIST_CONTAINER (c
)->items
, item
))
422 GTS_SLIST_CONTAINER (c
)->items
=
423 g_slist_prepend (GTS_SLIST_CONTAINER (c
)->items
, item
);
425 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_slist_container_class ())->parent_class
)->add
) (c
, item
);
428 static void slist_container_remove (GtsContainer
* c
, GtsContainee
* item
)
430 g_return_if_fail (GTS_SLIST_CONTAINER (c
)->frozen
== FALSE
);
432 GTS_SLIST_CONTAINER (c
)->items
=
433 g_slist_remove (GTS_SLIST_CONTAINER (c
)->items
, item
);
435 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_slist_container_class ())->parent_class
)->remove
) (c
, item
);
438 static void slist_container_foreach (GtsContainer
* c
,
444 i
= GTS_SLIST_CONTAINER (c
)->items
;
446 GSList
* next
= i
->next
;
448 (* func
) (i
->data
, data
);
453 static guint
slist_container_size (GtsContainer
* c
)
455 return g_slist_length (GTS_SLIST_CONTAINER (c
)->items
);
458 static void slist_container_class_init (GtsSListContainerClass
* klass
)
460 GTS_CONTAINER_CLASS (klass
)->add
= slist_container_add
;
461 GTS_CONTAINER_CLASS (klass
)->remove
= slist_container_remove
;
462 GTS_CONTAINER_CLASS (klass
)->foreach
= slist_container_foreach
;
463 GTS_CONTAINER_CLASS (klass
)->size
= slist_container_size
;
465 GTS_OBJECT_CLASS (klass
)->destroy
= slist_container_destroy
;
468 static void slist_container_init (GtsSListContainer
* object
)
470 object
->items
= NULL
;
471 object
->frozen
= FALSE
;
474 GtsSListContainerClass
* gts_slist_container_class (void)
476 static GtsSListContainerClass
* klass
= NULL
;
479 GtsObjectClassInfo slist_container_info
= {
481 sizeof (GtsSListContainer
),
482 sizeof (GtsSListContainerClass
),
483 (GtsObjectClassInitFunc
) slist_container_class_init
,
484 (GtsObjectInitFunc
) slist_container_init
,
485 (GtsArgSetFunc
) NULL
,
488 klass
= gts_object_class_new (GTS_OBJECT_CLASS (gts_container_class ()),
489 &slist_container_info
);