Skip to content

feature(headless): Add ParticleSystemManagerDummy for headless mode#2247

Open
bobtista wants to merge 11 commits intoTheSuperHackers:mainfrom
bobtista:bobtista/particle-system-manager-dummy
Open

feature(headless): Add ParticleSystemManagerDummy for headless mode#2247
bobtista wants to merge 11 commits intoTheSuperHackers:mainfrom
bobtista:bobtista/particle-system-manager-dummy

Conversation

@bobtista
Copy link

@bobtista bobtista commented Feb 2, 2026

Summary

  • Adds ParticleSystemManagerDummy class in Core/GameEngine/Include/GameClient/ParticleSys.h with no-op implementations for headless mode
  • GameEngine.cpp uses dummy when m_headless is true
  • Empty crc/xfer/loadPostProcess to skip particle system block in saves

Related

Split from #2139 per @xezon's suggestion to review each dummy class separately.

@greptile-apps
Copy link

greptile-apps bot commented Feb 2, 2026

Greptile Summary

This PR introduces ParticleSystemManagerDummy, a no-op subclass of ParticleSystemManager, and wires it up through the createParticleSystemManager(Bool dummy) factory to be used whenever TheGlobalData->m_headless is true. The design is sound: rendering methods (doParticles, queueParticleRender) and serialization methods (crc, xfer, loadPostProcess) are suppressed, while the base-class init, reset, and update still execute — correctly preserving particle-system game-logic in headless sessions without any renderer dependency.

Key changes:

  • Core/GameEngine/Include/GameClient/ParticleSys.h: new ParticleSystemManagerDummy class with no-op overrides for all render and snapshot methods
  • Generals/ and GeneralsMD/ GameEngine.h: createParticleSystemManager() signature updated to createParticleSystemManager(Bool dummy)
  • Win32GameEngine.h (both variants): adds #include "GameClient/ParticleSys.h" and routes factory selection via ternary — the ternary on a single line is quite long and would benefit from being rewritten as an if/else for debugger breakpoint support, consistent with project style
  • GameEngine.cpp (both variants): call site updated to forward TheGlobalData->m_headless

Confidence Score: 4/5

  • This PR is safe to merge — the changes are small, well-scoped, and correctly isolated to headless mode; only a style concern remains.
  • The dummy class is correct and complete: all pure-virtual methods are overridden, serialization is intentionally skipped, and the real manager path is unchanged. The only actionable issue is the long one-liner ternary in the factory inline functions which should be reformatted as if/else per project style guidelines for debuggability.
  • Generals/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h and GeneralsMD/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h (line 97 in both — ternary inline)

Important Files Changed

Filename Overview
Core/GameEngine/Include/GameClient/ParticleSys.h Adds ParticleSystemManagerDummy that correctly overrides all pure-virtual and serialization methods as no-ops; base-class init/reset/update remain active so particle logic still runs (only rendering is suppressed), which is the right design for headless mode.
Generals/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h Adds ParticleSys.h include and updates createParticleSystemManager to accept a Bool dummy flag, returning the appropriate implementation via a ternary; the long one-liner ternary would benefit from an if/else split for debugger breakpoint support per project style.
GeneralsMD/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h Mirrors the Generals version — same ParticleSys.h include and same createParticleSystemManager(Bool dummy) ternary; same style note about if/else applies here too.
Generals/Code/GameEngine/Include/Common/GameEngine.h Pure-virtual signature updated from createParticleSystemManager() to createParticleSystemManager(Bool dummy); straightforward interface change with no issues.
GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h Identical update to the Zero Hour counterpart of GameEngine.h — no issues.
Generals/Code/GameEngine/Source/Common/GameEngine.cpp Passes TheGlobalData->m_headless to createParticleSystemManager; correct call-site update, no issues.
GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp Identical call-site update as the Generals version; correct and consistent.

Sequence Diagram

sequenceDiagram
    participant GE as GameEngine::init()
    participant GD as TheGlobalData
    participant WGE as Win32GameEngine
    participant PSM as ParticleSystemManager (real)
    participant PSMD as ParticleSystemManagerDummy

    GE->>GD: read m_headless
    GE->>WGE: createParticleSystemManager(m_headless)
    alt dummy == false (normal mode)
        WGE->>PSM: NEW W3DParticleSystemManager
        PSM-->>GE: full manager instance
        Note over PSM: doParticles(), queueParticleRender(),<br/>crc/xfer/loadPostProcess all active
    else dummy == true (headless mode)
        WGE->>PSMD: NEW ParticleSystemManagerDummy
        PSMD-->>GE: dummy manager instance
        Note over PSMD: doParticles() → no-op<br/>queueParticleRender() → no-op<br/>crc/xfer/loadPostProcess → no-op<br/>init/reset/update → base class (runs normally)
    end
    GE->>GE: initSubsystem(TheParticleSystemManager, ...)
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: Generals/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h
Line: 97

Comment:
**Ternary on single line reduces debuggability**

Rule 16b9b669 asks for condition and body to be on separate lines so that precise debugger breakpoints can be set. Although a ternary operator is not technically an `if` statement, using it here produces the same problem: it is impossible to break on just one branch. The identical pattern appears in `GeneralsMD/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h:97` as well.

Consider replacing the one-liner ternary with a proper `if`/`else`:

```cpp
inline ParticleSystemManager* Win32GameEngine::createParticleSystemManager(Bool dummy)
{
    if (dummy)
        return NEW ParticleSystemManagerDummy;
    return NEW W3DParticleSystemManager;
}
```

This makes it straightforward to break on either branch and keeps the style consistent with the rest of the codebase.

**Rule Used:** Always place if/else/for/while statement bodies on... ([source](https://app.greptile.com/review/custom-context?memory=16b9b669-b823-49be-ba5b-2bd30ff3ba6d))

**Learnt From**
[TheSuperHackers/GeneralsGameCode#2067](https://github.com/TheSuperHackers/GeneralsGameCode/pull/2067#discussion_r2706274626)

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 1fb5d2a

@xezon xezon added Enhancement Is new feature or request Debug Is mostly debug functionality labels Mar 10, 2026
@bobtista bobtista force-pushed the bobtista/particle-system-manager-dummy branch from 00769c6 to 79c29e3 Compare March 11, 2026 21:12
Copy link

@xezon xezon left a comment

Choose a reason for hiding this comment

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

Looks ok. Compile error needs fixing.

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

Labels

Debug Is mostly debug functionality Enhancement Is new feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants