/* _______ ____ __ ___ ___ * \ _ \ \ / \ / \ \ / / ' ' ' * | | \ \ | | || | \/ | . . * | | | | | | || ||\ /| | * | | | | | | || || \/ | | ' ' ' * | | | | | | || || | | . . * | |_/ / \ \__// || | | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque * / \ * / . \ * register.c - Signal type registration. / / \ \ * | < / \_ * By entheh. | \/ /\ / * \_ / > / * | \ / / * | ' / * \__/ */#include <stdlib.h>#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;}
/* _______ ____ __ ___ ___
* \ _ \ \ / \ / \ \ / / ' ' '
* | | \ \ | | || | \/ | . .
* | | | | | | || ||\ /| |
* | | | | | | || || \/ | | ' ' '
* | | | | | | || || | | . .
* | |_/ / \ \__// || | |
* /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
* / \
* / . \
* register.c - Signal type registration. / / \ \
* | < / \_
* By entheh. | \/ /\ /
* \_ / > /
* | \ / /
* | ' /
* \__/
*/
#include <stdlib.h>
#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;
}