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))
|
LDLIBS += $(shell pkg-config --libs $(DEPS))
|
||||||
INTERP ?=
|
INTERP ?=
|
||||||
MAIN = main
|
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)
|
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 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 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)
|
#define DEBUG_PRINT_VALUE(x, fmt) fprintf(stderr, #x " = " fmt "\n", x); fflush(stderr)
|
||||||
|
|
||||||
#endif /* end of include guard: DEFS_H_ */
|
#endif /* end of include guard: DEFS_H_ */
|
||||||
|
|
19
main.c
19
main.c
|
@ -1,14 +1,6 @@
|
||||||
#include "processing.h"
|
#include "processing.h"
|
||||||
#include "hash_table.h"
|
#include "hash_table.h"
|
||||||
#include "nodes/print.h"
|
#include "module_registry.h"
|
||||||
#include "nodes/getchar.h"
|
|
||||||
#include "nodes/evdev.h"
|
|
||||||
|
|
||||||
GraphNodeSpecification *node_specifications[] = {
|
|
||||||
&nodespec_getchar,
|
|
||||||
&nodespec_print,
|
|
||||||
&nodespec_evdev,
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char ** argv)
|
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);
|
fprintf(stderr, "No node type for node %ld \"%s\"\n", i, loaded_config.nodes.items[i].name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
GraphNodeSpecification *spec = NULL;
|
GraphNodeSpecification *spec = lookup_graph_node_specification(type_name);
|
||||||
for (size_t j = 0; j < lengthof(node_specifications); ++j) {
|
|
||||||
if (strcmp(type_name, node_specifications[j]->name) == 0) {
|
|
||||||
spec = node_specifications[j];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!spec) {
|
if (!spec) {
|
||||||
fprintf(stderr, "Unknown node type \"%s\" for node %ld \"%s\"\n", type_name, i, loaded_config.nodes.items[i].name);
|
fprintf(stderr, "Unknown node type \"%s\" for node %ld \"%s\"\n", type_name, i, loaded_config.nodes.items[i].name);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -103,5 +89,6 @@ main(int argc, char ** argv)
|
||||||
|
|
||||||
io_subscription_list_deinit(&state.wait_output);
|
io_subscription_list_deinit(&state.wait_output);
|
||||||
io_subscription_list_deinit(&state.wait_input);
|
io_subscription_list_deinit(&state.wait_input);
|
||||||
|
destroy_graph_node_specification_registry();
|
||||||
return 0;
|
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 <stdio.h>
|
||||||
#include "evdev.h"
|
#include "evdev.h"
|
||||||
#include "../processing.h"
|
#include "../processing.h"
|
||||||
|
#include "../module_registry.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GraphNode as_GraphNode;
|
GraphNode as_GraphNode;
|
||||||
|
@ -139,3 +140,8 @@ GraphNodeSpecification nodespec_evdev = (GraphNodeSpecification) {
|
||||||
.register_io = ®ister_io,
|
.register_io = ®ister_io,
|
||||||
.name = "evdev",
|
.name = "evdev",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MODULE_CONSTRUCTOR(init)
|
||||||
|
{
|
||||||
|
register_graph_node_specification(&nodespec_evdev);
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "getchar.h"
|
#include "getchar.h"
|
||||||
#include "../processing.h"
|
#include "../processing.h"
|
||||||
|
#include "../module_registry.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GraphNode as_GraphNode;
|
GraphNode as_GraphNode;
|
||||||
|
@ -98,3 +99,8 @@ GraphNodeSpecification nodespec_getchar = (GraphNodeSpecification) {
|
||||||
.register_io = ®ister_io,
|
.register_io = ®ister_io,
|
||||||
.name = "getchar",
|
.name = "getchar",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MODULE_CONSTRUCTOR(init)
|
||||||
|
{
|
||||||
|
register_graph_node_specification(&nodespec_getchar);
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
|
#include "../module_registry.h"
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
handle_event(EventPositionBase * self, EventNode * event)
|
handle_event(EventPositionBase * self, EventNode * event)
|
||||||
|
@ -59,3 +60,8 @@ GraphNodeSpecification nodespec_print = (GraphNodeSpecification) {
|
||||||
.register_io = NULL,
|
.register_io = NULL,
|
||||||
.name = "print",
|
.name = "print",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MODULE_CONSTRUCTOR(init)
|
||||||
|
{
|
||||||
|
register_graph_node_specification(&nodespec_print);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue