Mercurial > audlegacy-plugins
diff src/paranormal-ng/containers.c @ 2078:1fa3c8cd366a
paranormal-ng: a GL visualiser. lots to do, most stuff won't work, but hey, this will do cool stuff too soon
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Mon, 15 Oct 2007 06:20:13 -0500 |
parents | |
children | f1b6f1b2cdb3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/paranormal-ng/containers.c Mon Oct 15 06:20:13 2007 -0500 @@ -0,0 +1,267 @@ +/* + * paranormal: iterated pipeline-driven visualization plugin + * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org> + * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <config.h> + +#include <stdio.h> + +#include <glib.h> + +#include "actuators.h" +#include "paranormal.h" + +/* **************** all containers **************** */ + +/* Add a actuator to a container (end of list) */ +void +container_add_actuator (struct pn_actuator *container, struct pn_actuator *a) +{ + g_assert (container->desc->flags & ACTUATOR_FLAG_CONTAINER); + g_assert (a); + + *((GSList **)container->data) = + g_slist_append (*(GSList **)container->data, a); +} + +void +container_remove_actuator (struct pn_actuator *container, struct pn_actuator *a) +{ + g_assert (container->desc->flags & ACTUATOR_FLAG_CONTAINER); + g_assert (a); + + *((GSList **)container->data) = + g_slist_remove (*(GSList **)container->data, a); +} + +/* clear the containee list */ +void +container_unlink_actuators (struct pn_actuator *container) +{ + g_assert (container->desc->flags & ACTUATOR_FLAG_CONTAINER); + + g_slist_free (*(GSList **)container->data); + *(GSList **)container->data = NULL; +} + +/* this does NOT free data */ +static void +container_cleanup (GSList** data) +{ + GSList *child; + + for (child = *data; child; child = child->next) + destroy_actuator ((struct pn_actuator *) child->data); + + g_slist_free (*data); +} + +/* **************** container_simple **************** */ +static void +container_simple_init (GSList ***data) +{ + *data = g_new0 (GSList *, 1); +} + +static void +container_simple_cleanup (GSList **data) +{ + container_cleanup (data); + g_free (data); +} + +static void +container_simple_exec (const struct pn_actuator_option *opts, + GSList **data) +{ + GSList *child; + + for (child = *data; child; child = child->next) + exec_actuator ((struct pn_actuator *) child->data); +} + +struct pn_actuator_desc builtin_container_simple = +{ + "container_simple", + "Simple Container", + "A simple (unconditional) container\n\n" + "This is usually used as the root actuator of a list", + ACTUATOR_FLAG_CONTAINER, NULL, + PN_ACTUATOR_INIT_FUNC (container_simple_init), + PN_ACTUATOR_CLEANUP_FUNC (container_simple_cleanup), + PN_ACTUATOR_EXEC_FUNC (container_simple_exec) +}; + +/* **************** container_once **************** */ +struct container_once_data +{ + GSList *children; /* This MUST be first! */ + + gboolean done; +}; + +static void +container_once_init (struct container_once_data **data) +{ + *data = g_new0 (struct container_once_data, 1); +} + +static void +container_once_cleanup (GSList **data) +{ + container_cleanup (data); + g_free (data); +} + +static void +container_once_exec (const struct pn_actuator_option *opts, + struct container_once_data *data) +{ + if (! data->done) + { + GSList *child; + + for (child = data->children; child; child = child->next) + exec_actuator ((struct pn_actuator *) child->data); + + data->done = TRUE; + } +} + +struct pn_actuator_desc builtin_container_once = +{ + "container_once", + "Initialization Container", + "A container whose contents get executed exactly once.\n\n" + "This is often used to set initial graphics states such as the\n" + "pixel depth, or to display some text (such as credits)", + ACTUATOR_FLAG_CONTAINER, NULL, + PN_ACTUATOR_INIT_FUNC (container_once_init), + PN_ACTUATOR_CLEANUP_FUNC (container_once_cleanup), + PN_ACTUATOR_EXEC_FUNC (container_once_exec) +}; + +/* **************** container_cycle ***************** */ +static struct pn_actuator_option_desc container_cycle_opts[] = +{ + { "change_interval", "The number of seconds between changing the " + "child to be executed", OPT_TYPE_INT, { ival: 20 } }, + { "beat", "Whether or not the change should only occur on a beat", + OPT_TYPE_BOOLEAN, { bval: TRUE } }, + { NULL } +}; + +struct container_cycle_data +{ + GSList *children; + GSList *current; + int last_change; +}; + +static void +container_cycle_init (gpointer *data) +{ + *data = g_new0 (struct container_cycle_data, 1); +} + +static void +container_cycle_cleanup (gpointer data) +{ + container_cleanup (data); + g_free (data); +} + +static void +container_cycle_exec (const struct pn_actuator_option *opts, + gpointer data) +{ + struct container_cycle_data *cdata = (struct container_cycle_data*)data; + int now; + + /* + * Change branch if all of the requirements are met for the branch to change. + */ + if ((opts[1].val.bval == TRUE && pn_new_beat != FALSE) || opts[1].val.bval == FALSE) + { + now = SDL_GetTicks(); + + if (now - cdata->last_change + > opts[0].val.ival * 1000) + { + cdata->last_change = now; + + /* FIXME: add randomization support */ + if (cdata->current) + cdata->current = cdata->current->next; + } + } + + if (! cdata->current) + cdata->current = cdata->children; + + if (cdata->current) + exec_actuator ((struct pn_actuator*)cdata->current->data); +} + +struct pn_actuator_desc builtin_container_cycle = +{ + "container_cycle", + "Branched-execution Container", + "A container that alternates which of its children is executed; it " + "can either change on an interval, or only on a beat.", + ACTUATOR_FLAG_CONTAINER, container_cycle_opts, + container_cycle_init, container_cycle_cleanup, container_cycle_exec +}; + +/* **************** container_onbeat **************** */ +static void +container_onbeat_init (GSList ***data) +{ + *data = g_new0 (GSList *, 1); +} + +static void +container_onbeat_cleanup (GSList **data) +{ + container_cleanup (data); + g_free (data); +} + +static void +container_onbeat_exec (const struct pn_actuator_option *opts, + GSList **data) +{ + GSList *child; + + if (pn_new_beat == TRUE) + { + for (child = *data; child; child = child->next) + exec_actuator ((struct pn_actuator *) child->data); + } +} + +struct pn_actuator_desc builtin_container_onbeat = +{ + "container_onbeat", + "OnBeat Container", + "A simple container which only triggers on a beat.", + ACTUATOR_FLAG_CONTAINER, NULL, + PN_ACTUATOR_INIT_FUNC (container_onbeat_init), + PN_ACTUATOR_CLEANUP_FUNC (container_onbeat_cleanup), + PN_ACTUATOR_EXEC_FUNC (container_onbeat_exec) +};