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 <string.h> 00021 #include "gts.h" 00022 #include "gts-private.h" 00023 00024 static GHashTable * class_table = NULL; 00025 00026 static void gts_object_class_init (GtsObjectClass * klass, 00027 GtsObjectClass * parent_class) 00028 { 00029 if (parent_class) { 00030 gts_object_class_init (klass, parent_class->parent_class); 00031 if (parent_class->info.class_init_func) 00032 (*parent_class->info.class_init_func) (klass); 00033 } 00034 } 00035 00044 gpointer gts_object_class_new (GtsObjectClass * parent_class, 00045 GtsObjectClassInfo * info) 00046 { 00047 GtsObjectClass * klass; 00048 00049 g_return_val_if_fail (info != NULL, NULL); 00050 g_return_val_if_fail (parent_class == NULL || 00051 info->object_size >= parent_class->info.object_size, 00052 NULL); 00053 g_return_val_if_fail (parent_class == NULL || 00054 info->class_size >= parent_class->info.class_size, 00055 NULL); 00056 00057 klass = g_malloc0 (info->class_size); 00058 klass->info = *info; 00059 klass->parent_class = parent_class; 00060 gts_object_class_init (klass, klass); 00061 00062 if (!class_table) 00063 class_table = g_hash_table_new (g_str_hash, g_str_equal); 00064 g_hash_table_insert (class_table, klass->info.name, klass); 00065 00066 return klass; 00067 } 00068 00076 GtsObjectClass * gts_object_class_from_name (const gchar * name) 00077 { 00078 g_return_val_if_fail (name != NULL, NULL); 00079 00080 if (!class_table) 00081 return NULL; 00082 return g_hash_table_lookup (class_table, name); 00083 } 00084 00085 static void object_destroy (GtsObject * object) 00086 { 00087 #ifdef DEBUG_IDENTITY 00088 #ifdef DEBUG_LEAKS 00089 fprintf (stderr, "destroy %s %p->%d\n", 00090 object->klass->info.name, 00091 object, 00092 id (object)); 00093 #endif 00094 id_remove (object); 00095 #endif 00096 object->klass = NULL; 00097 g_free (object); 00098 } 00099 00100 static void object_clone (GtsObject * clone, GtsObject * object) 00101 { 00102 memcpy (clone, object, object->klass->info.object_size); 00103 clone->reserved = NULL; 00104 } 00105 00106 static void object_class_init (GtsObjectClass * klass) 00107 { 00108 klass->clone = object_clone; 00109 klass->destroy = object_destroy; 00110 klass->read = NULL; 00111 klass->write = NULL; 00112 klass->color = NULL; 00113 klass->attributes = NULL; 00114 } 00115 00116 static void object_init (GtsObject * object) 00117 { 00118 object->reserved = NULL; 00119 object->flags = 0; 00120 } 00121 00127 GtsObjectClass * gts_object_class (void) 00128 { 00129 static GtsObjectClass * klass = NULL; 00130 00131 if (klass == NULL) { 00132 GtsObjectClassInfo object_info = { 00133 "GtsObject", 00134 sizeof (GtsObject), 00135 sizeof (GtsObjectClass), 00136 (GtsObjectClassInitFunc) object_class_init, 00137 (GtsObjectInitFunc) object_init, 00138 (GtsArgSetFunc) NULL, 00139 (GtsArgGetFunc) NULL 00140 }; 00141 klass = gts_object_class_new (NULL, &object_info); 00142 } 00143 00144 return klass; 00145 } 00146 00154 gpointer gts_object_check_cast (gpointer object, 00155 gpointer klass) 00156 { 00157 if (!object) { 00158 g_warning ("invalid cast from (NULL) pointer to `%s'", 00159 GTS_OBJECT_CLASS (klass)->info.name); 00160 return object; 00161 } 00162 if (!((GtsObject *) object)->klass) { 00163 g_warning ("invalid unclassed pointer in cast to `%s'", 00164 GTS_OBJECT_CLASS (klass)->info.name); 00165 return object; 00166 } 00167 if (!gts_object_is_from_class (object, klass)) { 00168 g_warning ("invalid cast from `%s' to `%s'", 00169 ((GtsObject *) object)->klass->info.name, 00170 GTS_OBJECT_CLASS (klass)->info.name); 00171 return object; 00172 } 00173 return object; 00174 } 00175 00184 gpointer gts_object_class_check_cast (gpointer klass, 00185 gpointer from) 00186 { 00187 if (!klass) { 00188 g_warning ("invalid cast from (NULL) pointer to `%s'", 00189 GTS_OBJECT_CLASS (from)->info.name); 00190 return klass; 00191 } 00192 if (!gts_object_class_is_from_class (klass, from)) { 00193 g_warning ("invalid cast from `%s' to `%s'", 00194 GTS_OBJECT_CLASS (klass)->info.name, 00195 GTS_OBJECT_CLASS (from)->info.name); 00196 return klass; 00197 } 00198 return klass; 00199 } 00200 00211 void gts_object_init (GtsObject * object, GtsObjectClass * klass) 00212 { 00213 GtsObjectClass * parent_class; 00214 00215 g_return_if_fail (object != NULL); 00216 g_return_if_fail (klass != NULL); 00217 00218 parent_class = klass->parent_class; 00219 if (parent_class) 00220 gts_object_init (object, parent_class); 00221 if (klass->info.object_init_func) 00222 (*klass->info.object_init_func) (object); 00223 } 00224 00231 GtsObject * gts_object_new (GtsObjectClass * klass) 00232 { 00233 GtsObject * object; 00234 00235 g_return_val_if_fail (klass != NULL, NULL); 00236 00237 object = g_malloc0 (klass->info.object_size); 00238 object->klass = klass; 00239 gts_object_init (object, klass); 00240 00241 #ifdef DEBUG_IDENTITY 00242 id_insert (object); 00243 #ifdef DEBUG_LEAKS 00244 fprintf (stderr, "new %s %p->%d\n", klass->info.name, 00245 object, 00246 id (object)); 00247 #endif 00248 #endif 00249 00250 return object; 00251 } 00252 00262 GtsObject * gts_object_clone (GtsObject * object) 00263 { 00264 GtsObject * clone; 00265 00266 g_return_val_if_fail (object != NULL, NULL); 00267 g_return_val_if_fail (object->klass->clone, NULL); 00268 00269 clone = g_malloc0 (object->klass->info.object_size); 00270 clone->klass = object->klass; 00271 object_init (clone); 00272 (* object->klass->clone) (clone, object); 00273 00274 #ifdef DEBUG_IDENTITY 00275 id_insert (clone); 00276 #ifdef DEBUG_LEAKS 00277 fprintf (stderr, "clone %s %p->%d\n", clone->klass->info.name, 00278 clone, 00279 id (clone)); 00280 #endif 00281 #endif 00282 00283 return clone; 00284 } 00285 00292 void gts_object_destroy (GtsObject * object) 00293 { 00294 g_assert (object->klass->destroy); 00295 GTS_OBJECT_SET_FLAGS (object, GTS_DESTROYED); 00296 (* object->klass->destroy) (object); 00297 } 00298 00305 void gts_object_reset_reserved (GtsObject * object) 00306 { 00307 g_return_if_fail (object != NULL); 00308 00309 object->reserved = NULL; 00310 } 00311 00319 void gts_object_attributes (GtsObject * object, GtsObject * from) 00320 { 00321 g_return_if_fail (object != NULL); 00322 00323 if (object->klass->attributes) 00324 (* object->klass->attributes) (object, from); 00325 } 00326 00327 static void free_class (gchar * name, GtsObjectClass * klass) 00328 { 00329 g_free (klass); 00330 } 00331 00338 void gts_finalize (void) 00339 { 00340 if (class_table) { 00341 g_hash_table_foreach (class_table, (GHFunc) free_class, NULL); 00342 g_hash_table_destroy (class_table); 00343 class_table = NULL; 00344 } 00345 }