fix(particlesys): Add or simplify null-checks to createParticleSystem calls#2724
fix(particlesys): Add or simplify null-checks to createParticleSystem calls#2724stephanmeesters wants to merge 2 commits into
Conversation
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Source/GameClient/System/ParticleSys.cpp | Removes the redundant if (tmp) guard in update() and simplifies createSlaveSystem by removing the explicit null check before calling createParticleSystem — safe because the manager already returns nullptr for a null template. |
| Core/GameEngine/Source/GameClient/Drawable/Update/BeaconClientUpdate.cpp | Removes nested template/system null checks — simplification is safe; behaviour change in the failsafe else path was already discussed in a prior thread. |
| Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankTruckDraw.cpp | Drops the if (sysTemplate) outer guard; createParticleSystem handles null internally, so the else/error-logging branch now also fires when the template is missing — an improvement in error coverage. |
| Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTruckDraw.cpp | Same simplification as W3DTankTruckDraw.cpp; safe for the same reason. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp | Removes the outer if (tmp) guard and flattens the null check; logic is correct but the if (system) block retains the indentation of the old inner scope instead of matching the surrounding code. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptEngine.cpp | Removes the if (parentTemp) wrapper around createParticleSystem; safe because the function returns nullptr for a null argument. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/HelicopterSlowDeathUpdate.cpp | Removes the if (modData->m_attachParticleSystem) guard, reducing nesting by two levels; subsequent code is correctly gated on the system pointer. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/SlavedUpdate.cpp | Flattens two levels of null-check nesting around createParticleSystem; safe and improves readability. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp | Removes the if (data->m_unitHealPulseParticleSystemTmpl) guard; since createParticleSystem handles null, the simplification is safe. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp | Removes the if (tmp) guard before createParticleSystem; safe refactor, no logic change. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/EMPUpdate.cpp | Removes the if (tmp) outer guard and flattens the null-check nesting; safe. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp | Removes the if (tmp) guards for both the main and target particle systems; safe simplification. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp | Removes the if (tmp) guards in createConnectorFlare and createLaserBaseFlare; safe refactor, no logic change. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/StealthDetectorUpdate.cpp | Removes three separate template null guards before createParticleSystem calls; all simplifications are safe. |
Sequence Diagram
sequenceDiagram
participant Caller
participant TPSM as TheParticleSystemManager
participant PS as ParticleSystem
Note over Caller,PS: Before this PR
Caller->>TPSM: findTemplate(name)
TPSM-->>Caller: tmpl (may be nullptr)
alt "tmpl != nullptr"
Caller->>TPSM: createParticleSystem(tmpl)
TPSM-->>Caller: sys (may be nullptr)
alt "sys != nullptr"
Caller->>PS: attachToObject / setPosition / etc.
end
end
Note over Caller,PS: After this PR
Caller->>TPSM: findTemplate(name)
TPSM-->>Caller: tmpl (may be nullptr)
Caller->>TPSM: createParticleSystem(tmpl)
Note right of TPSM: null guard: if tmpl==nullptr return nullptr
TPSM-->>Caller: sys (may be nullptr)
alt "sys != nullptr"
Caller->>PS: attachToObject / setPosition / etc.
end
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp:1201-1206
The `if (system)` block (lines 1203–1206) uses 2-tab + 2-space indentation while the two lines above it (1201–1202) use tab + 6-space indentation, which is inconsistent with the surrounding code. The PR removed the outer `if (tmp)` scope but inadvertently left the inner block at its old indentation level rather than normalising it to match the context.
```suggestion
const ParticleSystemTemplate *tmp = TheParticleSystemManager->findTemplate( getChinookAIUpdateModuleData()->m_rotorWashParticleSystem );
ParticleSystem *system = TheParticleSystemManager->createParticleSystem( tmp );
if( system )
{
system->setPosition( &pos );
}
```
Reviews (2): Last reviewed commit: "Process review comments" | Re-trigger Greptile
| system = TheParticleSystemManager->createParticleSystem( particleTemplate ); | ||
| if (system) | ||
| { | ||
| system = TheParticleSystemManager->createParticleSystem( particleTemplate ); | ||
| if (system) | ||
| system->attachToDrawable( draw ); | ||
| system->attachToDrawable( draw ); | ||
| } | ||
| else// This is a failsafe... if someone has monkeyed with the particle system names, or the MP house colors | ||
| {// THis this will whip up a new particle system to match the house color provided | ||
| templateName.format("BeaconSmokeFFFFFF"); | ||
| const ParticleSystemTemplate *failsafeTemplate = TheParticleSystemManager->findTemplate( templateName ); | ||
| DEBUG_ASSERTCRASH(failsafeTemplate, ("Doh, this is bad \n I Could not even find the white particle system to make a failsafe system out of.")); | ||
| if (failsafeTemplate) | ||
| system = TheParticleSystemManager->createParticleSystem( failsafeTemplate ); | ||
| if (system) | ||
| { | ||
| system = TheParticleSystemManager->createParticleSystem( failsafeTemplate ); | ||
| if (system) | ||
| { | ||
| system->attachToDrawable( draw ); | ||
| system->tintAllColors( obj->getIndicatorColor() ); | ||
| } | ||
| system->attachToDrawable( draw ); | ||
| system->tintAllColors( obj->getIndicatorColor() ); | ||
| } | ||
| } |
There was a problem hiding this comment.
Failsafe
else now triggers on a broader condition
Originally the else (fallback to BeaconSmokeFFFFFF) ran only when particleTemplate == nullptr, i.e. when the color-keyed template was not found. After this change it runs whenever createParticleSystem returns nullptr — which includes any future code path (e.g. particle-cap enforcement) where the manager declines to create a system for a valid template. In that scenario the failsafe would silently emit a tinted-white beacon instead of simply producing nothing, which is the unintended behavior the comment describes as "someone has monkeyed with the particle system names".
Prompt To Fix With AI
This is a comment left during a code review.
Path: Core/GameEngine/Source/GameClient/Drawable/Update/BeaconClientUpdate.cpp
Line: 100-116
Comment:
**Failsafe `else` now triggers on a broader condition**
Originally the `else` (fallback to `BeaconSmokeFFFFFF`) ran only when `particleTemplate == nullptr`, i.e. when the color-keyed template was not found. After this change it runs whenever `createParticleSystem` returns `nullptr` — which includes any future code path (e.g. particle-cap enforcement) where the manager declines to create a system for a *valid* template. In that scenario the failsafe would silently emit a tinted-white beacon instead of simply producing nothing, which is the unintended behavior the comment describes as "someone has monkeyed with the particle system names".
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Should investigate if we can remove this failsafe
There was a problem hiding this comment.
I wonder if the failsafe path can be the sole default path. What is the benefit of the preset house color beacons? Do they look different?
There was a problem hiding this comment.
The two paths differ as follows:
- Primary path: loads a pre-baked
BeaconSmoke{RRGGBB}template (e.g.BeaconSmokeFF0000). The color is authored directly into the particle system INI definition. - Failsafe path: loads the white
BeaconSmokeFFFFFFtemplate and then callstintAllColors(obj->getIndicatorColor()), which multiplies all particle colors by the house color at runtime.
Visually, if the only difference between the per-color templates and the white one is the baked color value, the two paths would produce identical results — tinting white by 0xRRGGBB gives 0xRRGGBB. So yes, the failsafe could be the sole path with no visual difference, and you'd be able to delete all the BeaconSmoke{color} INI entries except the white one.
The only scenario where they'd differ is if some per-color templates have non-white base colors or other differing properties (emission rate, size, alpha curves, etc.) — in which case those distinctions would be lost. Worth checking the INI data to confirm they're all identical except for color before removing the primary path.
Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.
createParticleSystemis null checkedTodo