summaryrefslogtreecommitdiff
path: root/src/til_tap.h
blob: 66f1d3e432a0a2780298f46490e81e7b40b33cc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 *  Copyright (C) 2023 - Vito Caputo - <vcaputo@pengaru.com>
 *
 *  This program is free software: you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License version 2 as published
 *  by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _TIL_TAP_H
#define _TIL_TAP_H

#include <stdint.h>
#include <string.h>

#include "til_jenkins.h"

/* A "tap" is a named binding of a local variable+pointer to that variable.
 *
 * Its purpose is to facilitate exposing local variables controlling rendering
 * to potential external influence.
 *
 * The tap itself is not a registry or otherwise discoverable entity by itself.
 * This is strictly just the local glue, Other pieces must index and tie taps
 * into streams or settings stuff for addressing them by name at a path or other
 * means.
 *
 * Note the intended way for taps to work is that the caller will always access their
 * local variables indirectly via the pointers they provided when initializing the taps.
 * There will be a function for managing the tap the caller must call before accessing
 * the variable indirectly as well.  It's that function which will update the indirection
 * pointer to potentially point elsewhere if another tap is driving the variable.
 */

/* These are all the supported tap types, nothing is set in stone this just
 * seemed like the likely stuff to need.  Feel free to add anything as needed.
 */
typedef enum til_tap_type_t {
	TIL_TAP_TYPE_I8,
	TIL_TAP_TYPE_I16,
	TIL_TAP_TYPE_I32,
	TIL_TAP_TYPE_I64,
	TIL_TAP_TYPE_U8,
	TIL_TAP_TYPE_U16,
	TIL_TAP_TYPE_U32,
	TIL_TAP_TYPE_U64,
	TIL_TAP_TYPE_FLOAT,
	TIL_TAP_TYPE_DOUBLE,
	TIL_TAP_TYPE_V2F,	/* 2D vector of floats */
	TIL_TAP_TYPE_V3F,	/* 3D vector of floats */
	TIL_TAP_TYPE_V4F,	/* 4D vector of floats */
	TIL_TAP_TYPE_M4F,	/* 4x4 float matrix */
	TIL_TAP_TYPE_VOIDP,	/* escape hatch for when you're getting exotic and want to bypass type checking */
	TIL_TAP_TYPE_MAX,
} til_tap_type_t;

/* this is deliberately left entirely public so taps can be easily embedded in contexts */
typedef struct til_tap_t {
	til_tap_type_t	type;
	void		**ptr;		/* points at the caller-provided tap-managed indirection pointer */
	size_t		n_elems;	/* when > 1, *ptr is an array of n_elems elements.  Otherwise individual variable. */
	void		*elems;		/* points at the first element of type type, may or may not be an array of them */
	const char	*name;
	uint32_t	name_hash;		/* cached hash of name, set once @ initialization */
} til_tap_t;

/* just some forward declared higher-order vector and matrix types for the wrappers */
typedef struct v2f_t v2f_t;
typedef struct v3f_t v3f_t;
typedef struct v4f_t v4f_t;
typedef struct m4f_t m4f_t;

/* This is the bare tap initializer but use the type-checked wrappers below and add one if one's missing */
static inline til_tap_t til_tap_init(til_tap_type_t type, void *ptr, size_t n_elems, void *elems, const char *name)
{
	assert(type < TIL_TAP_TYPE_MAX);
	assert(ptr);
	assert(n_elems);
	assert(elems);
	assert(name);

	*((void **)ptr) = elems;

	return (til_tap_t){
		.type = type,
		.ptr = ptr,
		.n_elems = n_elems,
		.elems = elems,
		.name = name,
		.name_hash = til_jenkins((uint8_t *)name, strlen(name)),
	};
}

/* typed wrappers, just supply n_elems=1 for individual variables - note n_elems is just a defensive
 * programming sanity check to catch callers mismatching array sizes
 */
static inline til_tap_t til_tap_init_i8(int8_t **ptr, size_t n_elems, int8_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_I8, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_i16(int16_t **ptr, size_t n_elems, int16_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_I16, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_i32(int32_t **ptr, size_t n_elems, int32_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_I32, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_i64(int64_t **ptr, size_t n_elems, int64_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_I64, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_u8(uint8_t **ptr, size_t n_elems, uint8_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_U8, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_u16(uint16_t **ptr, size_t n_elems, uint16_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_U16, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_u32(uint32_t **ptr, size_t n_elems, uint32_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_U32, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_u64(uint64_t **ptr, size_t n_elems, uint64_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_U64, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_float(float **ptr, size_t n_elems, float *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_FLOAT, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_double(double **ptr, size_t n_elems, double *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_DOUBLE, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_v2f(v2f_t **ptr, size_t n_elems, v2f_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_V2F, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_v3f(v3f_t **ptr, size_t n_elems, v3f_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_V3F, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_v4f(v4f_t **ptr, size_t n_elems, v4f_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_V4F, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_m4f(m4f_t **ptr, size_t n_elems, m4f_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_M4F, ptr, n_elems, elems, name);
}

static inline til_tap_t til_tap_init_til_tap_voidp(void **ptr, size_t n_elems, til_tap_t *elems, const char *name)
{
	return til_tap_init(TIL_TAP_TYPE_VOIDP, ptr, n_elems, elems, name);
}

#endif
© All Rights Reserved