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