/* _______ ____ __ ___ ___ * \ _ \ \ / \ / \ \ / / ' ' ' * | | \ \ | | || | \/ | . . * | | | | | | || ||\ /| | * | | | | | | || || \/ | | ' ' ' * | | | | | | || || | | . . * | |_/ / \ \__// || | | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque * / \ * / . \ * register.c - Signal type registration. / / \ \ * | < / \_ * By entheh. | \/ /\ / * \_ / > / * | \ / / * | ' / * \__/ */ #include #include "dumb.h" #include "internal/dumb.h" static DUH_SIGTYPE_DESC_LINK *sigtype_desc = NULL; static DUH_SIGTYPE_DESC_LINK **sigtype_desc_tail = &sigtype_desc; /* destroy_sigtypes(): frees all memory allocated while registering signal * types. This function is set up to be called by dumb_exit(). */ static void destroy_sigtypes(void) { DUH_SIGTYPE_DESC_LINK *desc_link = sigtype_desc, *next; sigtype_desc = NULL; sigtype_desc_tail = &sigtype_desc; while (desc_link) { next = desc_link->next; free(desc_link); desc_link = next; } } /* dumb_register_sigtype(): registers a new signal type with DUMB. The signal * type is identified by a four-character string (e.g. "WAVE"), which you can * encode using the the DUMB_ID() macro (e.g. DUMB_ID('W','A','V','E')). The * signal's behaviour is defined by four functions, whose pointers you pass * here. See the documentation for details. * * If a DUH tries to use a signal that has not been registered using this * function, then the library will fail to load the DUH. */ void dumb_register_sigtype(DUH_SIGTYPE_DESC *desc) { DUH_SIGTYPE_DESC_LINK *desc_link = sigtype_desc; ASSERT((desc->load_sigdata && desc->unload_sigdata) || (!desc->load_sigdata && !desc->unload_sigdata)); ASSERT((desc->start_sigrenderer && desc->end_sigrenderer) || (!desc->start_sigrenderer && !desc->end_sigrenderer)); ASSERT(desc->sigrenderer_generate_samples && desc->sigrenderer_get_current_sample); if (desc_link) { do { if (desc_link->desc->type == desc->type) { desc_link->desc = desc; return; } desc_link = desc_link->next; } while (desc_link); } else dumb_atexit(&destroy_sigtypes); desc_link = *sigtype_desc_tail = malloc(sizeof(DUH_SIGTYPE_DESC_LINK)); if (!desc_link) return; desc_link->next = NULL; sigtype_desc_tail = &desc_link->next; desc_link->desc = desc; } /* _dumb_get_sigtype_desc(): searches the registered functions for a signal * type matching the parameter. If such a sigtype is found, it returns a * pointer to a sigtype descriptor containing the necessary functions to * manage the signal. If none is found, it returns NULL. */ DUH_SIGTYPE_DESC *_dumb_get_sigtype_desc(long type) { DUH_SIGTYPE_DESC_LINK *desc_link = sigtype_desc; while (desc_link && desc_link->desc->type != type) desc_link = desc_link->next; return desc_link ? desc_link->desc : NULL; }