-
Notifications
You must be signed in to change notification settings - Fork 161
feature(headless): Add ViewDummy for headless mode #2246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e765ce7
0cec07f
a0c3c50
e30fa7a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -331,5 +331,27 @@ class ViewLocation | |
| } | ||
| }; | ||
|
|
||
| // TheSuperHackers @feature bobtista 31/01/2026 | ||
| // View that does nothing. Used for Headless Mode. | ||
| class ViewDummy : public View | ||
|
Comment on lines
+334
to
+336
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P0] If the intent is “dummy view but still serialize base view state”, explicitly add Prompt To Fix With AIThis is a comment left during a code review.
Path: Core/GameEngine/Include/GameClient/View.h
Line: 334:336
Comment:
[P0] `ViewDummy` no longer overrides `xfer()`, but it also doesn’t provide any serialization behavior of its own. If headless mode saves are expected to be loadable in non-headless mode, the view block still needs to be written/read in a compatible way (either by calling `View::xfer(xfer)` or by writing a compatible stub block). Otherwise, headless-created saves may be missing view data or desync snapshot CRC/state.
If the intent is “dummy view but still serialize base view state”, explicitly add `virtual void xfer(Xfer* xfer) override { View::xfer(xfer); }`.
How can I resolve this? If you propose a fix, please make it concise.
Comment on lines
+334
to
+336
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P2] The new Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! Prompt To Fix With AIThis is a comment left during a code review.
Path: Core/GameEngine/Include/GameClient/View.h
Line: 334:336
Comment:
[P2] The new `ViewDummy` includes author-tag comments (`// TheSuperHackers @feature bobtista ...`). If this repo is trying to keep attribution out of code comments (and especially out of headers), consider replacing these with a short functional comment (e.g., `// Dummy view used in headless mode`). This keeps the header consistent with the rest of the codebase’s style conventions.
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise. |
||
| { | ||
| public: | ||
| virtual Drawable *pickDrawable( const ICoord2D *screen, Bool forceAttack, PickType pickType ) { return nullptr; } | ||
|
Comment on lines
+337
to
+339
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P3] Several Also appears in Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! Prompt To Fix With AIThis is a comment left during a code review.
Path: Core/GameEngine/Include/GameClient/View.h
Line: 337:339
Comment:
[P3] Several `ViewDummy` overrides put the body on the same line as the signature (e.g., `forceRedraw() {}`). If you’re following the project’s breakpoint-friendly formatting rule, expand these to put the body on its own line.
Also appears in `Generals*/.../W3DInGameUI.h` for `createView()`.
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise. |
||
| virtual Int iterateDrawablesInRegion( IRegion2D *screenRegion, Bool (*callback)( Drawable *draw, void *userData ), void *userData ) { return 0; } | ||
| virtual void forceRedraw() {} | ||
| virtual const Coord3D& get3DCameraPosition() const { static Coord3D zero = {0,0,0}; return zero; } | ||
| virtual WorldToScreenReturn worldToScreenTriReturn(const Coord3D *w, ICoord2D *s ) { return WTS_INVALID; } | ||
| virtual void screenToWorld( const ICoord2D *s, Coord3D *w ) {} | ||
| virtual void screenToTerrain( const ICoord2D *screen, Coord3D *world ) {} | ||
| virtual void screenToWorldAtZ( const ICoord2D *s, Coord3D *w, Real z ) {} | ||
| virtual void drawView( void ) {} | ||
| virtual void updateView(void) {} | ||
| virtual void stepView() {} | ||
| virtual void setGuardBandBias( const Coord2D *gb ) {} | ||
|
|
||
|
Comment on lines
+339
to
+351
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This pattern also appears in Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! Prompt To Fix With AIThis is a comment left during a code review.
Path: Core/GameEngine/Include/GameClient/View.h
Line: 339:351
Comment:
`ViewDummy` overrides many methods with one-liners on the same line as the signature (e.g. `virtual void forceRedraw() {}`). If the project rule is to keep bodies on separate lines for breakpoint placement, these should be expanded.
This pattern also appears in `Generals*/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DInGameUI.h` for `createView()`.
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise. |
||
| // TheSuperHackers @bugfix bobtista 03/02/2026 Do not override View::xfer(). The base | ||
| // implementation must run to serialize valid view state for save file compatibility. | ||
| }; | ||
|
|
||
| // EXTERNALS ////////////////////////////////////////////////////////////////////////////////////// | ||
| extern View *TheTacticalView; ///< the main tactical interface to the game world | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1240,17 +1240,17 @@ void InGameUI::init( void ) | |
| been moved to where all the other translators are attached in game client */ | ||
|
|
||
| // create the tactical view | ||
| if (TheDisplay) | ||
| TheTacticalView = createView(); | ||
|
Comment on lines
1240
to
+1243
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P0] Consider calling Prompt To Fix With AIThis is a comment left during a code review.
Path: Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp
Line: 1240:1243
Comment:
[P0] `TheTacticalView` is now always created, but `setDefaultView()` is only called when `TheDisplay` exists. Even if `View::setDefaultView()` is currently a no-op, derived view implementations (e.g., `W3DView`) may rely on it to initialize camera defaults; in headless mode this can leave view state uninitialized while still being used by non-display code paths.
Consider calling `TheTacticalView->setDefaultView(0.0f, 0.0f, 1.0f);` unconditionally after `createView()` (guarded only by `TheTacticalView`), and keep only `init/attach/size` under the display check.
How can I resolve this? If you propose a fix, please make it concise. |
||
| if (TheTacticalView && TheDisplay) | ||
| { | ||
| TheTacticalView = createView(); | ||
| TheTacticalView->init(); | ||
| TheDisplay->attachView( TheTacticalView ); | ||
|
|
||
| // make the tactical display the full screen width and height | ||
| TheTacticalView->setWidth( TheDisplay->getWidth() ); | ||
| TheTacticalView->setHeight( TheDisplay->getHeight() ); | ||
| TheTacticalView->setDefaultView(0.0f, 0.0f, 1.0f); | ||
| } | ||
|
Comment on lines
1242
to
1253
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If the intent is “always create the view, always set its default parameters, but only init/attach/size when a display exists”, consider moving Prompt To Fix With AIThis is a comment left during a code review.
Path: Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp
Line: 1242:1253
Comment:
`TheTacticalView->setDefaultView(...)` is now only called inside the `if (TheTacticalView && TheDisplay)` block. In headless mode (or any scenario where `TheDisplay == nullptr`), this skips setting the view's default parameters, which can leave downstream code reading uninitialized/incorrect view defaults.
If the intent is “always create the view, always set its default parameters, but only init/attach/size when a display exists”, consider moving `setDefaultView(0.0f, 0.0f, 1.0f)` back outside the display check (guarded only by `TheTacticalView`).
How can I resolve this? If you propose a fix, please make it concise.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an empty no-op function in the base class, so calling or not calling it makes no difference. In headless mode, a ViewDummy is used which doesn't need camera defaults since there's no camera. |
||
| TheTacticalView->setDefaultView(0.0f, 0.0f, 1.0f); | ||
|
|
||
| /** @todo this may be the wrong place to create the sidebar, but for now | ||
| this is where it lives */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,6 +36,7 @@ | |
| // SYSTEM INCLUDES //////////////////////////////////////////////////////////// | ||
|
|
||
| // USER INCLUDES ////////////////////////////////////////////////////////////// | ||
| #include "Common/GlobalData.h" | ||
| #include "GameClient/InGameUI.h" | ||
| #include "GameClient/View.h" | ||
| #include "W3DDevice/GameClient/W3DView.h" | ||
|
|
@@ -69,7 +70,8 @@ class W3DInGameUI : public InGameUI | |
| protected: | ||
|
|
||
| /// factory for views | ||
|
Comment on lines
70
to
72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P0] Either guard ( Prompt To Fix With AIThis is a comment left during a code review.
Path: Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DInGameUI.h
Line: 70:72
Comment:
[P0] `createView()` dereferences `TheGlobalData` unconditionally (`TheGlobalData->m_headless`). If `W3DInGameUI::init()` (or any caller of `createView()`) can run before `TheGlobalData` is initialized, this will crash on startup.
Either guard (`if (TheGlobalData && TheGlobalData->m_headless) ...`) or add an assertion documenting the initialization order guarantee.
How can I resolve this? If you propose a fix, please make it concise. |
||
| virtual View *createView( void ) { return NEW W3DView; } | ||
| // TheSuperHackers @fix bobtista 31/01/2026 Return dummy in headless mode | ||
| virtual View *createView( void ) { return TheGlobalData->m_headless ? static_cast<View*>(NEW ViewDummy) : NEW W3DView; } | ||
|
|
||
| virtual void drawSelectionRegion( void ); ///< draw the selection region on screen | ||
| virtual void drawMoveHints( View *view ); ///< draw move hint visual feedback | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
ViewDummyblock adds// TheSuperHackers @feature bobtista ...comments. If this repository is enforcing the standardized prologue/no-author-comments rule, these author-tag comments may violate that convention even though they aren't in the file prologue. Consider removing the author attribution and keeping only the functional description (e.g. “Dummy view used for headless mode”).Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI