Skip to content

refactor(messaging): replace GameMessage argument linked list with std::vector#2700

Open
RikuAnt wants to merge 12 commits into
TheSuperHackers:mainfrom
RikuAnt:feature/#2630_Refactor_message_arguments_to_vector
Open

refactor(messaging): replace GameMessage argument linked list with std::vector#2700
RikuAnt wants to merge 12 commits into
TheSuperHackers:mainfrom
RikuAnt:feature/#2630_Refactor_message_arguments_to_vector

Conversation

@RikuAnt
Copy link
Copy Markdown

@RikuAnt RikuAnt commented May 11, 2026

Fixes #2630

GameMessage and NetGameCommandMsg stored their arguments in a linked list (m_argList/m_argTail/m_argCount/m_next). Since arguments are only ever appended and iterated in order, this is replaced with a std::vector, removing the manual pointer threading and simplifying all related code. A DEBUG_ASSERTCRASH is added to guard the existing 255-argument limit.

AI usage was minimal. All code has been reviewed and tested to best of my capability.

TODO:

  • Replicate in Generals.

RikuAnt added 3 commits May 12, 2026 00:04
…rs#2630)

Simpler and cleaner control. Improves loop performance significantly via cache hits
and brings random index access down to O(1)
Only affects parts that relied on the linked list functionality of the GameMessageArguments
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 11, 2026

Greptile Summary

This PR replaces the manual linked-list argument storage (m_argList/m_argTail/m_argCount/m_next) in GameMessage and NetGameCommandMsg with std::vector<const GameMessageArgument*>, applying the change consistently across both the Generals and GeneralsMD code paths.

  • GameMessageArgument::m_next is removed, and m_argList/m_argTail/m_argCount members are replaced by a single std::vector<const GameMessageArgument*> m_argList. All append, iterate, and free code is updated accordingly. const-correctness is maintained: the vector stores const GameMessageArgument*, allocArg() returns a non-const raw pointer for initialization, and const_cast is used only in the destructor where ownership is clear.
  • getArguments() is a new accessor returning const std::vector<const GameMessageArgument*>&, used by NetGameCommandMsg and RecorderClass to replace the old index-based loops. A DEBUG_ASSERTCRASH guards the 255-argument limit that was previously enforced implicitly by the UnsignedByte counter type.

Confidence Score: 5/5

Safe to merge. The linked-list-to-vector swap is applied consistently across all four source/header pairs and the change is straightforward.

Every allocation, iteration, and deletion site has been updated in both the Generals and GeneralsMD trees. Const-correctness is preserved throughout: the vector stores const GameMessageArgument*, allocArg() returns a mutable pointer only for initialization, and const_cast is used exclusively in the destructor where ownership is unambiguous. The previous-thread concern about a reinterpret_cast between incompatible vector specialisations does not appear in this version — the member type and the accessor return type are the same specialisation. No logic changes were made beyond the storage model.

No files require special attention.

Important Files Changed

Filename Overview
Generals/Code/GameEngine/Include/Common/MessageStream.h Removes m_next/m_argList/m_argTail/m_argCount; adds std::vector<const GameMessageArgument*> and getArguments() accessor with correct const-correctness. Inline getArgumentCount() adds a DEBUG_ASSERTCRASH guard.
Generals/Code/GameEngine/Source/Common/MessageStream.cpp Constructor, destructor, getArgument(), getArgumentDataType(), and allocArg() all correctly updated to use vector semantics; const_cast used appropriately in destructor.
GeneralsMD/Code/GameEngine/Include/Common/MessageStream.h Mirror of Generals changes; same vector refactoring applied correctly for Zero Hour expansion code path.
GeneralsMD/Code/GameEngine/Source/Common/MessageStream.cpp Mirror of Generals .cpp changes; all linked-list traversal replaced with index-based vector access.
Core/GameEngine/Include/GameNetwork/NetCommandMsg.h m_numArgs, m_argSize, m_argList (ptr), m_argTail removed; replaced with std::vector<const GameMessageArgument*>. Forward declaration of GameMessageArgument added. std::vector is available transitively via NetworkDefs.h → MessageStream.h → STLTypedefs.h.
Core/GameEngine/Source/GameNetwork/NetCommandMsg.cpp Constructor, copy-constructor, destructor, addArgument(), and constructGameMessage() all cleanly updated; reserve() call added when copying args from a GameMessage.
Generals/Code/GameEngine/Source/Common/Recorder.cpp Switches from getArgumentCount()/getArgumentDataType()/getArgument() loop to getArguments() vector range-for, simplifying the write path.
GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp Same Recorder simplification as the Generals path.

Reviews (7): Last reviewed commit: "fix: remove inconsistent todo leftover c..." | Re-trigger Greptile

Comment thread GeneralsMD/Code/GameEngine/Include/Common/MessageStream.h Outdated
Comment thread Core/GameEngine/Source/GameNetwork/NetCommandMsg.cpp Outdated
Comment thread Core/GameEngine/Source/GameNetwork/NetCommandMsg.cpp Outdated
Comment thread Core/GameEngine/Include/GameNetwork/NetCommandMsg.h Outdated
Comment thread Core/GameEngine/Include/GameNetwork/NetCommandMsg.h Outdated
Comment thread GeneralsMD/Code/GameEngine/Source/Common/MessageStream.cpp Outdated
// TheSuperHackers @refactor RiQQ 11/05/2026 Replaced linked list with std::vector for argument storage
GameMessage::Type m_type;
GameMessageArgument *m_argList, *m_argTail;
std::vector<GameMessageArgument*> m_argList;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be std::vector<const GameMessageArgument*>?

Copy link
Copy Markdown
Author

@RikuAnt RikuAnt May 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This collides with the pooled object delete functionality deleteInstance in NetGameCommandMsg destructor. We can use const_cast if this is the preferred way? I made the change in favor of const_cast over the reinterpret_cast that the AI first recommended

Copy link
Copy Markdown

@Caball009 Caball009 May 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. The const_cast is not ideal, but that's price we've to pay, I suppose. I think the current way with <const T*> is preferable, but I'll let this conversation stay unresolved for now.

(const_cast is right here; I'm not sure whether reinterpret_cast would even compile here).

RikuAnt added 3 commits May 12, 2026 16:22
- Return GameMessageArguments as const
- Style fixes (remove blank space, indent and space out too packed methods)
- Remove vector includes; already included from precompiled header
Comment thread GeneralsMD/Code/GameEngine/Include/Common/MessageStream.h Outdated
@RikuAnt RikuAnt requested a review from Caball009 May 12, 2026 14:24
@L3-M L3-M added Minor Severity: Minor < Major < Critical < Blocker ZH Relates to Zero Hour Refactor Edits the code with insignificant behavior changes, is never user facing Network Anything related to network, servers labels May 12, 2026
@L3-M L3-M added this to the Code foundation build up milestone May 12, 2026
Comment thread Core/GameEngine/Source/GameNetwork/NetCommandMsg.cpp Outdated
Comment thread Core/GameEngine/Source/GameNetwork/NetCommandMsg.cpp
Comment thread GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp Outdated
// TheSuperHackers @refactor RiQQ 11/05/2026 Replaced linked list with std::vector for argument storage
GameMessage::Type m_type;
GameMessageArgument *m_argList, *m_argTail;
std::vector<GameMessageArgument*> m_argList;
Copy link
Copy Markdown

@Caball009 Caball009 May 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. The const_cast is not ideal, but that's price we've to pay, I suppose. I think the current way with <const T*> is preferable, but I'll let this conversation stay unresolved for now.

(const_cast is right here; I'm not sure whether reinterpret_cast would even compile here).

Comment thread Core/GameEngine/Include/GameNetwork/NetCommandMsg.h
@Caball009
Copy link
Copy Markdown

Caball009 commented May 13, 2026

Good effort.

Generals fails to compile for now, but it's probably most convenient to wait for xezon's feedback before you replicate the changes from ZH to Gen.

@xezon
Copy link
Copy Markdown

xezon commented May 14, 2026

Is Caballs review addressed?

@RikuAnt
Copy link
Copy Markdown
Author

RikuAnt commented May 14, 2026

Addressed now @xezon Also included the mirrored changes into Generals/ side

Comment thread Generals/Code/GameEngine/Include/Common/MessageStream.h Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Minor Severity: Minor < Major < Critical < Blocker Network Anything related to network, servers Refactor Edits the code with insignificant behavior changes, is never user facing ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inefficient lookups in GameMessage::getArgument, GameMessage::getArgumentDataType

4 participants