refactor(W3DMPO): Remove W3DMPO class to avoid unnecessary virtual classes#2607
refactor(W3DMPO): Remove W3DMPO class to avoid unnecessary virtual classes#2607Caball009 wants to merge 7 commits intoTheSuperHackers:mainfrom
Conversation
|
| Filename | Overview |
|---|---|
| Core/Libraries/Source/WWVegas/WWLib/always.h | Core change: renames W3DMPO_GLUE to W3DMPO_CODE, removes the W3DMPO base class and its pure-virtual glueEnforcer; new comment omits backslash continuation on the /* line and has a double-word typo. |
| Core/Libraries/Source/WWVegas/WW3D2/dllist.h | DLNodeClass no longer inherits W3DMPO; loses its virtual destructor — safe for current DLListClass usage but a subtle trap for future subclasses deleted through DLNodeClass* pointers. |
| Generals/Code/Libraries/Source/WWVegas/WW3D2/mapper.h | Removes W3DMPO inheritance from TextureMapperClass and all concrete mapper subclasses; W3DMPO_GLUE replaced with W3DMPO_CODE on each concrete class. |
| Generals/Code/Libraries/Source/WWVegas/WW3D2/motchan.h | Five motion-channel classes drop W3DMPO inheritance and virtual destructors; safe as none form their own polymorphic hierarchy. |
| Generals/Code/Libraries/Source/WWVegas/WW3D2/hlod.h | HLodClass, HLodDefClass, and HLodPrototypeClass drop W3DMPO; HLodPrototypeClass retains virtual destruction via PrototypeClass. |
| Generals/Code/Libraries/Source/WWVegas/WW3D2/meshmdlio.cpp | MeshLoadContextClass drops W3DMPO and virtual destructor; private to the translation unit so no external code deletes through a base pointer. |
| Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp | SortingNodeStruct gains W3DMPO_CODE and drops W3DMPO; CRTP pattern ensures deletions occur through the concrete type. |
Class Diagram
%%{init: {'theme': 'neutral'}}%%
classDiagram
class W3DMPO {
<<removed>>
+virtual ~W3DMPO()
#virtual glueEnforcer() const = 0
}
class W3DMPO_CODE {
<<macro>>
-getClassMemoryPool() void*
+operator new(size_t) void*
+operator delete(void*) void
}
class HLodClass {
W3DMPO_CODE(HLodClass)
}
class TextureMapperClass
class ScaleTextureMapperClass {
W3DMPO_CODE(ScaleTextureMapperClass)
}
class MotionChannelClass {
W3DMPO_CODE(MotionChannelClass)
}
class DLNodeClass~T~ {
~DLNodeClass()
}
class SortingNodeStruct {
W3DMPO_CODE(SortingNodeStruct)
}
W3DMPO_CODE ..> HLodClass : injected
W3DMPO_CODE ..> ScaleTextureMapperClass : injected
W3DMPO_CODE ..> MotionChannelClass : injected
W3DMPO_CODE ..> SortingNodeStruct : injected
TextureMapperClass <|-- ScaleTextureMapperClass
DLNodeClass~T~ <|-- SortingNodeStruct
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
Core/Libraries/Source/WWVegas/WWLib/always.h:137-140
Double word typo in the new comment — "first first use" should be "first use".
```suggestion
/*
construct on first use to avoid static initialization order fiasco
that may occur if this were initialized prior to the initialization of TheMemoryPoolFactory.
*/ \
```
### Issue 2 of 3
Core/Libraries/Source/WWVegas/WWLib/always.h:137-140
**Block comment continuation without backslash in macro body**
The old code used `/* \` — explicit `\` on every line — to keep the block comment syntactically inside the `#define` replacement list. The new `/*` on line 137 has no trailing `\`, so according to the standard the logical `#define` directive ends there, leaving the rest of the macro body (lines 141–148) technically at file scope rather than inside the macro.
In practice GCC, Clang, and MSVC all treat a `/*` inside a macro as consuming subsequent physical lines until `*/`, so this compiles today. That behaviour is a common extension rather than conforming C++, so the change trades portability for a slightly cleaner comment style. Consider restoring `/* \` to stay strictly conforming.
### Issue 3 of 3
Core/Libraries/Source/WWVegas/WW3D2/dllist.h:90
**Virtual destructor removed from intended base class**
`DLNodeClass<T>` is explicitly designed to be subclassed (all its list traversal helpers return `T*` via `static_cast`). Previously, inheriting from `W3DMPO` gave it a virtual destructor. It now has a non-virtual `~DLNodeClass()`. Any code that stores these nodes as `DLNodeClass<T>*` and calls `delete` through that pointer will not invoke the derived-class destructor, silently leaking any resources owned by the concrete node type (e.g. `SortingNodeStruct`).
`DLListClass` itself never calls `delete` on nodes, so no current path is obviously broken, but the unsafe contract is worth a comment and a virtual destructor to make the class safe for future subclasses.
Reviews (3): Last reviewed commit: "Replicated in Generals." | Re-trigger Greptile
572aeb3 to
6e08074
Compare
6e08074 to
baa882f
Compare
|
Generals is broken until the changes are replicated there. |
|
Instead of removing the class, how about removing the macro, and making |
Could you expand on that? |
There was a problem hiding this comment.
I checked my suggestion and it does not satisfy the requirements.
The approach in this change is the correct one.
While reviewing, I realized that many classes inherit RefCountClass for reference counting, which has a virtual void Delete_This() { delete this; } function and is not overloaded by W3DMPO classes. I wonder how this works then. Will delete this call the overloaded delete functions? I assume it does, otherwise the runtime should fail catastophically, but I do not know how it knows which overloaded delete to call. They are not virtual functions after all.
Can you check it for a potential follow up fix?
|
|
Yes, but we want to call this: If it does not call this, then how does it free it from the correct mem pool? |
|
This is what happens if I'm not mistaken.
|
This PR removes the
W3DMPOclass because it has no value in and of itself. Originally,W3DMPOcould not be derived from by other classes without adding theW3DMPO_GLUE(due to the pure virtual function inW3DMPO) , but there was no mechanism in place to prevent the opposite (seeTextureClass).Check commits for cleaner diff.
TODO: