pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 /* GTS - Library for the manipulation of triangulated surfaces 00002 * Copyright (C) 1999 Stéphane Popinet 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Library General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Library General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Library General Public 00015 * License along with this library; if not, write to the 00016 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 * Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include "gts.h" 00021 00022 /* GtsContainee */ 00023 00024 static void containee_class_init (GtsContaineeClass * klass) 00025 { 00026 klass->remove_container = NULL; 00027 klass->add_container = NULL; 00028 klass->foreach = NULL; 00029 klass->is_contained = NULL; 00030 klass->replace = NULL; 00031 } 00032 00033 GtsContaineeClass * gts_containee_class (void) 00034 { 00035 static GtsContaineeClass * klass = NULL; 00036 00037 if (klass == NULL) { 00038 GtsObjectClassInfo containee_info = { 00039 "GtsContainee", 00040 sizeof (GtsContainee), 00041 sizeof (GtsContaineeClass), 00042 (GtsObjectClassInitFunc) containee_class_init, 00043 (GtsObjectInitFunc) NULL, 00044 (GtsArgSetFunc) NULL, 00045 (GtsArgGetFunc) NULL 00046 }; 00047 klass = gts_object_class_new (gts_object_class (), 00048 &containee_info); 00049 } 00050 00051 return klass; 00052 } 00053 00054 GtsContainee * gts_containee_new (GtsContaineeClass * klass) 00055 { 00056 GtsContainee * object; 00057 00058 object = GTS_CONTAINEE (gts_object_new (GTS_OBJECT_CLASS (klass))); 00059 00060 return object; 00061 } 00062 00063 gboolean gts_containee_is_contained (GtsContainee * item, 00064 GtsContainer * c) 00065 { 00066 g_return_val_if_fail (item != NULL, FALSE); 00067 g_return_val_if_fail (c != NULL, FALSE); 00068 00069 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->is_contained) 00070 return 00071 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->is_contained) 00072 (item, c); 00073 return FALSE; 00074 } 00075 00076 void gts_containee_replace (GtsContainee * item, 00077 GtsContainee * with) 00078 { 00079 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->replace) 00080 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->replace) (item, with); 00081 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->foreach) { 00082 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->foreach) 00083 (item, (GtsFunc) gts_container_add, with); 00084 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->foreach) 00085 (item, (GtsFunc) gts_container_remove, item); 00086 } 00087 } 00088 00089 /* GtsSListContainee */ 00090 00091 static void slist_containee_destroy (GtsObject * object) 00092 { 00093 GtsSListContainee * item = GTS_SLIST_CONTAINEE (object); 00094 GSList * i; 00095 00096 i = item->containers; 00097 while (i) { 00098 GSList * next = i->next; 00099 00100 gts_container_remove (i->data, GTS_CONTAINEE (item)); 00101 i = next; 00102 } 00103 g_assert (item->containers == NULL); 00104 00105 (* GTS_OBJECT_CLASS (gts_slist_containee_class ())->parent_class->destroy) 00106 (object); 00107 } 00108 00109 static void slist_containee_remove_container (GtsContainee * i, 00110 GtsContainer * c) 00111 { 00112 GtsSListContainee * item = GTS_SLIST_CONTAINEE (i); 00113 item->containers = g_slist_remove (item->containers, c); 00114 } 00115 00116 static void slist_containee_add_container (GtsContainee * i, 00117 GtsContainer * c) 00118 { 00119 GtsSListContainee * item = GTS_SLIST_CONTAINEE (i); 00120 if (!g_slist_find (item->containers, c)) 00121 item->containers = g_slist_prepend (item->containers, c); 00122 } 00123 00124 static void slist_containee_foreach (GtsContainee * c, 00125 GtsFunc func, 00126 gpointer data) 00127 { 00128 GSList * i = GTS_SLIST_CONTAINEE (c)->containers; 00129 00130 while (i) { 00131 GSList * next = i->next; 00132 00133 (* func) (i->data, data); 00134 i = next; 00135 } 00136 } 00137 00138 static gboolean slist_containee_is_contained (GtsContainee * i, 00139 GtsContainer * c) 00140 { 00141 return g_slist_find (GTS_SLIST_CONTAINEE (i)->containers, c) ? TRUE : FALSE; 00142 } 00143 00144 static void slist_containee_class_init (GtsSListContaineeClass * klass) 00145 { 00146 GTS_CONTAINEE_CLASS (klass)->remove_container = 00147 slist_containee_remove_container; 00148 GTS_CONTAINEE_CLASS (klass)->add_container = 00149 slist_containee_add_container; 00150 GTS_CONTAINEE_CLASS (klass)->foreach = 00151 slist_containee_foreach; 00152 GTS_CONTAINEE_CLASS (klass)->is_contained = 00153 slist_containee_is_contained; 00154 00155 GTS_OBJECT_CLASS (klass)->destroy = slist_containee_destroy; 00156 } 00157 00158 static void slist_containee_init (GtsSListContainee * object) 00159 { 00160 object->containers = NULL; 00161 } 00162 00163 GtsSListContaineeClass * gts_slist_containee_class (void) 00164 { 00165 static GtsSListContaineeClass * klass = NULL; 00166 00167 if (klass == NULL) { 00168 GtsObjectClassInfo slist_containee_info = { 00169 "GtsSListContainee", 00170 sizeof (GtsSListContainee), 00171 sizeof (GtsSListContaineeClass), 00172 (GtsObjectClassInitFunc) slist_containee_class_init, 00173 (GtsObjectInitFunc) slist_containee_init, 00174 (GtsArgSetFunc) NULL, 00175 (GtsArgGetFunc) NULL 00176 }; 00177 klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_containee_class ()), 00178 &slist_containee_info); 00179 } 00180 00181 return klass; 00182 } 00183 00184 /* GtsContainer */ 00185 00186 static void remove_container (GtsContainee * item, GtsContainer * c) 00187 { 00188 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->remove_container) 00189 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->remove_container) 00190 (item, c); 00191 } 00192 00193 static void container_destroy (GtsObject * object) 00194 { 00195 GtsContainer * c = GTS_CONTAINER (object); 00196 00197 gts_container_foreach (c, (GtsFunc) remove_container, c); 00198 00199 (* GTS_OBJECT_CLASS (gts_container_class ())->parent_class->destroy) 00200 (object); 00201 } 00202 00203 static void container_add (GtsContainer * c, GtsContainee * item) 00204 { 00205 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->add_container) 00206 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->add_container) 00207 (item, c); 00208 } 00209 00210 static void container_remove (GtsContainer * c, GtsContainee * item) 00211 { 00212 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->remove_container) 00213 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->remove_container) 00214 (item, c); 00215 } 00216 00217 static void container_clone_add (GtsContainee * item, GtsContainer * clone) 00218 { 00219 gts_container_add (clone, item); 00220 } 00221 00222 static void container_clone (GtsObject * clone, GtsObject * object) 00223 { 00224 gts_object_init (clone, object->klass); 00225 gts_container_foreach (GTS_CONTAINER (object), 00226 (GtsFunc) container_clone_add, clone); 00227 } 00228 00229 static void container_class_init (GtsContainerClass * klass) 00230 { 00231 klass->add = container_add; 00232 klass->remove = container_remove; 00233 klass->foreach = NULL; 00234 klass->size = NULL; 00235 00236 GTS_OBJECT_CLASS (klass)->destroy = container_destroy; 00237 GTS_OBJECT_CLASS (klass)->clone = container_clone; 00238 } 00239 00240 GtsContainerClass * gts_container_class (void) 00241 { 00242 static GtsContainerClass * klass = NULL; 00243 00244 if (klass == NULL) { 00245 GtsObjectClassInfo container_info = { 00246 "GtsContainer", 00247 sizeof (GtsContainer), 00248 sizeof (GtsContainerClass), 00249 (GtsObjectClassInitFunc) container_class_init, 00250 (GtsObjectInitFunc) NULL, 00251 (GtsArgSetFunc) NULL, 00252 (GtsArgGetFunc) NULL 00253 }; 00254 klass = 00255 gts_object_class_new (GTS_OBJECT_CLASS (gts_slist_containee_class ()), 00256 &container_info); 00257 } 00258 00259 return klass; 00260 } 00261 00262 GtsContainer * gts_container_new (GtsContainerClass * klass) 00263 { 00264 GtsContainer * object; 00265 00266 object = GTS_CONTAINER (gts_object_new (GTS_OBJECT_CLASS (klass))); 00267 00268 return object; 00269 } 00270 00271 void gts_container_add (GtsContainer * c, 00272 GtsContainee * item) 00273 { 00274 g_return_if_fail (c != NULL); 00275 g_return_if_fail (item != NULL); 00276 00277 g_assert (GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->add); 00278 (* GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->add) (c, item); 00279 } 00280 00281 void gts_container_remove (GtsContainer * c, 00282 GtsContainee * item) 00283 { 00284 g_return_if_fail (c != NULL); 00285 g_return_if_fail (item != NULL); 00286 00287 g_assert (GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->remove); 00288 (* GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->remove) (c, item); 00289 } 00290 00291 void gts_container_foreach (GtsContainer * c, 00292 GtsFunc func, 00293 gpointer data) 00294 { 00295 g_return_if_fail (c != NULL); 00296 g_return_if_fail (func != NULL); 00297 00298 if (GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->foreach) 00299 (* GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->foreach) (c, func, data); 00300 } 00301 00302 guint gts_container_size (GtsContainer * c) 00303 { 00304 g_return_val_if_fail (c != NULL, 0); 00305 00306 if (GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->size) 00307 return (* GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->size) (c); 00308 return 0; 00309 } 00310 00311 /* GtsHashContainer */ 00312 00313 static void hash_container_destroy (GtsObject * object) 00314 { 00315 GHashTable * items = GTS_HASH_CONTAINER (object)->items; 00316 00317 (* GTS_OBJECT_CLASS (gts_hash_container_class ())->parent_class->destroy) 00318 (object); 00319 00320 g_hash_table_destroy (items); 00321 } 00322 00323 static void hash_container_add (GtsContainer * c, GtsContainee * item) 00324 { 00325 g_return_if_fail (GTS_HASH_CONTAINER (c)->frozen == FALSE); 00326 00327 g_hash_table_insert (GTS_HASH_CONTAINER (c)->items, item, NULL); 00328 00329 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_hash_container_class ())->parent_class)->add) (c, item); 00330 } 00331 00332 static void hash_container_remove (GtsContainer * c, GtsContainee * item) 00333 { 00334 g_return_if_fail (GTS_HASH_CONTAINER (c)->frozen == FALSE); 00335 00336 g_hash_table_remove (GTS_HASH_CONTAINER (c)->items, item); 00337 00338 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_hash_container_class ())->parent_class)->remove) (c, item); 00339 } 00340 00341 static void hash_foreach (GtsContainee * item, 00342 gpointer item_data, 00343 gpointer * info) 00344 { 00345 (* ((GtsFunc) info[0])) (item, info[1]); 00346 } 00347 00348 static void hash_container_foreach (GtsContainer * c, 00349 GtsFunc func, 00350 gpointer data) 00351 { 00352 gpointer info[2]; 00353 00354 info[0] = func; 00355 info[1] = data; 00356 /* prevent removing or adding items */ 00357 GTS_HASH_CONTAINER (c)->frozen = TRUE; 00358 g_hash_table_foreach (GTS_HASH_CONTAINER (c)->items, 00359 (GHFunc) hash_foreach, info); 00360 GTS_HASH_CONTAINER (c)->frozen = FALSE; 00361 } 00362 00363 static guint hash_container_size (GtsContainer * c) 00364 { 00365 return g_hash_table_size (GTS_HASH_CONTAINER (c)->items); 00366 } 00367 00368 static void hash_container_class_init (GtsHashContainerClass * klass) 00369 { 00370 GTS_CONTAINER_CLASS (klass)->add = hash_container_add; 00371 GTS_CONTAINER_CLASS (klass)->remove = hash_container_remove; 00372 GTS_CONTAINER_CLASS (klass)->foreach = hash_container_foreach; 00373 GTS_CONTAINER_CLASS (klass)->size = hash_container_size; 00374 00375 GTS_OBJECT_CLASS (klass)->destroy = hash_container_destroy; 00376 } 00377 00378 static void hash_container_init (GtsHashContainer * object) 00379 { 00380 object->items = g_hash_table_new (NULL, NULL); 00381 object->frozen = FALSE; 00382 } 00383 00384 GtsHashContainerClass * gts_hash_container_class (void) 00385 { 00386 static GtsHashContainerClass * klass = NULL; 00387 00388 if (klass == NULL) { 00389 GtsObjectClassInfo hash_container_info = { 00390 "GtsHashContainer", 00391 sizeof (GtsHashContainer), 00392 sizeof (GtsHashContainerClass), 00393 (GtsObjectClassInitFunc) hash_container_class_init, 00394 (GtsObjectInitFunc) hash_container_init, 00395 (GtsArgSetFunc) NULL, 00396 (GtsArgGetFunc) NULL 00397 }; 00398 klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_container_class ()), 00399 &hash_container_info); 00400 } 00401 00402 return klass; 00403 } 00404 00405 /* GtsSListContainer */ 00406 00407 static void slist_container_destroy (GtsObject * object) 00408 { 00409 GSList * items = GTS_SLIST_CONTAINER (object)->items; 00410 00411 (* GTS_OBJECT_CLASS (gts_slist_container_class ())->parent_class->destroy) 00412 (object); 00413 00414 g_slist_free (items); 00415 } 00416 00417 static void slist_container_add (GtsContainer * c, GtsContainee * item) 00418 { 00419 g_return_if_fail (GTS_SLIST_CONTAINER (c)->frozen == FALSE); 00420 00421 if (!g_slist_find (GTS_SLIST_CONTAINER (c)->items, item)) 00422 GTS_SLIST_CONTAINER (c)->items = 00423 g_slist_prepend (GTS_SLIST_CONTAINER (c)->items, item); 00424 00425 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_slist_container_class ())->parent_class)->add) (c, item); 00426 } 00427 00428 static void slist_container_remove (GtsContainer * c, GtsContainee * item) 00429 { 00430 g_return_if_fail (GTS_SLIST_CONTAINER (c)->frozen == FALSE); 00431 00432 GTS_SLIST_CONTAINER (c)->items = 00433 g_slist_remove (GTS_SLIST_CONTAINER (c)->items, item); 00434 00435 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_slist_container_class ())->parent_class)->remove) (c, item); 00436 } 00437 00438 static void slist_container_foreach (GtsContainer * c, 00439 GtsFunc func, 00440 gpointer data) 00441 { 00442 GSList * i; 00443 00444 i = GTS_SLIST_CONTAINER (c)->items; 00445 while (i) { 00446 GSList * next = i->next; 00447 00448 (* func) (i->data, data); 00449 i = next; 00450 } 00451 } 00452 00453 static guint slist_container_size (GtsContainer * c) 00454 { 00455 return g_slist_length (GTS_SLIST_CONTAINER (c)->items); 00456 } 00457 00458 static void slist_container_class_init (GtsSListContainerClass * klass) 00459 { 00460 GTS_CONTAINER_CLASS (klass)->add = slist_container_add; 00461 GTS_CONTAINER_CLASS (klass)->remove = slist_container_remove; 00462 GTS_CONTAINER_CLASS (klass)->foreach = slist_container_foreach; 00463 GTS_CONTAINER_CLASS (klass)->size = slist_container_size; 00464 00465 GTS_OBJECT_CLASS (klass)->destroy = slist_container_destroy; 00466 } 00467 00468 static void slist_container_init (GtsSListContainer * object) 00469 { 00470 object->items = NULL; 00471 object->frozen = FALSE; 00472 } 00473 00474 GtsSListContainerClass * gts_slist_container_class (void) 00475 { 00476 static GtsSListContainerClass * klass = NULL; 00477 00478 if (klass == NULL) { 00479 GtsObjectClassInfo slist_container_info = { 00480 "GtsSListContainer", 00481 sizeof (GtsSListContainer), 00482 sizeof (GtsSListContainerClass), 00483 (GtsObjectClassInitFunc) slist_container_class_init, 00484 (GtsObjectInitFunc) slist_container_init, 00485 (GtsArgSetFunc) NULL, 00486 (GtsArgGetFunc) NULL 00487 }; 00488 klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_container_class ()), 00489 &slist_container_info); 00490 } 00491 00492 return klass; 00493 }