commands: Commands are not a ring buffer anymore.
authorLukas Krickl <lukas@krickl.dev>
Mon, 2 Mar 2026 11:37:59 +0000 (12:37 +0100)
committerLukas Krickl <lukas@krickl.dev>
Mon, 2 Mar 2026 11:37:59 +0000 (12:37 +0100)
Commands now will need to be sorted before they are executed.
This will ensure consistent execution.

src/t_command.c
src/t_command.h
src/tests/t_command.c

index 885400e62f44a61648e6edc4b4d5572d185567cc..29dd1b929c44709755119b9c690f9919b233cdc2 100644 (file)
@@ -1,26 +1,44 @@
 #include "t_command.h"
+#include "u_defs.h"
 
 struct t_command_queue t_command_queue;
 
 u32 t_command_queue_process(void) {
+       u32 i = 0;
+       struct t_command *c;
+       struct lrts_state *state = lrts_state();
+
+       /* TODO: sort command queue by player and tick */
+       
+       /* run all commands until type is 0 
+        * or the ticks do not match */
+       for (i = 0; i < t_command_queue.idx; i++) {
+               c = &t_command_queue.buffer[i];
+               if (c->type == T_COMMAND_NONE || c->run_at_tick > state->tick_count) {
+                       break;
+               }
+               t_command_exec(c);
+       }
+
        return 0;
 }
 
 lrts_bool t_command_exec(struct t_command *c) {
-       LRTS_UNUSED(c);
+       if (c->type == T_COMMAND_NONE) {
+               u_log(U_LOG_WARN, "Command of type none was passed to exec\n");
+               return LRTS_TRUE;
+       }
+       
+       c->type = T_COMMAND_NONE;
        return LRTS_TRUE;
 }
 
 void t_command_push(struct t_command c) {
-       if (t_command_queue.write_idx >= T_COMMANDS_MAX) {
-               t_command_queue.write_idx = 0;
-       }
-       
-       if (t_command_queue.buffer[t_command_queue.write_idx].type != T_COMMAND_NONE) {
+       if (t_command_queue.idx >= T_COMMANDS_MAX) {
                u_log(U_LOG_CRIT, "Command queue overflow!\n");
                p_exit(P_EXIT_FAIL);
                return;
        }
 
-       t_command_queue.buffer[t_command_queue.write_idx++] = c;
+       t_command_queue.buffer[t_command_queue.idx++] = c;
 }
index 5bb9d12840fdd9a899424d98384c088b756e83d1..ad35c194cc7157d858ee37dff2e97aa6d6626d5d 100644 (file)
@@ -12,6 +12,8 @@
 
 enum t_command_type {
        T_COMMAND_NONE = 0,
+       /* no-op command */
+       T_COMMAND_NOOP,
        /* moves camera in the direction of a 
         * provided vector
         */
@@ -30,18 +32,18 @@ struct t_command {
        enum t_command_type type;       
        enum t_command_flags flags;
        u32 run_at_tick;
+       u8 player;
        union t_command_data d;
 };
 
 /**
  * This is a comamnd buffer
  * It wraps around and keeps track of the current command
- * This is a ring buffer. If the current write is already allocated (not type NONE 
- * the program will exit!)
+ * The command queue should always be sorted by command type index, player number and ticks
+ * to ensure consistent execution
  */
 struct t_command_queue {
-       u16 write_idx;
-       u16 read_idx;
+       u16 idx;
        struct t_command buffer[T_COMMANDS_MAX];
 };
 
index 2d6a033ddb30c17ef68082a19d203f6256bff273..99ccef69ad687ca74edb7ffe50fcfc304b676b36 100644 (file)
@@ -7,14 +7,14 @@ int test_t_command_push(void) {
 
        t.type = T_COMMAND_MOVE_CAMERA;
        t_command_push(t);
-       T_ASSERT(t_command_queue.write_idx == 1, ("write index moved\n"));
+       T_ASSERT(t_command_queue.idx == 1, ("write index moved\n"));
        T_ASSERT(t_command_queue.buffer[0].type == T_COMMAND_MOVE_CAMERA, ("command written\n"));
 
        for (i = 0; i < T_COMMANDS_MAX+1; i++) {
                t_command_push(t);
        }
        
-       T_ASSERT(t_command_queue.write_idx == 0, ("write index out of bounds"));
+       T_ASSERT(t_command_queue.idx == T_COMMANDS_MAX, ("write index out of bounds\n"));
 
        return 0;
 }