gboolean cnd_register_class(const char *class_id, _cnd_constr constr_func, _cnd_destr destr_func, _cnd_eval eval_func, _cnd_reset reset_func) { char *key = NULL; _cnd_class *cls = NULL; /* check for valid parameters */ if ((constr_func == NULL) || (destr_func == NULL) || (eval_func == NULL) || (reset_func == NULL) || (class_id == NULL)) return FALSE; /* check if hash table is already initialized */ _cnd_init(); /* check for unique class id */ if (g_hash_table_lookup(classes, class_id) != NULL) { g_warning("cnd_register_class: Duplicate class ID \"%s\"", class_id); return FALSE; } /* GHashTable keys need to be persistent for the lifetime of the hash table. Allocate memory and copy the class id which we use as key. */ key = g_strdup(class_id); /* initialize class structure */ if ((cls = (_cnd_class*)g_malloc(sizeof(_cnd_class))) == NULL) { g_free(key); return FALSE; } cls->constr_func = constr_func; cls->destr_func = destr_func; cls->eval_func = eval_func; cls->reset_func = reset_func; /* insert new class */ g_hash_table_insert(classes, key, cls); return TRUE; } /* END cnd_register_class() */
condition* cnd_new(const char* class_id, ...){ va_list ap; condition *cnd = NULL, *cnd_ref = NULL; _cnd_class *cls = NULL; char* id = NULL; /* check if hash table is already initialized */ _cnd_init(); /* get class structure for this id */ if((cls = (_cnd_class*)g_hash_table_lookup(classes, class_id)) == NULL) { g_warning("cnd_new: Couldn't find class ID \"%s\"", class_id); return NULL; } /* initialize the basic structure */ if((cnd_ref = (condition*)g_malloc(sizeof(condition))) == NULL) return NULL; cnd_ref->user_data = NULL; cnd_ref->eval_func = cls->eval_func; cnd_ref->reset_func = cls->reset_func; cnd_ref->class_id = g_strdup(class_id); /* perform class specific initialization */ va_start(ap, class_id); cnd = (cls->constr_func)(cnd_ref, ap); va_end(ap); /* check for successful construction */ if(cnd == NULL){ g_free(cnd_ref); g_free(id); } return cnd; } /* END cnd_new() */
void cnd_delete(condition *cnd){ _cnd_class *cls = NULL; const char* class_id; /* check for valid pointer */ if(cnd == NULL) return; class_id = cnd->class_id; /* check if hash table is already initialized */ _cnd_init(); /* get the condition class */ cls = (_cnd_class*)g_hash_table_lookup(classes, class_id); /* call class specific destructor */ if(cls != NULL) (cls->destr_func)(cnd); /* free memory */ g_free(cnd->class_id); /* free basic structure */ g_free(cnd); } /* END cnd_delete() */
void cnd_unregister_class(const char* class_id) { const char *key = (const char*)class_id; _cnd_class *cls = NULL; /* check if hash table is already initialized */ _cnd_init(); /* find the key for this class id and store it in 'pkey' */ g_hash_table_foreach(classes, _cnd_find_hash_key_for_class_id, (gpointer)key); /* find the class structure for this class id */ cls = (_cnd_class*)g_hash_table_lookup(classes, class_id); /* remove constructor from hash table */ g_hash_table_remove(classes, class_id); /* free the key */ g_free(pkey); pkey = NULL; /* free the value */ g_free(cls); } /* END cnd_unregister_class() */