Skip to content

refactor OpenGL UboManager, UboBlocks, and Legacy cleanup - #506

Merged
nschimme merged 1 commit into
MUME:masterfrom
nschimme:refactor-ubo
Apr 7, 2026
Merged

refactor OpenGL UboManager, UboBlocks, and Legacy cleanup#506
nschimme merged 1 commit into
MUME:masterfrom
nschimme:refactor-ubo

Conversation

@nschimme

@nschimme nschimme commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Refine OpenGL legacy utilities by modernizing UBO management and tightening API contracts.

Enhancements:

  • Refactor UboManager to use non-legacy SharedVboEnum, Functions, VBO types and introduce stronger const- and nodiscard-annotated API.
  • Introduce BlockType_t alias and use it to simplify SharedVboBlocks tuple definition and UBO block type references.
  • Tighten access control and const-correctness in legacy Functions by making virtual helpers private and adjusting DrawModeEnum conversion signature.
  • Annotate GLWeather::TransitionPair and legacy TFO with NODISCARD/final to clarify intended usage and object semantics.

@sourcery-ai

sourcery-ai Bot commented Apr 7, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refactors the OpenGL UboManager and related UBO block types out of the Legacy namespace, tightens type aliases and const‑correctness, improves discard/nodiscard annotations, and does minor API visibility and comment cleanups across legacy OpenGL helpers.

Sequence diagram for UboManager updateIfInvalid and bind flow

sequenceDiagram
    actor Caller
    participant Manager as Legacy_UboManager
    participant GL as Functions
    participant SharedVbos as SharedVboManager
    participant Vbo as VBO

    Caller->>Manager: bind(GL, block)
    Manager->>Manager: updateIfInvalid(GL, block)
    alt buffer already bound
        Manager-->>Manager: return cached buffer
    else buffer invalid
        Manager->>Manager: lookup rebuild function for block
        alt rebuild function registered
            Manager->>GL: call rebuildFunction(GL)
            GL->>SharedVbos: getSharedVbos()
            SharedVbos-->>GL: sharedVboHandle
            GL->>Vbo: ensure VBO exists
            Vbo-->>GL: bufferId
            GL-->>Manager: rebuild completed
            Manager->>Manager: bind_internal(GL, block, bufferId)
            Manager-->>Manager: cache bufferId in m_boundBuffers
        else no rebuild function
            Manager-->>Caller: throw runtime_error
        end
    end
    Manager-->>GL: glBindBufferBase(GL_UNIFORM_BUFFER, bindingIndex, bufferId)
    GL-->>Caller: UBO bound
Loading

Sequence diagram for UboManager syncFields partial UBO update

sequenceDiagram
    actor Caller
    participant Manager as Legacy_UboManager
    participant GL as Functions
    participant Vbo as VBO

    Caller->>Manager: syncFields<Block,T,Us...>(GL, members...)
    Manager->>Manager: static_assert T == BlockType_t<Block>
    Manager->>Manager: compute offsets of members
    Manager->>Manager: blockData = get<Block>()
    Manager->>Manager: getOrCreateVbo(GL, Block)
    Manager->>GL: glBindBuffer(GL_UNIFORM_BUFFER, Vbo.get())
    loop for each member
        Manager->>GL: glBufferSubData(GL_UNIFORM_BUFFER, offset, size, pointer)
    end
    Manager->>GL: glBindBuffer(GL_UNIFORM_BUFFER, 0)
    Manager->>Manager: bind_internal(GL, Block, Vbo.get())
    Manager-->>Caller: return
Loading

Class diagram for refactored OpenGL UboManager and UBO block types

classDiagram
    direction LR

    class Legacy_UboManager {
        <<final>>
        +typedef RebuildFunction
        -EnumIndexedArray~RebuildFunction,SharedVboEnum~ m_rebuildFunctions
        -EnumIndexedArray~OptionalGLuint,SharedVboEnum~ m_boundBuffers
        -SharedVboBlocks m_shadowBlocks
        +UboManager()
        +~UboManager()
        +BlockType_t~Block~ & get~Block~()
        +const BlockType_t~Block~ & get~Block~() const
        +void invalidate(const SharedVboEnum block)
        +void invalidateAll()
        +void registerRebuildFunction(const SharedVboEnum block, RebuildFunction func, bool allowOverwrite = false)
        +void unregisterRebuildFunction(const SharedVboEnum block)
        +bool isInvalid(const SharedVboEnum block) const
        +GLuint updateIfInvalid(Functions &gl, const SharedVboEnum block)
        +GLuint update~T,A~(Functions &gl, const SharedVboEnum block, const vector~T,A~ &data)
        +GLuint update~T~(Functions &gl, const SharedVboEnum block, const T &data)
        +GLuint update~Block~(Functions &gl, const BlockType_t~Block~ &data)
        +GLuint sync~Block~(Functions &gl)
        +void syncFields~Block,T,Us...~(Functions &gl, Us T::* members...)
        +void syncField~Block,T,U~(Functions &gl, U T::* member)
        +void bind(Functions &gl, const SharedVboEnum block)
        -VBO & getOrCreateVbo(Functions &gl, const SharedVboEnum block)
        -GLuint bind_internal(Functions &gl, const SharedVboEnum block, const GLuint buffer)
    }

    class Functions {
        <<abstract>>
        -virtual bool virt_canRenderQuads()
        -virtual optional~GLenum~ virt_toGLenum(DrawModeEnum mode)
        -virtual void virt_enableProgramPointSize(bool enable)
        -virtual const char * virt_getShaderVersion() const
        +bool canRenderQuads()
        +optional~GLenum~ toGLenum(const DrawModeEnum mode)
        +const char * getShaderVersion() const
        +static const char * getUniformBlockName(SharedVboEnum block)
        +SharedVboManager & getSharedVbos()
    }

    class VBO {
        +VBO()
        +VBO(const VBO &)
        +VBO(VBO &&)
        +VBO & operator=(const VBO &)
        +VBO & operator=(VBO &&)
        +GLuint get() const
        +void emplace(shared_ptr~Functions~ gl)
        +operator bool() const
    }

    class EnumIndexedArray~T,E~ {
        -T data[ ]
        +T & operator[] (E index)
        +const T & operator[] (E index) const
        +size_t size() const
    }

    class SharedVboEnum {
        <<enumeration>>
    }

    class BlockType~T~ {
        +typedef type
    }

    class SharedVboBlocks {
        <<typedef>>
    }

    class BlockType_t~T~ {
        <<alias>>
    }

    class OptionalGLuint {
        <<typedef>>
    }

    Functions <|-- ConcreteFunctions
    Legacy_UboManager --> Functions : uses
    Legacy_UboManager --> VBO : manages
    Legacy_UboManager --> EnumIndexedArray~RebuildFunction,SharedVboEnum~ : owns
    Legacy_UboManager --> EnumIndexedArray~OptionalGLuint,SharedVboEnum~ : owns
    Legacy_UboManager --> SharedVboBlocks : owns
    EnumIndexedArray~T,E~ --> SharedVboEnum : indexed_by
    BlockType_t~T~ --> BlockType~T~ : alias_of
    SharedVboBlocks --> BlockType_t~SharedVboEnum~ : tuple_of
    Functions --> SharedVboEnum : parameter
    Legacy_UboManager --> SharedVboEnum : parameter
Loading

Class diagram for updated SharedVboBlocks and BlockType_t utilities

classDiagram
    direction LR

    class SharedVboEnum {
        <<enumeration>>
        +NUM_SHARED_VBOS
    }

    class BlockType~T~ {
        +typedef type
    }

    class BlockType_t~T~ {
        <<alias>>
    }

    class SharedVboBlocks {
        <<typedef>>
    }

    BlockType_t~T~ --> BlockType~T~ : uses_type

    SharedVboBlocks ..> BlockType_t~T~ : tuple_expansion

    class MakeSharedVboBlocksHelper {
        <<template_function>>
        +auto MakeSharedVboBlocksHelper(index_sequence~Is...~) : tuple~BlockType_t~static_cast~SharedVboEnum~(Is)~~...~
    }

    MakeSharedVboBlocksHelper ..> SharedVboEnum
    MakeSharedVboBlocksHelper ..> BlockType_t~T~
    SharedVboBlocks ..> MakeSharedVboBlocksHelper : decltype_of
Loading

Class diagram for GLWeather::TransitionPair and Legacy::TFO updates

classDiagram
    direction LR

    class GLWeather {
        +template~T~ T applyTransition(float startTime, T startVal, T targetVal) const
        +template~T~ class TransitionPair
    }

    class GLWeather_TransitionPair~T~ {
        <<final>>
        +T & start
        +T target
    }

    GLWeather *-- GLWeather_TransitionPair~T~ : nested

    class Legacy_TFO {
        <<final>>
        -GLuint id
        +TFO()
        +~TFO()
        +void bind()
        +void unbind()
    }

    note for Legacy_TFO "Comment: TFO = Transform Feedback Object"
Loading

File-Level Changes

Change Details Files
Refactor UboManager to use non-legacy types, stronger annotations, and centralized shadow block typing.
  • Add NODISCARD/ALLOW_DISCARD annotations to UboManager and its public methods that return values
  • Replace Legacy::SharedVboEnum, Legacy::Functions, Legacy::VBO, Legacy::BlockType, and Legacy::SharedVboBlocks with their non-legacy equivalents throughout UboManager
  • Introduce private members for rebuild functions, bound buffer tracking, and shadow blocks at the top of the class and remove the old duplicates at the bottom
  • Add BlockType_t alias usage in UboManager templates and simplify std::get type expressions
  • Make enum parameters const, and remove unused static_cast around setVbo calls
  • Ensure bind_internal and getOrCreateVbo are marked NODISCARD and always store/bind VBOs correctly, ignoring return values explicitly where appropriate
src/opengl/UboManager.h
Introduce generic BlockType_t alias and use it in SharedVboBlocks tuple construction.
  • Add BlockType_t template alias mapping SharedVboEnum to its block type
  • Update MakeSharedVboBlocksHelper to use BlockType_t instead of repeating the BlockType::type pattern
src/opengl/UboBlocks.h
Tighten encapsulation and const-correctness in Legacy::Functions.
  • Change the virtual platform-specific methods in Functions from protected to private to hide them from derived classes’ public interface
  • Make toGLenum take a const DrawModeEnum parameter and forward to the virtual implementation
src/opengl/legacy/Legacy.h
Minor API and documentation cleanups in other OpenGL helpers.
  • Mark Weather::TransitionPair as NODISCARD and final to discourage ignoring instances and inheritance
  • Add a clarifying comment explaining that Legacy::TFO stands for Transform Feedback Object
src/opengl/Weather.h
src/opengl/legacy/TFO.h

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In Legacy::Functions, the access specifiers are now a bit odd (private: for the virtual helpers plus a trailing protected:/private: pair); consider cleaning this up and deciding clearly whether the virt_* methods should remain protected for derived classes or be fully private.
  • Several parameters are now passed as const by value (e.g., const SharedVboEnum block, const GLuint buffer); since const on by-value parameters has no effect on the caller and can reduce readability, consider dropping these qualifiers unless they serve a specific purpose in your codebase conventions.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `Legacy::Functions`, the access specifiers are now a bit odd (`private:` for the virtual helpers plus a trailing `protected:`/`private:` pair); consider cleaning this up and deciding clearly whether the `virt_*` methods should remain `protected` for derived classes or be fully `private`.
- Several parameters are now passed as `const` by value (e.g., `const SharedVboEnum block`, `const GLuint buffer`); since `const` on by-value parameters has no effect on the caller and can reduce readability, consider dropping these qualifiers unless they serve a specific purpose in your codebase conventions.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@nschimme
nschimme merged commit f9515ee into MUME:master Apr 7, 2026
18 checks passed
@nschimme
nschimme deleted the refactor-ubo branch April 7, 2026 22:56
@codecov

codecov Bot commented Apr 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 25.10%. Comparing base (7f59bb9) to head (ef2400e).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/opengl/UboManager.h 0.00% 23 Missing ⚠️
src/opengl/legacy/Legacy.h 0.00% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master     #506   +/-   ##
=======================================
  Coverage   25.10%   25.10%           
=======================================
  Files         511      511           
  Lines       42286    42289    +3     
  Branches     4574     4574           
=======================================
+ Hits        10615    10617    +2     
- Misses      31671    31672    +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant