-
Notifications
You must be signed in to change notification settings - Fork 0
Add Class app as a Context #2
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
Conversation
|
Note
|
| Cohort / File(s) | Change Summary |
|---|---|
GitHub Actions workflow formatting .github/workflows/cmake-linux.yml, .github/workflows/cmake-windows.yml |
Restructured step indentation and spacing; converted inline multiline commands into explicit step blocks for Configure, Build, Test, Install, and Upload operations. No functional behavior changes. |
Application OO refactoring main.cpp |
Replaced procedural SDL callback code with a UserApp class derived from sopho::App; instance members replace global state; added virtual method overrides for lifecycle management and factory function create_app(). |
SDL wrapper module interface sdl_wrapper/sdl_wrapper.app.ixx |
New C++ module interface defining the abstract sopho::App class with pure virtual methods for init, iterate, event, and quit. |
SDL wrapper callback implementation sdl_wrapper/sdl_callback_implement.cpp |
New implementation file providing SDL3 callback functions (SDL_AppInit, SDL_AppIterate, SDL_AppEvent, SDL_AppQuit) that delegate to the sopho::App interface methods. |
SDL wrapper module exports sdl_wrapper/sdl_wrapper.ixx |
Added export import :app; to re-export the new app module partition. |
SDL wrapper module configuration sdl_wrapper/CMakeLists.txt |
Added sdl_wrapper.app.ixx to the module file set and introduced sdl_callback_implement.cpp as a private source. |
SDL wrapper buffer module reordering sdl_wrapper/sdl_wrapper.buffer.ixx |
Relocated module export directive from beginning to after include directive; no semantic changes. |
Sequence Diagram(s)
sequenceDiagram
participant SDL as SDL3 Runtime
participant Callback as sdl_callback_implement.cpp
participant App as sopho::App (UserApp)
SDL->>Callback: SDL_AppInit(void **appstate, argc, argv)
Callback->>App: create_app()
App-->>Callback: UserApp*
Callback->>App: app->init(argc, argv)
App-->>Callback: SDL_AppResult
Callback-->>SDL: result
loop Per Frame
SDL->>Callback: SDL_AppIterate(void *appstate)
Callback->>App: app->iterate()
App-->>Callback: SDL_AppResult
Callback-->>SDL: result
end
SDL->>Callback: SDL_AppEvent(void *appstate, SDL_Event *event)
Callback->>App: app->event(event)
App-->>Callback: SDL_AppResult
Callback-->>SDL: result
SDL->>Callback: SDL_AppQuit(void *appstate, SDL_AppResult result)
Callback->>App: app->quit(result)
App-->>Callback: (void)
Callback-->>SDL: done
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
- Extra attention areas:
main.cpp: Verify theUserAppclass correctly initializes/cleans up all SDL resources (window, device, buffers, pipeline); ensure virtual method overrides properly encapsulate former global state.sdl_wrapper/sdl_callback_implement.cpp: Review the delegation pattern andstatic_castusage; confirm error handling propagates correctly through the callback chain.sdl_wrapper/CMakeLists.txt: Validate that the module interface file and private implementation are correctly linked and discoverable by the build system.- Module import/export chain (
sdl_wrapper.ixx,sdl_wrapper.app.ixx,sdl_wrapper.buffer.ixx): Ensure module partitions are properly ordered and exported for downstream consumers.
Possibly related PRs
- Cpp20module #1: Modifies sdl_wrapper module structure and CMake target configuration with similar module interface and target_sources changes.
Poem
A class doth rise from callbacks old,
WhereUserAppbreaks the mold,
Virtual methods dance and sway,
Object-oriented comes to play! 🐰✨
From globals tamed to members neat,
The architecture's now complete!
Pre-merge checks and finishing touches
❌ Failed checks (1 warning, 1 inconclusive)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
|
| Title check | ❓ Inconclusive | The title 'Add Class app as a Context' is vague and does not clearly convey the main purpose of the changes, which involve refactoring SDL application code to use an object-oriented App class pattern with virtual methods and workflow restructuring. | Improve the title to be more specific about the primary change, such as 'Refactor SDL app lifecycle to object-oriented App class pattern' or 'Introduce abstract App class for application lifecycle management'. |
✅ Passed checks (1 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
class_app
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
|
@coderabbitai configuration |
CodeRabbit configurationlanguage: en-US
tone_instructions: ''
early_access: false
enable_free_tier: true
reviews:
profile: chill
request_changes_workflow: false
high_level_summary: true
high_level_summary_placeholder: '@coderabbitai summary'
high_level_summary_in_walkthrough: false
auto_title_placeholder: '@coderabbitai'
auto_title_instructions: ''
review_status: true
commit_status: true
fail_commit_status: false
collapse_walkthrough: false
changed_files_summary: true
sequence_diagrams: true
estimate_code_review_effort: true
assess_linked_issues: true
related_issues: true
related_prs: true
suggested_labels: true
labeling_instructions: []
auto_apply_labels: false
suggested_reviewers: true
auto_assign_reviewers: false
in_progress_fortune: true
poem: true
path_filters: []
path_instructions: []
abort_on_close: true
disable_cache: false
auto_review:
enabled: true
auto_incremental_review: true
ignore_title_keywords: []
labels: []
drafts: false
base_branches: []
ignore_usernames: []
finishing_touches:
docstrings:
enabled: true
unit_tests:
enabled: true
pre_merge_checks:
docstrings:
mode: warning
threshold: 80
title:
mode: warning
requirements: ''
description:
mode: warning
issue_assessment:
mode: warning
custom_checks: []
tools:
ast-grep:
rule_dirs: []
util_dirs: []
essential_rules: true
packages: []
shellcheck:
enabled: true
ruff:
enabled: true
markdownlint:
enabled: true
github-checks:
enabled: true
timeout_ms: 90000
languagetool:
enabled: true
enabled_rules: []
disabled_rules: []
enabled_categories: []
disabled_categories: []
enabled_only: false
level: default
biome:
enabled: true
hadolint:
enabled: true
swiftlint:
enabled: true
phpstan:
enabled: true
level: default
phpmd:
enabled: true
phpcs:
enabled: true
golangci-lint:
enabled: true
yamllint:
enabled: true
gitleaks:
enabled: true
checkov:
enabled: true
detekt:
enabled: true
eslint:
enabled: true
flake8:
enabled: true
rubocop:
enabled: true
buf:
enabled: true
regal:
enabled: true
actionlint:
enabled: true
pmd:
enabled: true
clang:
enabled: true
cppcheck:
enabled: true
semgrep:
enabled: true
circleci:
enabled: true
clippy:
enabled: true
sqlfluff:
enabled: true
prismaLint:
enabled: true
pylint:
enabled: true
oxc:
enabled: true
shopifyThemeCheck:
enabled: true
luacheck:
enabled: true
brakeman:
enabled: true
dotenvLint:
enabled: true
htmlhint:
enabled: true
checkmake:
enabled: true
osvScanner:
enabled: true
chat:
art: true
auto_reply: true
integrations:
jira:
usage: auto
linear:
usage: auto
knowledge_base:
opt_out: false
web_search:
enabled: true
code_guidelines:
enabled: true
filePatterns: []
learnings:
scope: auto
issues:
scope: auto
jira:
usage: auto
project_keys: []
linear:
usage: auto
team_keys: []
pull_requests:
scope: auto
mcp:
usage: auto
disabled_servers: []
code_generation:
docstrings:
language: en-US
path_instructions: []
unit_tests:
path_instructions: []
review:
style: concise
severity_threshold: medium
enable_tests: true
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
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.
Actionable comments posted: 4
🧹 Nitpick comments (4)
main.cpp (2)
61-248: Consider extracting helper methods for improved readability.The
initmethod is quite long (~187 lines) and handles multiple responsibilities: window/device creation, shader compilation, pipeline setup, buffer creation, and ImGui initialization. Consider extracting logical sections into private helper methods (e.g.,initShaders(),initPipeline(),initBuffers(),initImGui()).
265-292: Extract duplicate buffer upload logic.The buffer upload code (lines 265-292) duplicates the logic from the
initmethod (lines 189-215). Consider extracting this into a private helper method likeuploadVertexData()to follow the DRY principle.Example refactoring:
private: void uploadVertexData() { Vertex *data = (Vertex *)SDL_MapGPUTransferBuffer(device, transferBuffer, false); SDL_memcpy(data, (void *)vertices, sizeof(vertices)); SDL_UnmapGPUTransferBuffer(device, transferBuffer); SDL_GPUCommandBuffer *commandBuffer = SDL_AcquireGPUCommandBuffer(device); SDL_GPUCopyPass *copyPass = SDL_BeginGPUCopyPass(commandBuffer); SDL_GPUTransferBufferLocation location{}; location.transfer_buffer = transferBuffer; location.offset = 0; SDL_GPUBufferRegion region{}; region.buffer = vertexBuffer; region.size = sizeof(vertices); region.offset = 0; SDL_UploadToGPUBuffer(copyPass, &location, ®ion, true); SDL_EndGPUCopyPass(copyPass); SDL_SubmitGPUCommandBuffer(commandBuffer); }sdl_wrapper/sdl_callback_implement.cpp (2)
18-21: Add defensive null check.While
appstateshould not be null in normal operation, adding a null check provides defense-in-depth against potential SDL framework issues or future changes.Apply this diff:
SDL_AppResult SDL_AppIterate(void *appstate) { auto *app = static_cast<sopho::App *>(appstate); + if (!app) return SDL_APP_FAILURE; return app->iterate(); }
23-26: Add defensive null check.While
appstateshould not be null in normal operation, adding a null check provides defense-in-depth against potential SDL framework issues or future changes.Apply this diff:
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { auto *app = static_cast<sopho::App *>(appstate); + if (!app) return SDL_APP_FAILURE; return app->event(event); }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.github/workflows/cmake-linux.yml(1 hunks).github/workflows/cmake-windows.yml(2 hunks)main.cpp(2 hunks)sdl_wrapper/CMakeLists.txt(1 hunks)sdl_wrapper/sdl_callback_implement.cpp(1 hunks)sdl_wrapper/sdl_wrapper.app.ixx(1 hunks)sdl_wrapper/sdl_wrapper.buffer.ixx(1 hunks)sdl_wrapper/sdl_wrapper.ixx(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: build (Release, gcc)
- GitHub Check: build (Debug, gcc)
- GitHub Check: build (Release, clang)
- GitHub Check: build (Debug, clang)
- GitHub Check: build (windows-latest, Release, cl)
- GitHub Check: build (windows-latest, Release, gcc)
- GitHub Check: build (windows-latest, Release, clang)
🔇 Additional comments (5)
sdl_wrapper/sdl_wrapper.buffer.ixx (1)
4-6: LGTM! Correct module pattern.The reordering to use the global module fragment (
module;) before the include directive follows the correct C++20 module pattern, allowing SDL headers to be included before the module partition export.sdl_wrapper/sdl_wrapper.ixx (1)
6-7: LGTM! Proper module partition exports.The addition of
export import :app;correctly re-exports the new app partition alongside the existing buffer partition.sdl_wrapper/CMakeLists.txt (1)
12-14: LGTM! Build configuration updated correctly.The addition of
sdl_wrapper.app.ixxto the public module set andsdl_callback_implement.cppas a private implementation file is correct.sdl_wrapper/sdl_wrapper.app.ixx (1)
8-19: LGTM! Well-designed interface.The
Appinterface is clean and well-structured:
- Virtual destructor ensures proper cleanup of derived classes
- Pure virtual methods enforce a clear lifecycle contract (init → iterate → event → quit)
- Method signatures align with SDL3 callback conventions
main.cpp (1)
359-375: LGTM! Proper resource cleanup.The cleanup order is correct: ImGui context is destroyed first, followed by GPU resources (buffers, pipeline), then the device, and finally the window. All resources allocated in
initare properly released.
| vertices[0].z = node[2]; | ||
| class UserApp : public sopho::App { | ||
|
|
||
| sopho::BufferWrapper BufferWrapper{}; |
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.
Unused member variable.
The BufferWrapper member is declared but never used in the implementation. Consider removing it or implementing its intended functionality.
🤖 Prompt for AI Agents
In main.cpp around line 53, the sopho::BufferWrapper BufferWrapper{} member is
declared but never used; either remove this unused member declaration or
implement its intended usage. If it's not needed, delete the declaration and
recompile/run tests; if it should be used, initialize it properly where
required, replace direct buffer accesses with member calls, and update
constructors/cleanup to manage its lifetime so the compiler no longer reports it
as unused.
| sopho::App *create_app() { | ||
| return new UserApp(); | ||
| } |
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.
Memory leak: App instance is never deleted.
The factory function allocates a UserApp instance with new, but there's no corresponding delete in the codebase. The SDL_AppQuit callback in sdl_callback_implement.cpp (line 28-31) calls app->quit() but doesn't delete the app pointer.
Apply this fix to sdl_wrapper/sdl_callback_implement.cpp:
void SDL_AppQuit(void *appstate, SDL_AppResult result) {
auto *app = static_cast<sopho::App *>(appstate);
app->quit(result);
+ delete app;
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In sdl_wrapper/sdl_callback_implement.cpp around lines 28 to 31, the SDL_AppQuit
callback only calls app->quit() but never deletes the App instance returned by
create_app(), causing a memory leak; modify the callback to check that app is
non-null, call app->quit(), then delete app and set the pointer to nullptr (or
otherwise transfer ownership to a smart pointer) so the allocated UserApp is
freed; ensure this deletion is thread-safe with respect to SDL callbacks and
avoid double-deletion by clearing any global or static references to app after
deletion.
| SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { | ||
| auto app = create_app(); | ||
| *appstate = app; | ||
| return app->init(argc, argv); | ||
| } |
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.
Missing error handling for failed allocation.
If create_app() fails and returns nullptr (e.g., out of memory), the code will dereference a null pointer when calling app->init(). Add a null check and return an appropriate error code.
Apply this diff:
SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
auto app = create_app();
+ if (!app) {
+ return SDL_APP_FAILURE;
+ }
*appstate = app;
return app->init(argc, argv);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { | |
| auto app = create_app(); | |
| *appstate = app; | |
| return app->init(argc, argv); | |
| } | |
| SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { | |
| auto app = create_app(); | |
| if (!app) { | |
| return SDL_APP_FAILURE; | |
| } | |
| *appstate = app; | |
| return app->init(argc, argv); | |
| } |
🤖 Prompt for AI Agents
In sdl_wrapper/sdl_callback_implement.cpp around lines 12 to 16, handle the case
where create_app() returns nullptr: after calling create_app(), check if app is
nullptr, set *appstate = nullptr (or leave unchanged if preferred), and return
an appropriate failure SDL_AppResult (e.g., an out-of-memory or generic error
enum value used by this project) instead of calling app->init(); this prevents
dereferencing a null pointer and surfaces a clear error path.
| void SDL_AppQuit(void *appstate, SDL_AppResult result) { | ||
| auto *app = static_cast<sopho::App *>(appstate); | ||
| app->quit(result); | ||
| } |
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.
Missing cleanup and null check.
Two issues:
- The app instance is never deleted, causing a memory leak (already noted in main.cpp review)
- No null check on appstate
Apply this diff:
void SDL_AppQuit(void *appstate, SDL_AppResult result) {
auto *app = static_cast<sopho::App *>(appstate);
+ if (!app) return;
app->quit(result);
+ delete app;
}🤖 Prompt for AI Agents
In sdl_wrapper/sdl_callback_implement.cpp around lines 28-31, add a null check
for appstate and ensure the App instance is deleted to avoid leaking memory:
first return immediately if appstate is nullptr, then static_cast to
sopho::App*, call app->quit(result) as before, and finally delete the app
pointer (and optionally set it to nullptr in the caller if ownership is shared)
so the instance is freed after quit.
Summary by CodeRabbit
Release Notes
Refactor
Chores