7 /*---------------------------------------------------------------------------*/
10 * sol_step generates a few commands that supersede previous commands
11 * of the same type generated by the same sol_step invocation. The
12 * code below provides the means to accumulate commands for later
13 * addition to the command queue, while making sure that commands that
14 * have been superseded during the accumulation are discarded.
19 static void (*cmd_enq_fn)(const union cmd *);
20 static List deferred_cmds;
22 void sol_cmd_enq_deferred(void)
26 /* Reverse the list to preserve original command order. */
28 for (r = NULL, l = deferred_cmds;
30 r = list_cons(l->data, r), l = list_rest(l));
32 /* Enqueue commands. */
34 for (; r; r = list_rest(r))
45 void sol_cmd_enq(const union cmd *new)
52 for (p = NULL, l = deferred_cmds; l; p = l, l = l->next)
54 union cmd *cur = l->data;
56 /* Remove element made obsolete by the new command. */
58 if (new->type == cur->type &&
59 ((new->type == CMD_BODY_TIME &&
60 new->bodytime.bi == cur->bodytime.bi) ||
61 (new->type == CMD_BODY_PATH &&
62 new->bodypath.bi == cur->bodypath.bi)))
67 p->next = list_rest(l);
69 deferred_cmds = list_rest(l);
72 * The operation above made the list pointer useless
73 * for the variable update part of the loop, and it
74 * seems a bit involved to recover from that in a
75 * proper fashion. Fortunately, this very block
76 * ensures that there's only one element to remove, so
77 * no more iterations are needed.
85 if ((copy = malloc(sizeof (*copy))))
88 deferred_cmds = list_cons(copy, deferred_cmds);
95 void sol_cmd_enq_func(void (*enq_fn) (const union cmd *))
100 /*---------------------------------------------------------------------------*/