Skip to content

Conversation

@X-rays5
Copy link
Owner

@X-rays5 X-rays5 commented Aug 2, 2025

This pull request introduces several changes across multiple files, focusing on utility enhancements, logging improvements, and build system adjustments. The most significant updates include the addition of new utility classes, refactoring of logging functionality, and improvements to CMake configurations to streamline header management and asset embedding.

Utility Enhancements:

  • Added a new RangedValue utility class in common/src/util/ranged_value.hpp for type-safe bounded values, along with comprehensive tests in common/test/src/util/ranged_value.cpp. This class ensures values are clamped within a specified range and integrates with the Glaze library for serialization. [1] [2]
  • Introduced enum_bitops.hpp in common/src/util/enum_bitops.hpp to enable bitwise operations on enums using the magic_enum library.

Logging Improvements:

  • Simplified namespace usage in exception_report.cpp by removing redundant common:: prefixes for conversion and fs::vfs. [1] [2] [3]
  • Refactored exception handling in vectored_handler.cpp to use modern C++ syntax, including an if-with-initializer and conditional compilation for debug builds. [1] [2]
  • Improved logging safety by checking for null pointers before flushing the default logger in vectored_handler.cpp.

Build System Adjustments:

  • Updated common/CMakeLists.txt and common/test/CMakeLists.txt to include the new ranged_value and enum_bitops utilities. [1] [2]
  • Refactored imfont/CMakeLists.txt to use a build-type-specific INTERFACE_DIR for header management and updated asset embedding to include new font files. [1] [2] [3]

Asset Updates:

  • Replaced the Font Awesome font in imfont/src/imfont.cpp with a sharper variant (fa-sharp-solid-900.ttf) and added a bold version of the Roboto Mono font. [1] [2]

These changes collectively improve the codebase's utility, maintainability, and build process while introducing new features for bounded value handling and enhanced logging.

@X-rays5 X-rays5 added this to the 2.0 rewrite milestone Aug 2, 2025
@X-rays5 X-rays5 self-assigned this Aug 2, 2025
Copilot AI review requested due to automatic review settings August 2, 2025 21:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This pull request introduces an interaction menu system to the application, featuring a comprehensive refactoring from an old callback-based renderer to a new script-managed architecture. The changes establish a modern, event-driven UI framework with dynamic menu components, key input handling, and improved resource management.

Key changes include:

  • Complete refactoring from render thread callbacks to a script-based system with proper lifecycle management
  • Introduction of an interaction menu framework with components, themes, and navigation
  • Implementation of key input handling system for menu navigation and interactions

Reviewed Changes

Copilot reviewed 63 out of 68 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
menu/src/main.cpp Complete rewrite implementing startup/shutdown sequence with script manager and sample menu
menu/src/ui/menu_renderer.cpp New menu rendering system with animation and component-based UI
menu/src/scripts/script_manager.cpp New script lifecycle management system
menu/src/util/key_input/key_event_listener.cpp Key input handling system for menu navigation
menu/src/render/render_thread.cpp Refactored render thread using script system instead of callbacks
menu/src/ui/components/* Component-based UI system (labels, buttons, sub-navigation)
menu/src/util/startup_shutdown_handler.hpp Centralized startup/shutdown lifecycle management

// Used when the current sub is empty
std::shared_ptr<components::BaseComponent> fallback_option_;
// Used when no sub can be found
std::shared_ptr<Submenu> fallback_submenu_ = std::make_shared<Submenu>("Fallback SubMenu", [this](Submenu* sub) {;
Copy link

Copilot AI Aug 2, 2025

Choose a reason for hiding this comment

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

There is a stray semicolon after the opening brace of the lambda expression. This will cause a compilation error.

Suggested change
std::shared_ptr<Submenu> fallback_submenu_ = std::make_shared<Submenu>("Fallback SubMenu", [this](Submenu* sub) {;
std::shared_ptr<Submenu> fallback_submenu_ = std::make_shared<Submenu>("Fallback SubMenu", [this](Submenu* sub) {

Copilot uses AI. Check for mistakes.
const auto char_x_size = CalcTextSizeRaw(ImGui::GetFont(), font_size, " ").x;
const auto chars_per_line = static_cast<std::uint32_t>(real_max_x / char_x_size);

auto* lines = new std::string[max_lines];
Copy link

Copilot AI Aug 2, 2025

Choose a reason for hiding this comment

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

Using raw new[] and delete[] is not recommended in modern C++. Consider using std::vector<std::string> or std::unique_ptr<std::string[]> for automatic memory management.

Suggested change
auto* lines = new std::string[max_lines];
std::vector<std::string> lines(max_lines);

Copilot uses AI. Check for mistakes.
Comment on lines +140 to +141
str = WordWrapGetString(lines, line_count);
delete[] lines;
Copy link

Copilot AI Aug 2, 2025

Choose a reason for hiding this comment

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

This corresponds to the raw new[] on line 115. Using RAII containers would eliminate the need for manual memory management.

Suggested change
str = WordWrapGetString(lines, line_count);
delete[] lines;
str = WordWrapGetString(lines.data(), line_count);
// No need to delete[] lines; vector handles memory automatically.

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +58
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kSUBMIT);
} else if (menu_ui_navigation.WasKeyPressed(VK_LEFT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kLEFT);
} else if (menu_ui_navigation.WasKeyPressed(VK_RIGHT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kRIGHT);
Copy link

Copilot AI Aug 2, 2025

Choose a reason for hiding this comment

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

Potential null pointer dereference. GetCurrentComponent() can return nullptr as documented in the header file, but this is not checked before calling HandleButtonPress().

Suggested change
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kSUBMIT);
} else if (menu_ui_navigation.WasKeyPressed(VK_LEFT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kLEFT);
} else if (menu_ui_navigation.WasKeyPressed(VK_RIGHT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kRIGHT);
auto current_component = submenu->GetCurrentComponent();
if (current_component) {
current_component->HandleButtonPress(components::BaseComponent::PressedButton::kSUBMIT);
}
} else if (menu_ui_navigation.WasKeyPressed(VK_LEFT)) {
auto current_component = submenu->GetCurrentComponent();
if (current_component) {
current_component->HandleButtonPress(components::BaseComponent::PressedButton::kLEFT);
}
} else if (menu_ui_navigation.WasKeyPressed(VK_RIGHT)) {
auto current_component = submenu->GetCurrentComponent();
if (current_component) {
current_component->HandleButtonPress(components::BaseComponent::PressedButton::kRIGHT);
}

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +58
if (menu_ui_navigation.WasKeyPressed(VK_RETURN)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kSUBMIT);
} else if (menu_ui_navigation.WasKeyPressed(VK_LEFT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kLEFT);
} else if (menu_ui_navigation.WasKeyPressed(VK_RIGHT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kRIGHT);
Copy link

Copilot AI Aug 2, 2025

Choose a reason for hiding this comment

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

Potential null pointer dereference. GetCurrentComponent() can return nullptr but this is not checked before calling HandleButtonPress().

Suggested change
if (menu_ui_navigation.WasKeyPressed(VK_RETURN)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kSUBMIT);
} else if (menu_ui_navigation.WasKeyPressed(VK_LEFT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kLEFT);
} else if (menu_ui_navigation.WasKeyPressed(VK_RIGHT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kRIGHT);
auto current_component = submenu->GetCurrentComponent();
if (menu_ui_navigation.WasKeyPressed(VK_RETURN)) {
if (current_component) {
current_component->HandleButtonPress(components::BaseComponent::PressedButton::kSUBMIT);
}
} else if (menu_ui_navigation.WasKeyPressed(VK_LEFT)) {
if (current_component) {
current_component->HandleButtonPress(components::BaseComponent::PressedButton::kLEFT);
}
} else if (menu_ui_navigation.WasKeyPressed(VK_RIGHT)) {
if (current_component) {
current_component->HandleButtonPress(components::BaseComponent::PressedButton::kRIGHT);
}

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +58
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kSUBMIT);
} else if (menu_ui_navigation.WasKeyPressed(VK_LEFT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kLEFT);
} else if (menu_ui_navigation.WasKeyPressed(VK_RIGHT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kRIGHT);
Copy link

Copilot AI Aug 2, 2025

Choose a reason for hiding this comment

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

Potential null pointer dereference. GetCurrentComponent() can return nullptr but this is not checked before calling HandleButtonPress().

Suggested change
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kSUBMIT);
} else if (menu_ui_navigation.WasKeyPressed(VK_LEFT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kLEFT);
} else if (menu_ui_navigation.WasKeyPressed(VK_RIGHT)) {
submenu->GetCurrentComponent()->HandleButtonPress(components::BaseComponent::PressedButton::kRIGHT);
auto current_component = submenu->GetCurrentComponent();
if (current_component) {
current_component->HandleButtonPress(components::BaseComponent::PressedButton::kSUBMIT);
}
} else if (menu_ui_navigation.WasKeyPressed(VK_LEFT)) {
auto current_component = submenu->GetCurrentComponent();
if (current_component) {
current_component->HandleButtonPress(components::BaseComponent::PressedButton::kLEFT);
}
} else if (menu_ui_navigation.WasKeyPressed(VK_RIGHT)) {
auto current_component = submenu->GetCurrentComponent();
if (current_component) {
current_component->HandleButtonPress(components::BaseComponent::PressedButton::kRIGHT);
}

Copilot uses AI. Check for mistakes.
# Create directory if needed
if (dir_path)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/${PROJECT_NAME}/${dir_path})
file(MAKE_DIRECTORY $INTERFACE_DIR/${dir_path})
Copy link

Copilot AI Aug 2, 2025

Choose a reason for hiding this comment

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

Missing braces around the variable expansion. This should be ${INTERFACE_DIR}/${dir_path} instead of $INTERFACE_DIR/${dir_path}.

Suggested change
file(MAKE_DIRECTORY $INTERFACE_DIR/${dir_path})
file(MAKE_DIRECTORY ${INTERFACE_DIR}/${dir_path})

Copilot uses AI. Check for mistakes.
Comment on lines +193 to +195

rotation_start_idx_ = -1; // Reset the rotation start index after rotating
}
Copy link

Copilot AI Aug 2, 2025

Choose a reason for hiding this comment

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

The rotation start index is reset inside the loop, which means it only affects the first iteration. This should be moved outside the loop.

Suggested change
rotation_start_idx_ = -1; // Reset the rotation start index after rotating
}
}
rotation_start_idx_ = -1; // Reset the rotation start index after rotating

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

github-actions bot commented Aug 2, 2025

Test Results

71 tests  +29   71 ✅ +29   30s ⏱️ ±0s
 1 suites ± 0    0 💤 ± 0 
 1 files   ± 0    0 ❌ ± 0 

Results for commit 681ec66. ± Comparison against base commit 43a3f7c.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Aug 3, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
10 New Critical Issues (required ≤ 0)
D Reliability Rating on New Code (required ≥ A)
4 New Blocker Issues (required ≤ 0)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants