2 * Copyright (c) 2016-2019, S. Gilles <sgilles@math.umd.edu>
4 * Permission to use, copy, modify, and/or distribute this software
5 * for any purpose with or without fee is hereby granted, provided
6 * that the above copyright notice and this permission notice appear
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
13 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
14 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 static uint_fast8_t should_quit
= 0;
32 /* if (verbose) printf(...); */
34 history(int verbose
, const char *format
, ...)
43 va_start(arglist
, format
);
44 vprintf(format
, arglist
);
49 /* Having received some kind of input, change state accordingly */
51 state_transition(struct ui_event
*e
, struct quiver
*q
, int verbose
)
55 const char *errstr
= 0;
60 history(verbose
, "quit");
66 e
->idx_1
>= q
->v_num
) {
70 history(verbose
, "rename \"%s\" to \"%s\"", q
->v
[e
->idx_1
].name
,
73 if ((ret
= quiver_rename_vertex(q
, e
->idx_1
, e
->str
,
75 fprintf(stderr
, "%s\n", UBSAFES(errstr
));
78 ui_respond_quiver_change();
87 history(verbose
, "save to \"%s\"", e
->str
);
89 if (!(f
= fopen(e
->str
, "w"))) {
92 } else if ((ret
= quiver_save_to_file(q
, f
, &errstr
))) {
93 fprintf(stderr
, "%s\n", UBSAFES(errstr
));
95 ui_respond_successful_save(e
->str
);
106 history(verbose
, "load from \"%s\"", e
->str
);
108 if (!(f
= fopen(e
->str
, "r"))) {
111 } else if ((ret
= quiver_load_from_file(q
, f
, &errstr
))) {
112 fprintf(stderr
, "%s\n", UBSAFES(errstr
));
114 ui_respond_successful_load(e
->str
);
117 ui_respond_quiver_change();
121 if (e
->idx_1
< q
->v_num
) {
122 history(verbose
, "mutate at \"%s\" (%zu)",
123 q
->v
[e
->idx_1
].name
, e
->idx_1
);
125 if ((ret
= quiver_mutate(q
, e
->idx_1
, 0, &errstr
))) {
126 fprintf(stderr
, "%s\n", UBSAFES(errstr
));
138 history(verbose
, "new vertex \"%s\" at (%d, %d)", e
->str
,
141 if ((ret
= quiver_add_vertex(q
, 0, e
->str
, 1, e
->int_1
,
142 e
->int_2
, e
->z
, &errstr
))) {
143 fprintf(stderr
, "%s\n", UBSAFES(errstr
));
146 ui_respond_quiver_change();
150 if (e
->idx_1
< q
->v_num
&&
151 e
->idx_2
< q
->v_num
) {
153 "add edge from \"%s\" (%zu) to \"%s\" (%zu), weight %d/%d",
154 q
->v
[e
->idx_1
].name
, e
->idx_1
,
156 e
->idx_2
, (int) e
->a
, (int) e
->b
);
158 if ((ret
= quiver_add_to_edge(q
, e
->idx_1
, e
->idx_2
,
159 e
->a
, e
->b
, &errstr
))) {
160 fprintf(stderr
, "%s\n", UBSAFES(errstr
));
165 case ET_DELETE_VERTEX
:
167 if (e
->idx_1
< q
->v_num
) {
168 history(verbose
, "delete vertex \"%s\" (%zu)",
169 q
->v
[e
->idx_1
].name
, e
->idx_1
);
171 if ((ret
= quiver_delete_vertex(q
, e
->idx_1
,
173 fprintf(stderr
, "%s\n", UBSAFES(errstr
));
177 ui_respond_quiver_change();
181 if (e
->idx_1
< q
->v_num
&&
182 e
->idx_2
< q
->v_num
) {
183 size_t i12
= e
->idx_1
* q
->v_len
+ e
->idx_2
;
184 size_t i21
= e
->idx_2
* q
->v_len
+ e
->idx_1
;
187 "remove edge between \"%s\" (%zu) and \"%s\" (%zu)",
188 q
->v
[e
->idx_1
].name
, e
->idx_1
,
191 q
->e
[i12
] = (struct rational
) { .p
= 0, .q
= 1 };
192 q
->e
[i21
] = (struct rational
) { .p
= 0, .q
= 1 };
196 case ET_CHANGE_FATNESS
:
198 if (e
->idx_1
< q
->v_num
&&
199 q
->v
[e
->idx_1
].fatness
+ e
->int_1
> 0 &&
200 q
->v
[e
->idx_1
].fatness
+ e
->int_1
< UINT_FAST8_MAX
) {
202 "change fatness of vertex \"%s\" (%zu) to %d",
203 q
->v
[e
->idx_1
].name
, e
->idx_1
,
204 q
->v
[e
->idx_1
].fatness
+
207 if ((ret
= quiver_adjust_fatness(q
, e
->idx_1
, e
->int_1
,
209 fprintf(stderr
, "%s\n", UBSAFES(errstr
));
214 case ET_CHANGE_COLOR
:
216 if (e
->idx_1
< q
->v_num
) {
218 "change color of vertex \"%s\" (%zu) to %#010lx",
219 q
->v
[e
->idx_1
].name
, e
->idx_1
, (long int) e
->z
);
221 if ((ret
= quiver_color_vertex(q
, e
->idx_1
, e
->z
,
223 fprintf(stderr
, "%s\n", UBSAFES(errstr
));
241 main(int argc
, char **argv
)
244 struct quiver q
= { 0 };
247 const char *initial_file
= 0;
251 setlocale(LC_ALL
, "");
253 while ((opt
= getopt(argc
, argv
, "vf:")) != -1) {
259 initial_file
= optarg
;
264 if ((ret
= ui_init(&q
))) {
268 /* Preload a basic quiver */
272 if ((f
= fopen(initial_file
, "r"))) {
273 if (!(quiver_load_from_file(&q
, f
, 0))) {
274 if ((ret
= ui_respond_successful_load(
285 quiver_add_vertex(&q
, &va
, "A", 1, -50, 50, 0x008282b2, 0);
286 quiver_add_vertex(&q
, &vb
, "B", 1, 0, -75, 0x008282b2, 0);
287 quiver_add_vertex(&q
, &vc
, "C", 1, 75, 0, 0x008282b2, 0);
288 quiver_add_to_edge(&q
, va
, vb
, 1, 1, 0);
289 quiver_add_to_edge(&q
, vc
, va
, 1, 1, 0);
292 if ((ret
= ui_respond_quiver_change())) {
296 if ((ret
= ui_start_frame())) {
300 uint_fast8_t more_evs
= 0;
301 struct ui_event e
= { 0 };
303 while (!should_quit
) {
304 /* includes framelimiting delay */
305 if ((ret
= ui_finish_frame())) {
312 if ((ret
= ui_get_event(&e
, &more_evs
))) {
317 state_transition(&e
, &q
, verbose
);
321 if ((ret
= ui_start_frame())) {