backend-infra-engineer: Post v0.3.9-hotfix7 snapshot (build cleanup)

This commit is contained in:
scawful
2025-12-22 00:20:49 +00:00
parent 2934c82b75
commit 5c4cd57ff8
1259 changed files with 239160 additions and 43801 deletions

View File

@@ -6,32 +6,49 @@
#include "absl/status/status.h"
#include "app/editor/editor_manager.h"
#include "app/gfx/backend/renderer_factory.h" // Use renderer factory for SDL2/SDL3 selection
#include "app/gfx/resource/arena.h" // Add include for Arena
#include "app/gfx/backend/renderer_factory.h"
#include "app/gfx/resource/arena.h"
#include "app/gui/automation/widget_id_registry.h"
#include "app/gui/core/background_renderer.h"
#include "app/gui/core/theme_manager.h"
#include "app/emu/emulator.h"
#include "app/platform/iwindow.h"
#include "app/platform/timing.h"
#include "app/platform/window.h"
#include "imgui/backends/imgui_impl_sdl2.h"
#include "imgui/backends/imgui_impl_sdlrenderer2.h"
#include "app/service/screenshot_utils.h"
#include "imgui/imgui.h"
namespace yaze {
absl::Status Controller::OnEntry(std::string filename) {
// Create renderer FIRST (uses factory for SDL2/SDL3 selection)
renderer_ = gfx::RendererFactory::Create();
// Create window backend using factory (auto-selects SDL2 or SDL3)
window_backend_ = platform::WindowBackendFactory::Create(
platform::WindowBackendFactory::GetDefaultType());
// Call CreateWindow with our renderer
RETURN_IF_ERROR(CreateWindow(window_, renderer_.get(), SDL_WINDOW_RESIZABLE));
platform::WindowConfig config;
config.title = "Yet Another Zelda3 Editor";
config.resizable = true;
config.high_dpi = false; // Disabled to match legacy behavior (SDL_WINDOW_RESIZABLE only)
RETURN_IF_ERROR(window_backend_->Initialize(config));
// Create renderer via factory (auto-selects SDL2 or SDL3)
renderer_ = gfx::RendererFactory::Create();
if (!window_backend_->InitializeRenderer(renderer_.get())) {
return absl::InternalError("Failed to initialize renderer");
}
// Initialize ImGui via backend (handles SDL2/SDL3 automatically)
RETURN_IF_ERROR(window_backend_->InitializeImGui(renderer_.get()));
// Initialize the graphics Arena with the renderer
gfx::Arena::Get().Initialize(renderer_.get());
// Set up audio for emulator
editor_manager_.emulator().set_audio_buffer(window_.audio_buffer_.get());
editor_manager_.emulator().set_audio_device_id(window_.audio_device_);
// Set up audio for emulator (using backend's audio resources)
auto audio_buffer = window_backend_->GetAudioBuffer();
if (audio_buffer) {
editor_manager_.emulator().set_audio_buffer(audio_buffer.get());
}
editor_manager_.emulator().set_audio_device_id(window_backend_->GetAudioDevice());
// Initialize editor manager with renderer
editor_manager_.Initialize(renderer_.get(), filename);
@@ -41,36 +58,82 @@ absl::Status Controller::OnEntry(std::string filename) {
}
void Controller::SetStartupEditor(const std::string& editor_name,
const std::string& cards) {
// Process command-line flags for editor and cards
// Example: --editor=Dungeon --cards="Rooms List,Room 0,Room 105"
const std::string& panels) {
// Process command-line flags for editor and panels
// Example: --editor=Dungeon --open_panels="dungeon.room_list,Room 0"
if (!editor_name.empty()) {
editor_manager_.OpenEditorAndCardsFromFlags(editor_name, cards);
editor_manager_.OpenEditorAndPanelsFromFlags(editor_name, panels);
}
}
void Controller::OnInput() {
PRINT_IF_ERROR(HandleEvents(window_));
if (!window_backend_) return;
platform::WindowEvent event;
while (window_backend_->PollEvent(event)) {
switch (event.type) {
case platform::WindowEventType::Quit:
case platform::WindowEventType::Close:
active_ = false;
break;
default:
// Other events are handled by ImGui via ProcessNativeEvent
// which is called inside PollEvent
break;
}
// Forward native SDL events to emulator input for event-based paths
if (event.has_native_event) {
editor_manager_.emulator().input_manager().ProcessEvent(
static_cast<void*>(&event.native_event));
}
}
}
absl::Status Controller::OnLoad() {
if (editor_manager_.quit() || !window_.active_) {
if (!window_backend_) {
return absl::InternalError("Window backend not initialized");
}
if (editor_manager_.quit() || !window_backend_->IsActive()) {
active_ = false;
return absl::OkStatus();
}
#if TARGET_OS_IPHONE != 1
ImGui_ImplSDLRenderer2_NewFrame();
ImGui_ImplSDL2_NewFrame();
// Start new ImGui frame via backend (handles SDL2/SDL3 automatically)
window_backend_->NewImGuiFrame();
ImGui::NewFrame();
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
ImGui::SetNextWindowSize(viewport->WorkSize);
// Calculate layout offsets for sidebars and status bar
const float left_offset = editor_manager_.GetLeftLayoutOffset();
const float right_offset = editor_manager_.GetRightLayoutOffset();
const float bottom_offset = editor_manager_.GetBottomLayoutOffset();
// Adjust dockspace position and size for sidebars and status bar
ImVec2 dockspace_pos = viewport->WorkPos;
ImVec2 dockspace_size = viewport->WorkSize;
dockspace_pos.x += left_offset;
dockspace_size.x -= (left_offset + right_offset);
dockspace_size.y -= bottom_offset; // Reserve space for status bar at bottom
ImGui::SetNextWindowPos(dockspace_pos);
ImGui::SetNextWindowSize(dockspace_size);
ImGui::SetNextWindowViewport(viewport->ID);
ImGuiWindowFlags window_flags =
ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
// Check if menu bar should be visible (WASM can hide it for clean UI)
bool show_menu_bar = true;
if (editor_manager_.ui_coordinator()) {
show_menu_bar = editor_manager_.ui_coordinator()->IsMenuBarVisible();
}
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking;
if (show_menu_bar) {
window_flags |= ImGuiWindowFlags_MenuBar;
}
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
window_flags |=
@@ -83,15 +146,22 @@ absl::Status Controller::OnLoad() {
ImGui::Begin("DockSpaceWindow", nullptr, window_flags);
ImGui::PopStyleVar(3);
// Create DockSpace first
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
// Create DockSpace with adjusted size
ImGuiID dockspace_id = ImGui::GetID("MainDockSpace");
gui::DockSpaceRenderer::BeginEnhancedDockSpace(
dockspace_id, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_PassthruCentralNode);
editor_manager_.DrawMenuBar(); // Draw the fixed menu bar at the top
if (show_menu_bar) {
editor_manager_.DrawMenuBar(); // Draw the fixed menu bar at the top
}
gui::DockSpaceRenderer::EndEnhancedDockSpace();
ImGui::End();
// Draw menu bar restore button when menu is hidden (WASM)
if (!show_menu_bar && editor_manager_.ui_coordinator()) {
editor_manager_.ui_coordinator()->DrawMenuBarRestoreButton();
}
#endif
gui::WidgetIdRegistry::Instance().BeginFrame();
absl::Status update_status = editor_manager_.Update();
@@ -101,17 +171,22 @@ absl::Status Controller::OnLoad() {
}
void Controller::DoRender() const {
// Process all pending texture commands (batched to max 8 per frame).
if (!window_backend_ || !renderer_) return;
// Process pending texture commands (max 8 per frame for consistent performance)
gfx::Arena::Get().ProcessTextureQueue(renderer_.get());
ImGui::Render();
renderer_->Clear();
ImGui_ImplSDLRenderer2_RenderDrawData(
ImGui::GetDrawData(),
static_cast<SDL_Renderer*>(renderer_->GetBackendRenderer()));
// Render ImGui draw data and handle viewports via backend
window_backend_->RenderImGui(renderer_.get());
renderer_->Present();
// Use TimingManager for accurate frame timing in sync with SDL
// Process any pending screenshot requests on the main thread after present
ProcessScreenshotRequests();
// Get delta time AFTER render for accurate measurement
float delta_time = TimingManager::Get().Update();
// Gentle frame rate cap to prevent excessive CPU usage
@@ -122,8 +197,42 @@ void Controller::DoRender() const {
}
void Controller::OnExit() {
renderer_->Shutdown();
PRINT_IF_ERROR(ShutdownWindow(window_));
if (renderer_) {
renderer_->Shutdown();
}
if (window_backend_) {
window_backend_->Shutdown();
}
}
absl::Status Controller::LoadRomForTesting(const std::string& rom_path) {
// Use EditorManager's OpenRomOrProject which handles the full initialization:
// 1. Load ROM file into session
// 2. ConfigureEditorDependencies()
// 3. LoadAssets() - initializes all editors and loads graphics
// 4. Updates UI state (hides welcome screen, etc.)
return editor_manager_.OpenRomOrProject(rom_path);
}
void Controller::RequestScreenshot(const ScreenshotRequest& request) {
std::lock_guard<std::mutex> lock(screenshot_mutex_);
screenshot_requests_.push(request);
}
void Controller::ProcessScreenshotRequests() const {
#ifdef YAZE_WITH_GRPC
std::lock_guard<std::mutex> lock(screenshot_mutex_);
while (!screenshot_requests_.empty()) {
auto request = screenshot_requests_.front();
screenshot_requests_.pop();
// Perform capture on main thread
auto result = test::CaptureHarnessScreenshot(request.preferred_path);
if (request.callback) {
request.callback(result);
}
}
#endif
}
} // namespace yaze