6. Nodes

6.1. Mother Node

<<funcdefs>>=
tdelay_d * node_tdelay_mother(gf_node *node, int nloops);
<<funcs>>=
static void tdelay_compute(gf_node *node)
{
    tdelay_d *td;
    int blksize;
    int n;
    int clock_tick;
    int event_tick;
    int rc;

    td = gf_node_get_data(node);
    blksize = gf_node_blksize(node);

    event_tick = 0;
    clock_tick = 0;

    if (td->ticked_last_block) {
        tdelay_loop *bank;
        bank = td->bank;
        td->ticked_last_block = 0;
        for (n = 0; n < td->nloops; n++) {
            if (bank[n].state == FIRE) {
                 bank[n].state = RELOAD;
            }
        }
    }

    for (n = 0; n < blksize; n++) {

        rc = gf_cable_get(td->in, n) != 0 && !event_tick;

        if (rc) {
            event_tick = 1;
            tdelay_trigger_loop(td, n);
        }

        rc = gf_cable_get(td->clk, n) != 0 && !clock_tick;

        if (rc) {
            clock_tick = 1;
            tdelay_update(td, n);
        }
    }
}

static void tdelay_destroy(gf_node *node)
{
    tdelay_d *td;
    void *mem;
    gf_patch *patch;
    int rc;
    gf_node_cables_free(node);

    rc = gf_node_get_patch(node, &patch);
    if (rc != GF_OK) return;

    td = gf_node_get_data(node);
    if (td == NULL) return;
    mem = td->bank;
    rc = gf_memory_free(patch, &mem);
    if (rc != GF_OK) return;
    mem = td;
    gf_memory_free(patch, &mem);
}

tdelay_d * node_tdelay_mother(gf_node *node, int nloops)
{
    tdelay_d *td;
    gf_patch *patch;
    int rc;
    void *mem;
    int i;

    rc = gf_node_get_patch(node, &patch);
    if (rc != GF_OK) return NULL;

    mem = NULL;
    rc = gf_memory_alloc(patch, sizeof(tdelay_d), &mem);

    if (rc != GF_OK) return NULL;
    td = mem;

    rc = gf_memory_alloc(patch,
                         sizeof(tdelay_loop) * nloops,
                         &mem);

    if (rc != GF_OK) {
        mem = td;
        gf_memory_free(patch, &mem);
        return NULL;
    }

    td->bank = mem;
    td->nloops = nloops;
    td->last_free = -1;
    td->nactive = 0;
    td->ticked_last_block = 0;
    td->eps = 0.001;

    for (i = 0; i < nloops; i++) {
        tdelay_loop_init(&td->bank[i]);
    }

    gf_node_cables_alloc(node, 4);
<<bind_cables>>

    gf_node_set_data(node, td);
    gf_node_set_destroy(node, tdelay_destroy);
    gf_node_set_compute(node, tdelay_compute);
    return td;
}

6.2. Loop Node

<<funcdefs>>=
int node_tdelay_loop(gf_node *node, tdelay_d *td, int loop);
<<funcs>>=
static void loop_compute(gf_node *node)
{
    int n;
    int blksize;
    gf_cable *out;
    GFFLT tick;
    tdelay_loop *lp;

    gf_node_get_cable(node, 0, &out);
    blksize = gf_node_blksize(node);
    lp = gf_node_get_data(node);

    for (n = 0; n < blksize; n++) {
        tick = 0;

        if (lp->state == FIRE && n == lp->blockpos) {
            tick = lp->energy;
        }

        gf_cable_set(out, n, tick);
    }
}

int node_tdelay_loop(gf_node *node, tdelay_d *td, int loop)
{
    if (loop >= td->nloops) {
        return GF_NOT_OK;
    }
    gf_node_cables_alloc(node, 1);
    gf_node_set_block(node, 0);
    gf_node_set_data(node, &td->bank[loop]);
    gf_node_set_compute(node, loop_compute);
    return GF_OK;
}



prev | home | next