comparison src/libmlk-core/core/action.c @ 320:8f9937403749

misc: improve loading of data
author David Demelier <markand@malikania.fr>
date Fri, 01 Oct 2021 20:30:00 +0200
parents libmlk-core/core/action.c@d01e83210ca2
children 1e06f871dc63
comparison
equal deleted inserted replaced
319:b843eef4cc35 320:8f9937403749
1 /*
2 * action.c -- action states
3 *
4 * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <assert.h>
20 #include <stddef.h>
21 #include <string.h>
22
23 #include "action.h"
24
25 #define ACTION_FOREACH(st, iter) \
26 for (size_t i = 0; i < ACTION_STACK_MAX && ((iter) = (st)->actions[i], 1); ++i)
27
28 void
29 action_handle(struct action *act, const union event *ev)
30 {
31 assert(act);
32 assert(ev);
33
34 if (act->handle)
35 act->handle(act, ev);
36 }
37
38 int
39 action_update(struct action *act, unsigned int ticks)
40 {
41 assert(act);
42
43 if (act->update)
44 return act->update(act, ticks);
45
46 /* No function means immortal action. */
47 return 0;
48 }
49
50 void
51 action_draw(struct action *act)
52 {
53 assert(act);
54
55 if (act->draw)
56 act->draw(act);
57 }
58
59 void
60 action_end(struct action *act)
61 {
62 assert(act);
63
64 if (act->end)
65 act->end(act);
66 }
67
68 void
69 action_finish(struct action *act)
70 {
71 assert(act);
72
73 if (act->finish)
74 act->finish(act);
75 }
76
77 void
78 action_stack_init(struct action_stack *st)
79 {
80 assert(st);
81
82 memset(st, 0, sizeof (*st));
83 }
84
85 int
86 action_stack_add(struct action_stack *st, struct action *act)
87 {
88 assert(st);
89 assert(act);
90
91 for (size_t i = 0; i < ACTION_STACK_MAX; ++i) {
92 if (!st->actions[i]) {
93 st->actions[i] = act;
94 return 0;
95 }
96 }
97
98 return -1;
99 }
100
101 void
102 action_stack_handle(struct action_stack *st, const union event *ev)
103 {
104 assert(st);
105 assert(ev);
106
107 struct action *act;
108
109 ACTION_FOREACH(st, act)
110 if (act)
111 action_handle(act, ev);
112 }
113
114 int
115 action_stack_update(struct action_stack *st, unsigned int ticks)
116 {
117 assert(st);
118
119 struct action *act;
120
121 for (size_t i = 0; i < ACTION_STACK_MAX; ++i) {
122 act = st->actions[i];
123
124 if (act && action_update(act, ticks)) {
125 action_end(act);
126 action_finish(act);
127 st->actions[i] = NULL;
128 }
129 }
130
131 /*
132 * We process all actions again in case the user modified the stack
133 * within their update function.
134 */
135 return action_stack_completed(st);
136 }
137
138 void
139 action_stack_draw(const struct action_stack *st)
140 {
141 assert(st);
142
143 struct action *act;
144
145 ACTION_FOREACH(st, act)
146 if (act)
147 action_draw(act);
148 }
149
150 int
151 action_stack_completed(const struct action_stack *st)
152 {
153 assert(st);
154
155 struct action *act;
156
157 ACTION_FOREACH(st, act)
158 if (act)
159 return 0;
160
161 return 1;
162 }
163
164 void
165 action_stack_finish(struct action_stack *st)
166 {
167 assert(st);
168
169 struct action *act;
170
171 ACTION_FOREACH(st, act) {
172 if (act) {
173 action_end(act);
174 action_finish(act);
175 }
176 }
177
178 memset(st, 0, sizeof (*st));
179 }