]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
cbuf: use standard parsing and buffering of deferred strings
authorbones_was_here <bones_was_here@xonotic.au>
Mon, 25 Sep 2023 08:02:29 +0000 (18:02 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Tue, 26 Sep 2023 04:40:25 +0000 (14:40 +1000)
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>
cmd.c
cmd.h

diff --git a/cmd.c b/cmd.c
index deb9a4a66b11706ae19ccf817a852d8f8c827db9..8a301066fd644556bacd6cc45784eaee9651ebc5 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -74,11 +74,13 @@ Cmd_Defer_f
 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;
+       unsigned int cmdsize;
 
        if(Cmd_Argc(cmd) == 1)
        {
@@ -93,25 +95,19 @@ static void Cmd_Defer_f (cmd_state_t *cmd)
        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);
+               }
        }
-       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));
+               Cbuf_Lock(cbuf);
 
-               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(&current->list, &cbuf->deferred);
+               Cbuf_Unlock(cbuf);
        }
        else
        {
@@ -362,25 +358,25 @@ Cbuf_Execute_Deferred --blub
 */
 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 (eat < (1.0 / 120.0))
+       if (eat < 1/128)
                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)
                {
-                       cbuf->size += current->length;
-                       List_Move(&current->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(&current->list, &cbuf->free); // make deferred string memory available for reuse
+                       cbuf->size -= current->length;
                }
        }
 }
diff --git a/cmd.h b/cmd.h
index fddd2a08d88b25883264e9c9d6388401fcc59fd0..99241fcf753618591fa61052398d2280119702d4 100644 (file)
--- a/cmd.h
+++ b/cmd.h
@@ -158,7 +158,7 @@ typedef struct cmd_input_s
 {
        llist_t list;
        cmd_state_t *source;
-       double delay;
+       vec_t delay;
        size_t size;
        size_t length;
        char *text;