comparison src/rovascope/containers.c @ 408:290588854a9d trunk

[svn] - rovascope -- a variant of the paranormal visualization engine that is uses random data instead of presets.
author nenolod
date Sat, 06 Jan 2007 01:57:34 -0800
parents src/paranormal/containers.c@5e19836a2db2
children
comparison
equal deleted inserted replaced
407:3c0cb7e84e0d 408:290588854a9d
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <stdio.h>
6
7 #include <glib.h>
8
9 #include "actuators.h"
10 #include "paranormal.h"
11
12 /* **************** all containers **************** */
13
14 /* Add a actuator to a container (end of list) */
15 void
16 container_add_actuator (struct pn_actuator *container, struct pn_actuator *a)
17 {
18 g_assert (container->desc->flags & ACTUATOR_FLAG_CONTAINER);
19 g_assert (a);
20
21 *((GSList **)container->data) =
22 g_slist_append (*(GSList **)container->data, a);
23 }
24
25 void
26 container_remove_actuator (struct pn_actuator *container, struct pn_actuator *a)
27 {
28 g_assert (container->desc->flags & ACTUATOR_FLAG_CONTAINER);
29 g_assert (a);
30
31 *((GSList **)container->data) =
32 g_slist_remove (*(GSList **)container->data, a);
33 }
34
35 /* clear the containee list */
36 void
37 container_unlink_actuators (struct pn_actuator *container)
38 {
39 g_assert (container->desc->flags & ACTUATOR_FLAG_CONTAINER);
40
41 g_slist_free (*(GSList **)container->data);
42 *(GSList **)container->data = NULL;
43 }
44
45 /* this does NOT free data */
46 static void
47 container_cleanup (GSList** data)
48 {
49 GSList *child;
50
51 for (child = *data; child; child = child->next)
52 destroy_actuator ((struct pn_actuator *) child->data);
53
54 g_slist_free (*data);
55 }
56
57 /* **************** container_simple **************** */
58 static void
59 container_simple_init (GSList ***data)
60 {
61 *data = g_new0 (GSList *, 1);
62 }
63
64 static void
65 container_simple_cleanup (GSList **data)
66 {
67 container_cleanup (data);
68 g_free (data);
69 }
70
71 static void
72 container_simple_exec (const struct pn_actuator_option *opts,
73 GSList **data)
74 {
75 GSList *child;
76
77 for (child = *data; child; child = child->next)
78 exec_actuator ((struct pn_actuator *) child->data);
79 }
80
81 struct pn_actuator_desc builtin_container_simple =
82 {
83 "container_simple",
84 "Simple Container",
85 "A simple (unconditional) container\n\n"
86 "This is usually used as the root actuator of a list",
87 ACTUATOR_FLAG_CONTAINER, NULL,
88 PN_ACTUATOR_INIT_FUNC (container_simple_init),
89 PN_ACTUATOR_CLEANUP_FUNC (container_simple_cleanup),
90 PN_ACTUATOR_EXEC_FUNC (container_simple_exec)
91 };
92
93 /* **************** container_once **************** */
94 struct container_once_data
95 {
96 GSList *children; /* This MUST be first! */
97
98 gboolean done;
99 };
100
101 static void
102 container_once_init (struct container_once_data **data)
103 {
104 *data = g_new0 (struct container_once_data, 1);
105 }
106
107 static void
108 container_once_cleanup (GSList **data)
109 {
110 container_cleanup (data);
111 g_free (data);
112 }
113
114 static void
115 container_once_exec (const struct pn_actuator_option *opts,
116 struct container_once_data *data)
117 {
118 if (! data->done)
119 {
120 GSList *child;
121
122 for (child = data->children; child; child = child->next)
123 exec_actuator ((struct pn_actuator *) child->data);
124
125 data->done = TRUE;
126 }
127 }
128
129 struct pn_actuator_desc builtin_container_once =
130 {
131 "container_once",
132 "Initialization Container",
133 "A container whose contents get executed exactly once.\n\n"
134 "This is often used to set initial graphics states such as the\n"
135 "pixel depth, or to display some text (such as credits)",
136 ACTUATOR_FLAG_CONTAINER, NULL,
137 PN_ACTUATOR_INIT_FUNC (container_once_init),
138 PN_ACTUATOR_CLEANUP_FUNC (container_once_cleanup),
139 PN_ACTUATOR_EXEC_FUNC (container_once_exec)
140 };
141
142 /* **************** container_cycle ***************** */
143 static struct pn_actuator_option_desc container_cycle_opts[] =
144 {
145 { "change_interval", "The number of seconds between changing the "
146 "child to be executed", OPT_TYPE_INT, { ival: 20 } },
147 { "beat", "Whether or not the change should only occur on a beat",
148 OPT_TYPE_BOOLEAN, { bval: TRUE } },
149 { NULL }
150 };
151
152 struct container_cycle_data
153 {
154 GSList *children;
155 GSList *current;
156 int last_change;
157 };
158
159 static void
160 container_cycle_init (gpointer *data)
161 {
162 *data = g_new0 (struct container_cycle_data, 1);
163 }
164
165 static void
166 container_cycle_cleanup (gpointer data)
167 {
168 container_cleanup (data);
169 g_free (data);
170 }
171
172 static void
173 container_cycle_exec (const struct pn_actuator_option *opts,
174 gpointer data)
175 {
176 struct container_cycle_data *cdata = (struct container_cycle_data*)data;
177 int now;
178
179 /*
180 * Change branch if all of the requirements are met for the branch to change.
181 */
182 if ((opts[1].val.bval == TRUE && pn_new_beat != FALSE) || opts[1].val.bval == FALSE)
183 {
184 now = SDL_GetTicks();
185
186 if (now - cdata->last_change
187 > opts[0].val.ival * 1000)
188 {
189 cdata->last_change = now;
190
191 /* FIXME: add randomization support */
192 if (cdata->current)
193 cdata->current = cdata->current->next;
194 }
195 }
196
197 if (! cdata->current)
198 cdata->current = cdata->children;
199
200 if (cdata->current)
201 exec_actuator ((struct pn_actuator*)cdata->current->data);
202 }
203
204 struct pn_actuator_desc builtin_container_cycle =
205 {
206 "container_cycle",
207 "Branched-execution Container",
208 "A container that alternates which of its children is executed; it "
209 "can either change on an interval, or only on a beat.",
210 ACTUATOR_FLAG_CONTAINER, container_cycle_opts,
211 container_cycle_init, container_cycle_cleanup, container_cycle_exec
212 };
213
214 /* **************** container_onbeat **************** */
215 static void
216 container_onbeat_init (GSList ***data)
217 {
218 *data = g_new0 (GSList *, 1);
219 }
220
221 static void
222 container_onbeat_cleanup (GSList **data)
223 {
224 container_cleanup (data);
225 g_free (data);
226 }
227
228 static void
229 container_onbeat_exec (const struct pn_actuator_option *opts,
230 GSList **data)
231 {
232 GSList *child;
233
234 if (pn_new_beat == TRUE)
235 {
236 for (child = *data; child; child = child->next)
237 exec_actuator ((struct pn_actuator *) child->data);
238 }
239 }
240
241 struct pn_actuator_desc builtin_container_onbeat =
242 {
243 "container_onbeat",
244 "OnBeat Container",
245 "A simple container which only triggers on a beat.",
246 ACTUATOR_FLAG_CONTAINER, NULL,
247 PN_ACTUATOR_INIT_FUNC (container_onbeat_init),
248 PN_ACTUATOR_CLEANUP_FUNC (container_onbeat_cleanup),
249 PN_ACTUATOR_EXEC_FUNC (container_onbeat_exec)
250 };