Skip to content

refactor(smudge): Replace custom doubly linked list with std::deque in W3DSmudge - #3021

Open
stephanmeesters wants to merge 5 commits into
TheSuperHackers:mainfrom
stephanmeesters:refactor/smudge-deque
Open

refactor(smudge): Replace custom doubly linked list with std::deque in W3DSmudge#3021
stephanmeesters wants to merge 5 commits into
TheSuperHackers:mainfrom
stephanmeesters:refactor/smudge-deque

Conversation

@stephanmeesters

Copy link
Copy Markdown
  • Replaces DLListClass usages in W3DSmudge with std::deque. std::deque was chosen instead of std::list because we only needed removals/insertions at the front/back (no splicing).
  • Removes some unused functions to reduce the conversion work
  • Replaces bookkeeping field m_usedSmudgeCount with the queue's size

@greptile-apps

greptile-apps Bot commented Jul 27, 2026

Copy link
Copy Markdown

Greptile Summary

Replaces W3DSmudge’s intrusive doubly linked lists and manual active-count bookkeeping with standard deque containers.

  • Updates smudge and smudge-set pooling, traversal, reset, allocation, and destruction operations.
  • Adapts W3D rendering iteration and batch-resume state to deque iterators.
  • Removes two unused removal APIs and derives the active smudge count from container size.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
Core/GameEngine/Include/GameClient/Smudge.h Replaces intrusive-list inheritance and members with typed deque aliases and container-derived counting.
Core/GameEngine/Source/GameClient/System/Smudge.cpp Converts smudge lifecycle and object-pool operations to equivalent deque operations.
Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp Converts rendering and batching traversal from linked nodes to deque iterators.

Reviews (3): Last reviewed commit: "Process review comments #2" | Re-trigger Greptile

@stephanmeesters stephanmeesters added the Refactor Edits the code with insignificant behavior changes, is never user facing label Jul 27, 2026

@Caball009 Caball009 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

AFAIK MSVC's implementation of std::deque uses a very low bucket size, so I don't think we'll get a free performance boost that way, unfortunately.

Comment thread Core/GameEngine/Include/GameClient/Smudge.h Outdated
Comment thread Core/GameEngine/Source/GameClient/System/Smudge.cpp Outdated
Comment on lines +49 to 53
while (!m_freeSmudgeSetList.empty()) {
head = m_freeSmudgeSetList.front();
m_freeSmudgeSetList.pop_front();
delete head;
}

@Caball009 Caball009 Jul 28, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Could also delete while iterating and then clear the container outside the loop. I'm a little fuzzy on the internals of std::deque, so I'm a bit doubtful this would be a performance improvement.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Decided to keep this one for readability, unfortunately vc6 can't do the short hand for-loop

Comment thread Core/GameEngine/Source/GameClient/System/Smudge.cpp Outdated

@xezon xezon left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code looks correct.

SmudgeQueue& smudgeList = (*setIt)->getUsedSmudgeList();

for (; smudge; smudge=smudge->Succ())
while (remainingSmudge != smudgeList.end())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Better: for (; remainingSmudge != smudgeList.end(); ++remainingSmudge)

set=m_usedSmudgeSetList.Head(); //first smudge set that needs rendering.
Smudge *remainingSmudgeStart=set->getUsedSmudgeList().Head(); //first smudge that needs rendering.
setIt=m_usedSmudgeSetList.begin(); //first smudge set that needs rendering.
SmudgeQueue::iterator remainingSmudge = (*setIt)->getUsedSmudgeList().begin(); //first smudge that needs rendering.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe just call it smudgeIt then?

}

while (set)
while (setIt != m_usedSmudgeSetList.end())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Or for (; setIt != m_usedSmudgeSetList.end(); ++setIt)


while ((head = m_usedSmudgeList.Head ()) != nullptr) {
m_usedSmudgeList.Remove_Head ();
m_freeSmudgeList.Add_Head(head); //add to free list

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

comment was removed here, but kept at other places

static SmudgeQueue m_freeSmudgeList; ///<list of unused smudges for use by SmudgeSets.
};

typedef std::deque<SmudgeSet*> SmudgeSetQueue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe call it SmudgeSetDeque

smudgeVertex m_verts[5]; //5 vertices of this smudge (in counter-clockwise order, starting at top-left, ending in center.)
};

typedef std::deque<Smudge*> SmudgeQueue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe call it SmudgeDeque

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Refactor Edits the code with insignificant behavior changes, is never user facing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants