shithub: dumb

ref: 7da945b75c3bd48821dbc2cfb65b886f80fa501e
dir: /src/core/register.c/

View raw version
/*  _______         ____    __         ___    ___
 * \    _  \       \    /  \  /       \   \  /   /       '   '  '
 *  |  | \  \       |  |    ||         |   \/   |         .      .
 *  |  |  |  |      |  |    ||         ||\  /|  |
 *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
 *  |  |  |  |      |  |    ||         ||    |  |         .      .
 *  |  |_/  /        \  \__//          ||    |  |
 * /_______/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;
}