Fixes https://gitlab.com/xonotic/darkplaces/-/issues/377
Matches div0-stable in that the deferred string is not parsed until
execution time and is printed verbatim in the pending command list.
Also fixes unsafe linked list removal and removes its workaround.
Slightly improves timing precsion and PRVM_64 / 32 support.
Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
Cause a command to be executed after a delay.
============
*/
Cause a command to be executed after a delay.
============
*/
-static cmd_input_t *Cbuf_NodeGet(cmd_buf_t *cbuf, cmd_input_t *existing);
+static void Cbuf_ParseText(cmd_state_t *cmd, llist_t *head, cmd_input_t *existing, const char *text, qbool allowpending);
+static void Cbuf_LinkString(cmd_state_t *cmd, llist_t *head, cmd_input_t *existing, const char *text, qbool leavepending, unsigned int cmdsize);
static void Cmd_Defer_f (cmd_state_t *cmd)
{
cmd_input_t *current;
cmd_buf_t *cbuf = cmd->cbuf;
static void Cmd_Defer_f (cmd_state_t *cmd)
{
cmd_input_t *current;
cmd_buf_t *cbuf = cmd->cbuf;
else if(Cmd_Argc(cmd) == 2 && !strcasecmp("clear", Cmd_Argv(cmd, 1)))
{
while(!List_Is_Empty(&cbuf->deferred))
else if(Cmd_Argc(cmd) == 2 && !strcasecmp("clear", Cmd_Argv(cmd, 1)))
{
while(!List_Is_Empty(&cbuf->deferred))
+ {
+ cbuf->size -= List_Entry(cbuf->deferred.next, cmd_input_t, list)->length;
List_Move_Tail(cbuf->deferred.next, &cbuf->free);
List_Move_Tail(cbuf->deferred.next, &cbuf->free);
- else if(Cmd_Argc(cmd) == 3)
+ else if(Cmd_Argc(cmd) == 3 && (cmdsize = strlen(Cmd_Argv(cmd, 2))) )
- const char *text = Cmd_Argv(cmd, 2);
- current = Cbuf_NodeGet(cbuf, NULL);
- current->length = strlen(text);
- current->source = cmd;
- current->delay = atof(Cmd_Argv(cmd, 1));
- if(current->size < current->length)
- {
- current->text = (char *)Mem_Realloc(cbuf_mempool, current->text, current->length + 1);
- current->size = current->length;
- }
+ Cbuf_LinkString(cmd, &cbuf->deferred, NULL, Cmd_Argv(cmd, 2), false, cmdsize);
+ List_Entry(cbuf->deferred.prev, cmd_input_t, list)->delay = atof(Cmd_Argv(cmd, 1));
- strlcpy(current->text, text, current->length + 1);
-
- List_Move_Tail(¤t->list, &cbuf->deferred);
*/
static void Cbuf_Execute_Deferred (cmd_buf_t *cbuf)
{
*/
static void Cbuf_Execute_Deferred (cmd_buf_t *cbuf)
{
- cmd_input_t *current;
- double eat;
+ cmd_input_t *current, *n;
+ vec_t eat;
if (host.realtime - cbuf->deferred_oldtime < 0 || host.realtime - cbuf->deferred_oldtime > 1800)
cbuf->deferred_oldtime = host.realtime;
eat = host.realtime - cbuf->deferred_oldtime;
if (host.realtime - cbuf->deferred_oldtime < 0 || host.realtime - cbuf->deferred_oldtime > 1800)
cbuf->deferred_oldtime = host.realtime;
eat = host.realtime - cbuf->deferred_oldtime;
- if (eat < (1.0 / 120.0))
return;
cbuf->deferred_oldtime = host.realtime;
return;
cbuf->deferred_oldtime = host.realtime;
- List_For_Each_Entry(current, &cbuf->deferred, cmd_input_t, list)
+ List_For_Each_Entry_Safe(current, n, &cbuf->deferred, cmd_input_t, list)
{
current->delay -= eat;
if(current->delay <= 0)
{
{
current->delay -= eat;
if(current->delay <= 0)
{
- cbuf->size += current->length;
- List_Move(¤t->list, &cbuf->start);
- // We must return and come back next frame or the engine will freeze. Fragile... like glass :3
- return;
+ Cbuf_AddText(current->source, current->text); // parse deferred string and append its cmdstring(s)
+ List_Entry(cbuf->start.prev, cmd_input_t, list)->pending = false; // faster than div0-stable's Cbuf_AddText(";\n");
+ List_Move_Tail(¤t->list, &cbuf->free); // make deferred string memory available for reuse
+ cbuf->size -= current->length;
{
llist_t list;
cmd_state_t *source;
{
llist_t list;
cmd_state_t *source;
size_t size;
size_t length;
char *text;
size_t size;
size_t length;
char *text;