-#include <stdlib.h>
+/*
+ * Copyright (C) 2003-2010 Neverball authors
+ *
+ * NEVERBALL 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; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * 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.
+ */
#include "solid_cmd.h"
#include "cmd.h"
-#include "list.h"
/*---------------------------------------------------------------------------*/
-/*
- * sol_step generates a few commands that supersede previous commands
- * of the same type generated by the same sol_step invocation. The
- * code below provides the means to accumulate commands for later
- * addition to the command queue, while making sure that commands that
- * have been superseded during the accumulation are discarded.
- */
-
-int sol_cmd_defer;
-
static void (*cmd_enq_fn)(const union cmd *);
-static List deferred_cmds;
-
-void sol_cmd_enq_deferred(void)
-{
- List l, r;
-
- /* Reverse the list to preserve original command order. */
-
- for (r = NULL, l = deferred_cmds;
- l;
- r = list_cons(l->data, r), l = list_rest(l));
-
- /* Enqueue commands. */
-
- for (; r; r = list_rest(r))
- {
- if (cmd_enq_fn)
- cmd_enq_fn(r->data);
-
- free(r->data);
- }
-
- deferred_cmds = NULL;
-}
void sol_cmd_enq(const union cmd *new)
{
- if (sol_cmd_defer)
- {
- union cmd *copy;
- List l, p;
-
- for (p = NULL, l = deferred_cmds; l; p = l, l = l->next)
- {
- union cmd *cur = l->data;
-
- /* Remove element made obsolete by the new command. */
-
- if (new->type == cur->type &&
- ((new->type == CMD_BODY_TIME &&
- new->bodytime.bi == cur->bodytime.bi) ||
- (new->type == CMD_BODY_PATH &&
- new->bodypath.bi == cur->bodypath.bi)))
- {
- free(cur);
-
- if (p)
- p->next = list_rest(l);
- else
- deferred_cmds = list_rest(l);
-
- /*
- * The operation above made the list pointer useless
- * for the variable update part of the loop, and it
- * seems a bit involved to recover from that in a
- * proper fashion. Fortunately, this very block
- * ensures that there's only one element to remove, so
- * no more iterations are needed.
- */
-
- l = NULL;
- break;
- }
- }
-
- if ((copy = malloc(sizeof (*copy))))
- {
- *copy = *new;
- deferred_cmds = list_cons(copy, deferred_cmds);
- }
- }
- else if (cmd_enq_fn)
+ if (cmd_enq_fn)
cmd_enq_fn(new);
}