Conversation
ragnar-howler
left a comment
There was a problem hiding this comment.
Code Review: Removed static variables
Summary
This PR addresses an important architectural issue where static variables with thread_local work correctly in the native app but fail in glvis-js, where new visualization scene instances are started in the same window/thread without reinitialization.
Changes Analysis
1. Static Member Migration (Good)
- Moving
vsdata,vssol,vssol3d,vsvector,vsvector3dfrom global statics tostatic thread_localclass members is proper encapsulation - Thread safety is preserved -
thread_localensures per-thread isolation
2. Key Handler Refactoring (Good)
- Converting free functions to
staticmember functions improves code organization - Making them
privatehides implementation details from public API - All key handlers properly access scene instance via the static thread_local pointer
3. Instance Variable Fixes (Critical Fix)
Moving these from static globals to instance variables correctly fixes state carryover:
magic_key_pressed(vssolution3d)ianim,ianimmax,key_u_func(vsvector)arrows_nl,vector_h,vector_hh(vsvector3d - replaces static locals)
This ensures each scene instance maintains its own state.
4. Plane Constructor Change
// Before:
Plane(double A, double B, double C, double D);
// After:
Plane(const double (&eqn_)[4], const VisualizationScene::Box &bb);- Passing bounding box by reference avoids accessing global state
- Array reference for equation parameters is cleaner
- The named struct
Boxinopenglvis.hppenables this
5. Logic Corrections
vsvector.cpp:ChangeDisplacement()correctly handles wraparound with modulo arithmeticvsvector3d.cpp:ArrowsDrawOrNot()now usesarrows_nlmember (initialized to -1) instead offirst_timestaticKeyrPressed/KeyRPressednow correctly usevsvector3d->instead ofwindow->vs->
Verdict
✅ Approve
This is a well-executed refactoring that:
- Fixes the glvis-js state carryover bug
- Improves encapsulation
- Maintains thread safety
- Preserves all existing functionality
The changes are minimal and focused on the specific issue without unnecessary scope creep.
There was a problem hiding this comment.
Pull request overview
This PR refactors GLVis VisualizationScene* implementations to eliminate function-local static state that can persist incorrectly across scene instances (notably in glvis-js), and restructures key handlers/state to be scene-owned (and mostly private).
Changes:
- Moved several scene-specific “static” caches/state into per-instance members (e.g., vector field scaling, arrow selection state).
- Converted many free/static key handlers into
staticclass members with athread_local“current scene” pointer. - Introduced
VisualizationScene::Boxtype and updatedPlaneconstruction to take a bounding box explicitly.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/vsvector3d.hpp | Adds per-instance fields and privatizes key handler plumbing for 3D vector scenes. |
| lib/vsvector3d.cpp | Removes function-local statics; moves vector scaling/arrow logic to instance state; converts key handlers to class statics. |
| lib/vsvector.hpp | Moves key handler state into the class and adjusts member layout (e.g., ArrowScale). |
| lib/vsvector.cpp | Converts key handlers to class statics; replaces thread_local globals with members; initializes per-instance key state in Init(). |
| lib/vssolution3d.hpp | Moves key handler declarations/state into the class and makes them non-public. |
| lib/vssolution3d.cpp | Converts free key handlers into class statics; updates cutting plane creation to use new Plane ctor. |
| lib/vssolution.hpp | Moves key handler declarations/state into the class and makes them non-public; adds SwitchAttribute helper as a member. |
| lib/vssolution.cpp | Converts free key handlers into class statics; makes SwitchAttribute a member; updates cutting plane creation to use new Plane ctor. |
| lib/vsdata.hpp | Changes Plane API; moves CuttingPlane/shrink factors into protected; adds key handler declarations/state. |
| lib/vsdata.cpp | Converts free key handlers into class statics; updates Plane ctor implementation to use explicit bounding box input. |
| lib/openglvis.hpp | Names the bounding box struct as VisualizationScene::Box for reuse outside VisualizationScene. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Refactored code to remove static variables from
VisualizationScenes, which are fine in the native app when declared asthread_local(not always the case), but fail in glvis-js, where a new instance of visualization scene is started (in the same window and thread). Initialization does not happen again and the values are carried over.Bonus: Changed key handlers and variables to private.