diff options
| author | Ethan Werner <mail@ethanwerner.com> | 2024-04-17 16:00:00 -0700 |
|---|---|---|
| committer | Ethan Werner <mail@ethanwerner.com> | 2026-06-08 16:01:49 +0400 |
| commit | f6a144987cc403de8ad6bddd055f756120f8d405 (patch) | |
| tree | 3b4cfc8c76db7adba8504dc0e079466e2a0d336c /include/direct.h | |
archival commit
Diffstat (limited to 'include/direct.h')
| -rw-r--r-- | include/direct.h | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/include/direct.h b/include/direct.h new file mode 100644 index 0000000..c26907e --- /dev/null +++ b/include/direct.h @@ -0,0 +1,121 @@ +#ifndef DT_H +#define DT_H + +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> + +struct value_t; + +typedef struct edge { + struct edge *next; + struct node *node; +} edge_t; + +typedef struct node { + struct edge *edge; + value_t x; + bool flag; + value_t (*function)(struct node *node); +} node_t; + +void dt_connect(node_t *, node_t *); +void dt_disconnect(node_t *, node_t *); +void dt_update(node_t *); + +value_t dt_one(node_t *node); +value_t dt_add(node_t *node); +value_t dt_subtract(node_t *node); + +#endif + +#ifdef DT_IMPLEMENTATION + +void dt_connect(node_t *to, node_t *from) { + edge_t *edge = malloc(sizeof(edge_t)); + edge->node = from; + edge->next = to->edge; + to->edge = edge; +} + +void dt_disconnect(node_t *to, node_t *from) { + edge_t *edge = to->edge; + edge_t *last = NULL; + + while (edge) { + if (edge->node == from) { + edge_t *tmp = edge; + last->next = edge->next; + free(tmp); + } + + last = edge; + edge = edge->next; + } +} + +void dt_update(node_t *origin) { + // printf(">: %p - %lf\n", origin, origin->x); + + edge_t *edge = origin->edge; + origin->flag = !origin->flag; + + while (edge) { + if (origin->flag != edge->node->flag) { + dt_update(edge->node); + } + + edge = edge->next; + } + + origin->x = origin->function(origin); + // printf("<: %p - %lf\n", origin, origin->x); +} + +void dt_update_trace(node_t *origin) { + printf(">: %p - %lf\n", origin, origin->x); + + edge_t *edge = origin->edge; + origin->flag = !origin->flag; + + while (edge) { + if (origin->flag != edge->node->flag) { + dt_update_trace(edge->node); + } + + edge = edge->next; + } + + origin->x = origin->function(origin); + printf("<: %p - %lf\n", origin, origin->x); +} + +value_t dt_one(node_t *node) { + return 1; +} + +value_t dt_add(node_t *node) { + edge_t *edge = node->edge; + value_t x = node->x; + + while(edge) { + x += edge->node->x; + edge = edge->next; + } + + return x; +} + +value_t dt_subtract(node_t *node) { + edge_t *edge = node->edge; + value_t x = node->x; + + while(edge) { + x -= edge->node->x; + edge = edge->next; + } + + return x; +} + +#endif |