Make the program unaware in compile time of the node types
Using "constructor" attribute
This commit is contained in:
parent
71e04c7f2d
commit
245563ec8b
2
Makefile
2
Makefile
|
@ -12,7 +12,7 @@ CPPFLAGS += $(shell pkg-config --cflags $(DEPS))
|
|||
LDLIBS += $(shell pkg-config --libs $(DEPS))
|
||||
INTERP ?=
|
||||
MAIN = main
|
||||
OBJS = main.o events.o processing.o graph.o config.o hash_table.o nodes/getchar.o nodes/print.o nodes/evdev.o
|
||||
OBJS = main.o events.o processing.o graph.o config.o hash_table.o module_registry.o nodes/getchar.o nodes/print.o nodes/evdev.o
|
||||
|
||||
all: $(MAIN)
|
||||
|
||||
|
|
2
defs.h
2
defs.h
|
@ -15,6 +15,8 @@
|
|||
#define IMPLICIT_CAST(dsttype, srctype, ptr) (((union { typeof(srctype) *src; typeof(dsttype) *dst; }){.src = ptr}).dst)
|
||||
#define T_ALLOC(count, T) ((T*)calloc(count, sizeof(T)))
|
||||
|
||||
#define MODULE_CONSTRUCTOR(name) __attribute__((constructor)) static void name(void)
|
||||
|
||||
#define DEBUG_PRINT_VALUE(x, fmt) fprintf(stderr, #x " = " fmt "\n", x); fflush(stderr)
|
||||
|
||||
#endif /* end of include guard: DEFS_H_ */
|
||||
|
|
19
main.c
19
main.c
|
@ -1,14 +1,6 @@
|
|||
#include "processing.h"
|
||||
#include "hash_table.h"
|
||||
#include "nodes/print.h"
|
||||
#include "nodes/getchar.h"
|
||||
#include "nodes/evdev.h"
|
||||
|
||||
GraphNodeSpecification *node_specifications[] = {
|
||||
&nodespec_getchar,
|
||||
&nodespec_print,
|
||||
&nodespec_evdev,
|
||||
};
|
||||
#include "module_registry.h"
|
||||
|
||||
int
|
||||
main(int argc, char ** argv)
|
||||
|
@ -42,13 +34,7 @@ main(int argc, char ** argv)
|
|||
fprintf(stderr, "No node type for node %ld \"%s\"\n", i, loaded_config.nodes.items[i].name);
|
||||
exit(1);
|
||||
}
|
||||
GraphNodeSpecification *spec = NULL;
|
||||
for (size_t j = 0; j < lengthof(node_specifications); ++j) {
|
||||
if (strcmp(type_name, node_specifications[j]->name) == 0) {
|
||||
spec = node_specifications[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
GraphNodeSpecification *spec = lookup_graph_node_specification(type_name);
|
||||
if (!spec) {
|
||||
fprintf(stderr, "Unknown node type \"%s\" for node %ld \"%s\"\n", type_name, i, loaded_config.nodes.items[i].name);
|
||||
exit(1);
|
||||
|
@ -103,5 +89,6 @@ main(int argc, char ** argv)
|
|||
|
||||
io_subscription_list_deinit(&state.wait_output);
|
||||
io_subscription_list_deinit(&state.wait_input);
|
||||
destroy_graph_node_specification_registry();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#include "module_registry.h"
|
||||
#include "hash_table.h"
|
||||
|
||||
static TYPED_HASH_TABLE(GraphNodeSpecification*) registry;
|
||||
static bool initialized = false;
|
||||
|
||||
static void
|
||||
ensure_initialized()
|
||||
{
|
||||
if (!initialized) {
|
||||
hash_table_init(®istry, NULL);
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
register_graph_node_specification(GraphNodeSpecification * spec)
|
||||
{
|
||||
ensure_initialized();
|
||||
if (!spec->name) {
|
||||
return;
|
||||
}
|
||||
hash_table_insert(®istry, hash_table_key_from_cstr(spec->name), &spec);
|
||||
}
|
||||
|
||||
GraphNodeSpecification *
|
||||
lookup_graph_node_specification(const char * name)
|
||||
{
|
||||
ensure_initialized();
|
||||
HashTableIndex idx = hash_table_find(®istry, hash_table_key_from_cstr(name));
|
||||
if (idx < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return registry.value_array[idx];
|
||||
}
|
||||
|
||||
void
|
||||
destroy_graph_node_specification_registry()
|
||||
{
|
||||
ensure_initialized();
|
||||
hash_table_deinit(®istry);
|
||||
initialized = false;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef MODULE_REGISTRY_H_
|
||||
#define MODULE_REGISTRY_H_
|
||||
|
||||
#include "graph.h"
|
||||
|
||||
void register_graph_node_specification(GraphNodeSpecification * spec);
|
||||
GraphNodeSpecification * lookup_graph_node_specification(const char * name);
|
||||
void destroy_graph_node_specification_registry();
|
||||
|
||||
#endif /* end of include guard: MODULE_REGISTRY_H_ */
|
|
@ -7,6 +7,7 @@
|
|||
#include <stdio.h>
|
||||
#include "evdev.h"
|
||||
#include "../processing.h"
|
||||
#include "../module_registry.h"
|
||||
|
||||
typedef struct {
|
||||
GraphNode as_GraphNode;
|
||||
|
@ -139,3 +140,8 @@ GraphNodeSpecification nodespec_evdev = (GraphNodeSpecification) {
|
|||
.register_io = ®ister_io,
|
||||
.name = "evdev",
|
||||
};
|
||||
|
||||
MODULE_CONSTRUCTOR(init)
|
||||
{
|
||||
register_graph_node_specification(&nodespec_evdev);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <unistd.h>
|
||||
#include "getchar.h"
|
||||
#include "../processing.h"
|
||||
#include "../module_registry.h"
|
||||
|
||||
typedef struct {
|
||||
GraphNode as_GraphNode;
|
||||
|
@ -98,3 +99,8 @@ GraphNodeSpecification nodespec_getchar = (GraphNodeSpecification) {
|
|||
.register_io = ®ister_io,
|
||||
.name = "getchar",
|
||||
};
|
||||
|
||||
MODULE_CONSTRUCTOR(init)
|
||||
{
|
||||
register_graph_node_specification(&nodespec_getchar);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <stdio.h>
|
||||
#include "print.h"
|
||||
#include "../module_registry.h"
|
||||
|
||||
static bool
|
||||
handle_event(EventPositionBase * self, EventNode * event)
|
||||
|
@ -59,3 +60,8 @@ GraphNodeSpecification nodespec_print = (GraphNodeSpecification) {
|
|||
.register_io = NULL,
|
||||
.name = "print",
|
||||
};
|
||||
|
||||
MODULE_CONSTRUCTOR(init)
|
||||
{
|
||||
register_graph_node_specification(&nodespec_print);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue