summaryrefslogtreecommitdiff
path: root/src/modules/swarm/swarm.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2022-04-01 17:47:19 -0700
committerVito Caputo <vcaputo@pengaru.com>2022-04-01 17:59:03 -0700
commit6b8790a22c38e0d5419eb5a4dac5e30f684ae473 (patch)
tree444ac5369c34a705cd302862928ccad237d68bfe /src/modules/swarm/swarm.c
parent78c275b094b63e01a5f7bc71af80fe787911bbf4 (diff)
modules/*: instantiate and use setups
Now modules allocate and return an opaque setup pointer in res_setup when they implement a setup method. Defaults are utilized when ${module}_create_context() receives a NULL setup. The default setup used in this case should match the defaults/preferred values emitted by the module's setup method. But performing setup should always be optional, so a NULL setup provided to create_context() is to be expected. No cleanup of these setup instances is currently performed, so it's a small memory leak for now. Since these are opaque and may contain nested references to other allocations, simply using free() somewhere in the frontend is insufficient. There will probably need to be something like a til_module_t.setup_free() method added in the future which modules may assign libc's free() to when appropriate, or their own more elaborate version. Lifecycle for the settings is very simple; the setup method returns an instance, the caller is expected to free it when no longer needed (once free is implemented). The create_context consumer of a given setup must make its own copy of the settings if necessary, and may not keep a reference - it must assume the setup will be freed immediately after create_context() returns. This enables the ability to reuse a setup instance across multiple create_context() calls if desired, one can imagine something like running the same module with the same settings multiple times across multiple displays for instance. If the module has significant entropy the output will differ despite being configured identically... With this commit one may change settings for any of the modules *while* the modules are actively rendering a given context, and the settings should *not* be visible. They should only affect the context they're supplied to.
Diffstat (limited to 'src/modules/swarm/swarm.c')
-rw-r--r--src/modules/swarm/swarm.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/src/modules/swarm/swarm.c b/src/modules/swarm/swarm.c
index ffaaa1d..a41e388 100644
--- a/src/modules/swarm/swarm.c
+++ b/src/modules/swarm/swarm.c
@@ -20,6 +20,7 @@
* https://en.wikipedia.org/wiki/Swarm_intelligence
*/
+#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
@@ -27,11 +28,6 @@
#include "til.h"
#include "til_fb.h"
-typedef enum swarm_draw_style_t {
- SWARM_DRAW_STYLE_POINTS, /* simple opaque pixel per particle */
- SWARM_DRAW_STYLE_LINES, /* simple opaque lines per particle, oriented and sized by direction and velocity */
-} swarm_draw_style_t;
-
typedef struct v3f_t {
float x, y, z;
} v3f_t;
@@ -46,9 +42,19 @@ typedef struct boid_t {
float velocity;
} boid_t;
+typedef enum swarm_draw_style_t {
+ SWARM_DRAW_STYLE_POINTS, /* simple opaque pixel per particle */
+ SWARM_DRAW_STYLE_LINES, /* simple opaque lines per particle, oriented and sized by direction and velocity */
+} swarm_draw_style_t;
+
+typedef struct swarm_setup_t {
+ swarm_draw_style_t draw_style;
+} swarm_setup_t;
+
typedef struct swarm_context_t {
v3f_t color;
float ztweak;
+ swarm_setup_t setup;
boid_t boids[];
} swarm_context_t;
@@ -56,7 +62,9 @@ typedef struct swarm_context_t {
#define SWARM_ZCONST 4.f
#define SWARM_DEFAULT_STYLE SWARM_DRAW_STYLE_LINES
-static swarm_draw_style_t swarm_draw_style = SWARM_DEFAULT_STYLE;
+static swarm_setup_t swarm_default_setup = {
+ .draw_style = SWARM_DEFAULT_STYLE,
+};
static inline float randf(float min, float max)
@@ -174,10 +182,15 @@ static void * swarm_create_context(unsigned ticks, unsigned num_cpus, void *setu
{
swarm_context_t *ctxt;
+ if (!setup)
+ setup = &swarm_default_setup;
+
ctxt = calloc(1, sizeof(swarm_context_t) + sizeof(*(ctxt->boids)) * SWARM_SIZE);
if (!ctxt)
return NULL;
+ ctxt->setup = *(swarm_setup_t *)setup;
+
for (unsigned i = 0; i < SWARM_SIZE; i++)
boid_randomize(&ctxt->boids[i]);
@@ -399,7 +412,7 @@ static void swarm_render_fragment(void *context, unsigned ticks, unsigned cpu, t
til_fb_fragment_zero(fragment);
- switch (swarm_draw_style) {
+ switch (ctxt->setup.draw_style) {
case SWARM_DRAW_STYLE_POINTS:
return swarm_draw_as_points(ctxt, fragment);
case SWARM_DRAW_STYLE_LINES:
@@ -432,9 +445,19 @@ static int swarm_setup(const til_settings_t *settings, til_setting_t **res_setti
if (r)
return r;
- for (int i = 0; styles[i]; i++) {
- if (!strcmp(styles[i], style))
- swarm_draw_style = i;
+ if (res_setup) {
+ swarm_setup_t *setup;
+
+ setup = calloc(1, sizeof(*setup));
+ if (!setup)
+ return -ENOMEM;
+
+ for (int i = 0; styles[i]; i++) {
+ if (!strcmp(styles[i], style))
+ setup->draw_style = i;
+ }
+
+ *res_setup = setup;
}
return 0;
© All Rights Reserved