tweak: decouple GUI window-move animations from the render frame rate#2833
tweak: decouple GUI window-move animations from the render frame rate#2833bobtista wants to merge 4 commits into
Conversation
|
| Filename | Overview |
|---|---|
| Generals/Code/GameEngine/Source/GameClient/GUI/AnimateWindowManager.cpp | Extracts per-frame logic into step(), adds m_frameAccumulator and accumulator-driven update(); accumulator is properly reset in constructor, init(), and reset(). |
| GeneralsMD/Code/GameEngine/Source/GameClient/GUI/AnimateWindowManager.cpp | Mirror of the Generals copy; identical accumulator-based changes applied correctly. |
| Generals/Code/GameEngine/Include/GameClient/AnimateWindowManager.h | Adds private step() declaration and m_frameAccumulator member; both correctly placed in the private section. |
| GeneralsMD/Code/GameEngine/Include/GameClient/AnimateWindowManager.h | Mirror of Generals header; private step() and m_frameAccumulator correctly added. |
| Generals/Code/GameEngine/Source/GameClient/GUI/Shell/Shell.cpp | Moves animate-window update call outside the ~30 Hz gate so it fires every render frame; the accumulator in AnimateWindowManager now handles pacing correctly for both the shell and in-game paths. |
| GeneralsMD/Code/GameEngine/Source/GameClient/GUI/Shell/Shell.cpp | Mirror of Generals Shell.cpp change; update call moved outside gate consistently. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Engine as Render Loop
participant Shell as Shell::update()
participant CB as ControlBar::update()
participant AWM as AnimateWindowManager::update()
participant FP as FramePacer
participant Step as AnimateWindowManager::step()
Note over Shell: ~30 Hz gate (unchanged)
Engine->>Shell: every render frame
Shell->>Shell: "if (now - lastUpdate >= 33ms)"
Shell->>Shell: runUpdate, schemeManager::update
Shell->>AWM: update() [every render frame, outside gate]
AWM->>FP: getBaseOverUpdateFpsRatio()
FP-->>AWM: "BaseFps / updateFps (e.g. 0.5 @ 60fps)"
AWM->>AWM: "accumulator += ratio"
AWM->>AWM: "steps = floor(accumulator)"
loop for each whole step
AWM->>Step: step()
Step->>Step: advance all registered window animations
end
Engine->>CB: every render frame
CB->>AWM: update() [per-frame, always was]
AWM->>FP: getBaseOverUpdateFpsRatio()
FP-->>AWM: BaseFps / updateFps
AWM->>AWM: "accumulate & step"
%%{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"}}}%%
sequenceDiagram
participant Engine as Render Loop
participant Shell as Shell::update()
participant CB as ControlBar::update()
participant AWM as AnimateWindowManager::update()
participant FP as FramePacer
participant Step as AnimateWindowManager::step()
Note over Shell: ~30 Hz gate (unchanged)
Engine->>Shell: every render frame
Shell->>Shell: "if (now - lastUpdate >= 33ms)"
Shell->>Shell: runUpdate, schemeManager::update
Shell->>AWM: update() [every render frame, outside gate]
AWM->>FP: getBaseOverUpdateFpsRatio()
FP-->>AWM: "BaseFps / updateFps (e.g. 0.5 @ 60fps)"
AWM->>AWM: "accumulator += ratio"
AWM->>AWM: "steps = floor(accumulator)"
loop for each whole step
AWM->>Step: step()
Step->>Step: advance all registered window animations
end
Engine->>CB: every render frame
CB->>AWM: update() [per-frame, always was]
AWM->>FP: getBaseOverUpdateFpsRatio()
FP-->>AWM: BaseFps / updateFps
AWM->>AWM: "accumulate & step"
Reviews (4): Last reviewed commit: "tweak: use frame pacer ratio for animati..." | Re-trigger Greptile
xezon
left a comment
There was a problem hiding this comment.
Try to use less AI code generation for better code
76414cb to
e5a23b5
Compare
e5a23b5 to
e829b80
Compare
| Real deltaSeconds = TheFramePacer->getUpdateTime(); | ||
|
|
||
| // Clamp the delta so a long stall (load, alt-tab) cannot snap an animation to its end. | ||
| const Real maxCatchUpSeconds = 0.2f; |
There was a problem hiding this comment.
Can be simplified to
const Real deltaSeconds = std::min(TheFramePacer->getUpdateTime(), 0.2f);
| deltaSeconds = maxCatchUpSeconds; | ||
| } | ||
|
|
||
| m_updateAccumulator += deltaSeconds * (Real)BaseFps; |
There was a problem hiding this comment.
Can this perhaps do m_updateAccumulator += TheFramePacer->getBaseOverUpdateFpsRatio() ?
| clearWinList(m_winMustFinishList); | ||
| m_needsUpdate = FALSE; | ||
| m_reverse = FALSE; | ||
| m_updateAccumulator = 0.0f; |
…r every frame (Generals)
Addresses #2832, Similar to 2056, which decoupled the
GameWindowTransitions.Problem
Control bar, diplomacy/communicator panels slide animations go too fast when you increase render FPS
Approach
AnimateWindowManager::update()now paces itself withTheFramePacer->getBaseOverUpdateFpsRatio(): it accumulates base-rate (30 fps) frames and runs that many steps, carrying the fractional remainder between updates.Shell::updatenow pumps the manager every frame instead of through its 30 Hz gate, since the manager paces itself.TODO:
[x] Testing
[x] Replicate to Generals