refactor(w3dview): Migrate from MEMBER_ADD/MEMBER_RELEASE macros to RefCountPtr<T>#1763
refactor(w3dview): Migrate from MEMBER_ADD/MEMBER_RELEASE macros to RefCountPtr<T>#1763bobtista wants to merge 3 commits into
Conversation
cc1d8dc to
c3f8d36
Compare
xezon
left a comment
There was a problem hiding this comment.
Before I continue review, please make another pass on this and correct all missing resource cleanups. It is important that no logic is changed, unless it fixes a bug.
| @@ -243,8 +241,6 @@ CW3DViewDoc::CleanupResources (void) | |||
| { | |||
There was a problem hiding this comment.
So, yes the operations inside are safe to execute regardless. If I understand correctly, the conditional checks make the intent explicit (only cleanup when there's something to clean up). RefCountPtr provides operator const DummyPtrType *() specifically to enable null-checking in boolean contexts.
// From ref_ptr.h documentation (lines 92-96):
void Do_It(void)
{
if (MyObject) { // Recommended pattern
MyObject->Do_Something();
}
}
This is also the pattern we use elsewhere eg CW3DViewDoc::CleanupResources.
Happy to keep or remove them, up to you
There was a problem hiding this comment.
Assignment functions already do the tests and are safe.
GeneralsGameCode/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h
Lines 289 to 298 in 7a6402b
Alternatively, use Clear() function. Maybe that is cleaner.
GeneralsGameCode/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h
Lines 352 to 358 in 7a6402b
0cbd2fc to
4c2acf0
Compare
xezon
left a comment
There was a problem hiding this comment.
How about we first make a change where we just remove the duplicate Macros, without adding RefCountPtr? Then this change will be simpler? And then make small changes to introduce RefCountPtr slowly? I am afraid this will be a big review here otherwise given the implications. One mistake with ref counting and the game will crash.
Ok, check out 1784. Shall we continue this PR after rebasing and have it focus just on just W3DView, then additional RefCountPtr migrations can have separate PRs? |
3c0d862 to
d3cd83c
Compare
|
This still needs work. |
1229310 to
52e834f
Compare
xezon
left a comment
There was a problem hiding this comment.
This refactor needs another pass. Something went wrong the indentation of code. And behavior has changed.
| if (m_pCBackObjectScene) | ||
| { | ||
| // Free the scene object | ||
| m_pCBackObjectScene->Release_Ref (); |
There was a problem hiding this comment.
m_pCBackObjectScene is a raw pointer (SceneClass *), not a RefCountPtr, so it uses Release_Ref() and = NULL for cleanup (lines 167-168). Want me to convert it to RefCountPtr? Or should that be in a separate PR?
There was a problem hiding this comment.
Checking again - On main:
m_pCursorScene used REF_PTR_RELEASE and was migrated to RefCountPtr with .Clear().
m_pCBackObjectScene used manual Release_Ref() + = NULL (not REF_PTR_RELEASE), so it wasn’t done in this PR. Do you want me to migrate it in this PR?
81a71ad to
bad267f
Compare
| SAFE_DELETE (m_pCAnimCombo); | ||
| REF_PTR_RELEASE (m_pCAnimation); | ||
|
|
||
| if (m_pCRenderObj != NULL) { |
There was a problem hiding this comment.
This indentation seems wrong in the original code, fixed here
|
I think this is ready for another look |
bad267f to
e2d2ae2
Compare
| DisplayObject (pCModel); | ||
|
|
||
| // Get an instance of the animation object | ||
| SAFE_DELETE (m_pCAnimCombo); |
There was a problem hiding this comment.
Here too, the indentation was weird in the original. It looks like they meant to do:
Function body level: 4 spaces
Inside the if block: 8 spaces (4 + 4)
But a few spots got 10 spaces, eg SAFE_DELETE, so I fixed those, at least here
e2d2ae2 to
9bdab84
Compare
9bdab84 to
a3409ec
Compare
|
| Filename | Overview |
|---|---|
| Core/Tools/W3DView/W3DViewDoc.cpp | Largest file in the PR; migrates m_pCRenderObj, m_pCAnimation, m_pCursorScene, and m_pCursor to RefCountPtr with correct Create_NoAddRef/Create_AddRef choices. The removed redundant m_pCBackObjectScene block after m_pDazzleLayer was dead code (the earlier if-block already nulled it). Cleanup, OnNewDocument, and DisplayObject paths all preserve original semantics. |
| Core/Tools/W3DView/W3DViewDoc.h | m_pCRenderObj, m_pCAnimation, m_pCursorScene, and m_pCursor declaration types updated to RefCountPtr; accessor methods updated to return .Peek(). |
| Core/Tools/W3DView/AssetInfo.cpp | Initialize() updated to use .Peek(); the Add_Ref/REF_PTR_RELEASE pattern on the local prender_obj is preserved and correct — it balances the ref on both the wrapped-instance and the factory-created temporary paths. |
| Core/Tools/W3DView/AssetInfo.h | m_pRenderObj migrated to RefCountPtr; Get_Render_Obj and Peek_Render_Obj updated to use .Peek() with correct manual Add_Ref semantics preserved in Get_Render_Obj. |
| Core/Tools/W3DView/GraphicView.cpp | m_pCamera and m_pLightMesh migrated to RefCountPtr with correct Create_NoAddRef for newly allocated objects; .Peek() used consistently for raw pointer API calls. |
| Core/Tools/W3DView/ScreenCursor.cpp | m_pTexture and m_pVertMaterial migrated to RefCountPtr. The copy constructor does not copy these fields (it calls Initialize() instead), which matches the original behavior where they were explicitly initialized to nullptr and rebuilt. |
| Core/Tools/W3DView/RingPropertySheet.cpp | m_RenderObj migrated to RefCountPtr; constructor initializer list reordered to put base class first (matching C++ initialization order), fixing a latent warning. Create_AddRef used for existing objects, Create_NoAddRef for newly constructed RingRenderObjClass. |
| Core/Tools/W3DView/SpherePropertySheet.cpp | Parallel refactoring to RingPropertySheet — identical pattern, identical correctness. Base class reordering and Create_AddRef/Create_NoAddRef choices are both right. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
subgraph Before["Before (Manual Macros)"]
B1["Raw pointer member\n(e.g. RenderObjClass* m_pCRenderObj)"] --> B2["Constructor: m_pRenderObj = nullptr\nthen REF_PTR_SET adds ref"]
B2 --> B3["Usage: pass raw pointer directly"]
B3 --> B4["Destructor/Cleanup:\nREF_PTR_RELEASE or\nRelease_Ref + nullptr"]
end
subgraph After["After (RefCountPtr)"]
A1["Smart pointer member\n(e.g. RefCountPtr<RenderObjClass> m_pCRenderObj)"] --> A2["Factory result → Create_NoAddRef\nExisting object → Create_AddRef"]
A2 --> A3["Usage: .Peek() for raw pointer APIs\nbool/== works directly"]
A3 --> A4["Destructor: automatic\nEarly release: .Clear()"]
end
Before --> |Refactored to| After
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
subgraph Before["Before (Manual Macros)"]
B1["Raw pointer member\n(e.g. RenderObjClass* m_pCRenderObj)"] --> B2["Constructor: m_pRenderObj = nullptr\nthen REF_PTR_SET adds ref"]
B2 --> B3["Usage: pass raw pointer directly"]
B3 --> B4["Destructor/Cleanup:\nREF_PTR_RELEASE or\nRelease_Ref + nullptr"]
end
subgraph After["After (RefCountPtr)"]
A1["Smart pointer member\n(e.g. RefCountPtr<RenderObjClass> m_pCRenderObj)"] --> A2["Factory result → Create_NoAddRef\nExisting object → Create_AddRef"]
A2 --> A3["Usage: .Peek() for raw pointer APIs\nbool/== works directly"]
A3 --> A4["Destructor: automatic\nEarly release: .Clear()"]
end
Before --> |Refactored to| After
Reviews (2): Last reviewed commit: "refactor(w3dview): Migrate W3DViewDoc an..." | Re-trigger Greptile
a3409ec to
e75954a
Compare
|
Ready for re-review. Rebased onto latest main and it's behavior-consistent with the original. Note - these fixes can either be added here or to separate PRs if we want:
|
Replaces custom reference counting macros (MEMBER_ADD, MEMBER_RELEASE, SAFE_ADD_REF, SAFE_RELEASE_REF) with the type-safe RefCountPtr smart pointer from the core library.
Member Variables Migrated to RefCountPtr:
Local Variable Usage:
Removed Macros (Utils.h):
Notes: