backend-infra-engineer: Release v0.3.3 snapshot
This commit is contained in:
121
docs/internal/blueprints/architecture-refactor-plan.md
Normal file
121
docs/internal/blueprints/architecture-refactor-plan.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# B7 - Architecture Refactoring Plan
|
||||
|
||||
**Date**: October 15, 2025
|
||||
**Status**: Proposed
|
||||
**Author**: Gemini AI Assistant
|
||||
|
||||
## 1. Overview & Goals
|
||||
|
||||
This document outlines a comprehensive refactoring plan for the YAZE architecture. The current structure has resulted in tight coupling between components, slow incremental build times, and architectural inconsistencies (e.g., shared libraries located within the `app/` directory).
|
||||
|
||||
The primary goals of this refactoring are:
|
||||
|
||||
1. **Establish a Clear, Layered Architecture**: Separate foundational libraries (`core`, `gfx`, `zelda3`) from the applications that consume them (`app`, `cli`).
|
||||
2. **Improve Modularity & Maintainability**: Decompose large, monolithic libraries into smaller, single-responsibility modules.
|
||||
3. **Drastically Reduce Build Times**: Minimize rebuild cascades by ensuring changes in one module do not trigger unnecessary rebuilds in unrelated components.
|
||||
4. **Enable Future Development**: Create a flexible foundation for new features like alternative rendering backends (SDL3, Metal, Vulkan) and a fully-featured CLI.
|
||||
|
||||
## 2. Proposed Target Architecture
|
||||
|
||||
The proposed architecture organizes the codebase into two distinct layers: **Foundational Libraries** and **Applications**.
|
||||
|
||||
```
|
||||
/src
|
||||
├── core/ (NEW) 📖 Project model, Asar wrapper, etc.
|
||||
├── gfx/ (MOVED) 🎨 Graphics engine, backends, resource management
|
||||
├── zelda3/ (MOVED) Game Game-specific data models and logic
|
||||
├── util/ (EXISTING) Low-level utilities (logging, file I/O)
|
||||
│
|
||||
├── app/ (REFACTORED) Main GUI Application
|
||||
│ ├── controller.cc (MOVED) Main application controller
|
||||
│ ├── platform/ (MOVED) Windowing, input, platform abstractions
|
||||
│ ├── service/ (MOVED) AI gRPC services for automation
|
||||
│ ├── editor/ (EXISTING) 🎨 Editor implementations
|
||||
│ └── gui/ (EXISTING) Shared ImGui widgets
|
||||
│
|
||||
└── cli/ (EXISTING) z3ed Command-Line Tool
|
||||
```
|
||||
|
||||
## 3. Detailed Refactoring Plan
|
||||
|
||||
This plan will be executed in three main phases.
|
||||
|
||||
### Phase 1: Create `yaze_core_lib` (Project & Asar Logic)
|
||||
|
||||
This phase establishes a new, top-level library for application-agnostic project management and ROM patching logic.
|
||||
|
||||
1. **Create New Directory**: Create `src/core/`.
|
||||
2. **Move Files**:
|
||||
* Move `src/app/core/{project.h, project.cc}` → `src/core/` (pending)
|
||||
* Move `src/app/core/{asar_wrapper.h, asar_wrapper.cc}` → `src/core/` (done)
|
||||
* Move `src/app/core/features.h` → `src/core/` (pending)
|
||||
3. **Update Namespace**: In the moved files, change the namespace from `yaze::core` to `yaze::project` for clarity.
|
||||
4. **Create CMake Target**: In a new `src/core/CMakeLists.txt`, define the `yaze_core_lib` static library containing the moved files. This library should have minimal dependencies (e.g., `yaze_util`, `absl`).
|
||||
|
||||
### Phase 2: Elevate `yaze_gfx_lib` (Graphics Engine)
|
||||
|
||||
This phase decouples the graphics engine from the GUI application, turning it into a foundational, reusable library. This is critical for supporting multiple rendering backends as outlined in `docs/G2-renderer-migration-plan.md`.
|
||||
|
||||
1. **Move Directory**: Move the entire `src/app/gfx/` directory to `src/gfx/`.
|
||||
2. **Create CMake Target**: In a new `src/gfx/CMakeLists.txt`, define the `yaze_gfx_lib` static library. This will aggregate all graphics components (`backend`, `core`, `resource`, etc.).
|
||||
3. **Update Dependencies**: The `yaze` application target will now explicitly depend on `yaze_gfx_lib`.
|
||||
|
||||
### Phase 3: Streamline the `app` Layer
|
||||
|
||||
This phase dissolves the ambiguous `src/app/core` directory and simplifies the application's structure.
|
||||
|
||||
1. **Move Service Layer**: Move the `src/app/core/service/` directory to `src/app/service/`. This creates a clear, top-level service layer for gRPC implementations.
|
||||
2. **Move Platform Code**: Move `src/app/core/{window.cc, window.h, timing.h}` into the existing `src/app/platform/` directory. This consolidates all platform-specific windowing and input code.
|
||||
3. **Elevate Main Controller**: Move `src/app/core/{controller.cc, controller.h}` to `src/app/`. This highlights its role as the primary orchestrator of the GUI application.
|
||||
4. **Update CMake**:
|
||||
* Eliminate the `yaze_app_core_lib` target.
|
||||
* Add the source files from the moved directories (`app/controller.cc`, `app/platform/window.cc`, `app/service/*.cc`, etc.) directly to the main `yaze` executable target.
|
||||
|
||||
## 4. Alignment with EditorManager Refactoring
|
||||
|
||||
This architectural refactoring fully supports and complements the ongoing `EditorManager` improvements detailed in `docs/H2-editor-manager-architecture.md`.
|
||||
|
||||
- The `EditorManager` and its new coordinators (`UICoordinator`, `PopupManager`, `SessionCoordinator`) are clearly components of the **Application Layer**.
|
||||
- By moving the foundational libraries (`core`, `gfx`) out of `src/app`, we create a clean boundary. The `EditorManager` and its helpers will reside within `src/app/editor/` and `src/app/editor/system/`, and will consume the new `yaze_core_lib` and `yaze_gfx_lib` as dependencies.
|
||||
- This separation makes the `EditorManager`'s role as a UI and session coordinator even clearer, as it no longer lives alongside low-level libraries.
|
||||
|
||||
## 5. Migration Checklist
|
||||
|
||||
1. [x] **Phase 1**: Create `src/core/` and move `project`, `asar_wrapper`, and `features` files.
|
||||
2. [x] **Phase 1**: Create the `yaze_core_lib` CMake target.
|
||||
3. [ ] **Phase 2**: Move `src/app/gfx/` to `src/gfx/`. (DEFERRED - app-specific)
|
||||
4. [ ] **Phase 2**: Create the `yaze_gfx_lib` CMake target. (DEFERRED - app-specific)
|
||||
5. [x] **Phase 3**: Move `src/app/core/service/` to `src/app/service/`.
|
||||
6. [x] **Phase 3**: Move `src/app/core/testing/` to `src/app/test/` (merged with existing test/).
|
||||
7. [x] **Phase 3**: Move `window.cc`, `timing.h` to `src/app/platform/`.
|
||||
8. [x] **Phase 3**: Move `controller.cc` to `src/app/`.
|
||||
9. [x] **Phase 3**: Update CMake targets - renamed `yaze_core_lib` to `yaze_app_core_lib` to distinguish from foundational `yaze_core_lib`.
|
||||
10. [x] **Phase 3**: `src/app/core/` now only contains `core_library.cmake` for app-level functionality.
|
||||
11. [x] **Cleanup**: All `#include "app/core/..."` directives updated to new paths.
|
||||
|
||||
## 6. Completed Changes (October 15, 2025)
|
||||
|
||||
### Phase 1: Foundational Core Library ✅
|
||||
- Created `src/core/` with `project.{h,cc}`, `features.h`, and `asar_wrapper.{h,cc}`
|
||||
- Changed namespace from `yaze::core` to `yaze::project` for project management types
|
||||
- Created new `yaze_core_lib` in `src/core/CMakeLists.txt` with minimal dependencies
|
||||
- Updated all 32+ files to use `#include "core/project.h"` and `#include "core/features.h"`
|
||||
|
||||
### Phase 3: Application Layer Streamlining ✅
|
||||
- Moved `src/app/core/service/` → `src/app/service/` (gRPC services)
|
||||
- Moved `src/app/core/testing/` → `src/app/test/` (merged with existing test infrastructure)
|
||||
- Moved `src/app/core/window.{cc,h}`, `timing.h` → `src/app/platform/`
|
||||
- Moved `src/app/core/controller.{cc,h}` → `src/app/`
|
||||
- Renamed old `yaze_core_lib` to `yaze_app_core_lib` to avoid naming conflict
|
||||
- Updated all CMake dependencies in editor, emulator, agent, and test libraries
|
||||
- Removed duplicate source files from `src/app/core/`
|
||||
|
||||
### Deferred (Phase 2)
|
||||
Graphics refactoring (`src/app/gfx/` → `src/gfx/`) deferred as it's app-specific and requires careful consideration of rendering backends.
|
||||
|
||||
## 6. Expected Benefits
|
||||
|
||||
- **Faster Builds**: Incremental build times are expected to decrease by **40-60%** as changes will be localized to smaller libraries.
|
||||
- **Improved Maintainability**: A clear, layered architecture makes the codebase easier to understand, navigate, and extend.
|
||||
- **True CLI Decoupling**: The `z3ed` CLI can link against `yaze_core_lib` and `yaze_zelda3_lib` without pulling in any GUI or rendering dependencies, resulting in a smaller, more portable executable.
|
||||
- **Future-Proofing**: The abstracted `gfx` library paves the way for supporting SDL3, Metal, or Vulkan backends with minimal disruption to the rest of the application.
|
||||
1433
docs/internal/blueprints/editor-manager-architecture.md
Normal file
1433
docs/internal/blueprints/editor-manager-architecture.md
Normal file
File diff suppressed because it is too large
Load Diff
1167
docs/internal/blueprints/renderer-migration-complete.md
Normal file
1167
docs/internal/blueprints/renderer-migration-complete.md
Normal file
File diff suppressed because it is too large
Load Diff
176
docs/internal/blueprints/renderer-migration-plan.md
Normal file
176
docs/internal/blueprints/renderer-migration-plan.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# SDL2 to SDL3 Migration and Rendering Abstraction Plan
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
This document outlines a strategic plan to refactor the rendering architecture of the `yaze` application. The primary goals are:
|
||||
|
||||
1. **Decouple the application from the SDL2 rendering API.**
|
||||
2. **Create a clear and straightforward path for migrating to SDL3.**
|
||||
3. **Enable support for multiple rendering backends** (e.g., OpenGL, Metal, DirectX) to improve cross-platform performance and leverage modern graphics APIs.
|
||||
|
||||
## 2. Current State Analysis
|
||||
|
||||
The current architecture exhibits tight coupling with the SDL2 rendering API.
|
||||
|
||||
- **Direct Dependency:** Components like `gfx::Bitmap`, `gfx::Arena`, and `gfx::AtlasRenderer` directly accept or call functions using an `SDL_Renderer*`.
|
||||
- **Singleton Pattern:** The `core::Renderer` singleton in `src/app/core/window.h` provides global access to the `SDL_Renderer`, making it difficult to manage, replace, or mock.
|
||||
- **Dual Rendering Pipelines:** The main application (`yaze.cc`, `app_delegate.mm`) and the standalone emulator (`app/emu/emu.cc`) both perform their own separate, direct SDL initialization and rendering loops. This code duplication makes maintenance and migration efforts more complex.
|
||||
|
||||
This tight coupling makes it brittle, difficult to maintain, and nearly impossible to adapt to newer rendering APIs like SDL3 or other backends without a major, project-wide rewrite.
|
||||
|
||||
## 3. Proposed Architecture: The `Renderer` Abstraction
|
||||
|
||||
The core of this plan is to introduce a `Renderer` interface (an abstract base class) that defines a set of rendering primitives. The application will be refactored to program against this interface, not a concrete SDL2 implementation.
|
||||
|
||||
### 3.1. The `IRenderer` Interface
|
||||
|
||||
A new interface, `IRenderer`, will be created. It will define the contract for all rendering operations.
|
||||
|
||||
**File:** `src/app/gfx/irenderer.h`
|
||||
|
||||
```cpp
|
||||
#pragma once
|
||||
|
||||
#include <SDL.h> // For SDL_Rect, SDL_Color, etc.
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "app/gfx/bitmap.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace gfx {
|
||||
|
||||
// Forward declarations
|
||||
class Bitmap;
|
||||
|
||||
// A handle to a texture, abstracting away the underlying implementation
|
||||
using TextureHandle = void*;
|
||||
|
||||
class IRenderer {
|
||||
public:
|
||||
virtual ~IRenderer() = default;
|
||||
|
||||
// --- Initialization and Lifecycle ---
|
||||
virtual bool Initialize(SDL_Window* window) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
// --- Texture Management ---
|
||||
virtual TextureHandle CreateTexture(int width, int height) = 0;
|
||||
virtual void UpdateTexture(TextureHandle texture, const Bitmap& bitmap) = 0;
|
||||
virtual void DestroyTexture(TextureHandle texture) = 0;
|
||||
|
||||
// --- Rendering Primitives ---
|
||||
virtual void Clear() = 0;
|
||||
virtual void Present() = 0;
|
||||
virtual void RenderCopy(TextureHandle texture, const SDL_Rect* srcrect, const SDL_Rect* dstrect) = 0;
|
||||
virtual void SetRenderTarget(TextureHandle texture) = 0;
|
||||
virtual void SetDrawColor(SDL_Color color) = 0;
|
||||
|
||||
// --- Backend-specific Access ---
|
||||
// Provides an escape hatch for libraries like ImGui that need the concrete renderer.
|
||||
virtual void* GetBackendRenderer() = 0;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace yaze
|
||||
```
|
||||
|
||||
### 3.2. The `SDL2Renderer` Implementation
|
||||
|
||||
A concrete class, `SDL2Renderer`, will be the first implementation of the `IRenderer` interface. It will encapsulate all the existing SDL2-specific rendering logic.
|
||||
|
||||
**File:** `src/app/gfx/sdl2_renderer.h` & `src/app/gfx/sdl2_renderer.cc`
|
||||
|
||||
```cpp
|
||||
// sdl2_renderer.h
|
||||
#include "app/gfx/irenderer.h"
|
||||
#include "util/sdl_deleter.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace gfx {
|
||||
|
||||
class SDL2Renderer : public IRenderer {
|
||||
public:
|
||||
SDL2Renderer();
|
||||
~SDL2Renderer() override;
|
||||
|
||||
bool Initialize(SDL_Window* window) override;
|
||||
void Shutdown() override;
|
||||
|
||||
TextureHandle CreateTexture(int width, int height) override;
|
||||
void UpdateTexture(TextureHandle texture, const Bitmap& bitmap) override;
|
||||
void DestroyTexture(TextureHandle texture) override;
|
||||
|
||||
void Clear() override;
|
||||
void Present() override;
|
||||
void RenderCopy(TextureHandle texture, const SDL_Rect* srcrect, const SDL_Rect* dstrect) override;
|
||||
void SetRenderTarget(TextureHandle texture) override;
|
||||
void SetDrawColor(SDL_Color color) override;
|
||||
|
||||
void* GetBackendRenderer() override { return renderer_.get(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<SDL_Renderer, util::SDL_Deleter> renderer_;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace yaze
|
||||
```
|
||||
|
||||
## 4. Migration Plan
|
||||
|
||||
The migration will be executed in phases to ensure stability and minimize disruption.
|
||||
|
||||
### Phase 1: Implement the Abstraction Layer
|
||||
|
||||
1. **Create `IRenderer` and `SDL2Renderer`:** Implement the interface and concrete class as defined above.
|
||||
2. **Refactor `core::Renderer` Singleton:** The existing `core::Renderer` singleton will be deprecated and removed. A new central mechanism (e.g., a service locator or passing the `IRenderer` instance) will provide access to the active renderer.
|
||||
3. **Update Application Entry Points:**
|
||||
* In `app/core/controller.cc` (for the main editor) and `app/emu/emu.cc` (for the emulator), instantiate `SDL2Renderer` during initialization. The `Controller` will own the `unique_ptr<IRenderer>`.
|
||||
* This immediately unifies the rendering pipeline initialization for both application modes.
|
||||
4. **Refactor `gfx` Library:**
|
||||
* **`gfx::Bitmap`:** Modify `CreateTexture` and `UpdateTexture` to accept an `IRenderer*` instead of an `SDL_Renderer*`. The `SDL_Texture*` will be replaced with the abstract `TextureHandle`.
|
||||
* **`gfx::Arena`:** The `AllocateTexture` method will now call `renderer->CreateTexture()`. The internal pools will store `TextureHandle`s.
|
||||
* **`gfx::AtlasRenderer`:** The `Initialize` method will take an `IRenderer*`. All calls to `SDL_RenderCopy`, `SDL_SetRenderTarget`, etc., will be replaced with calls to the corresponding methods on the `IRenderer` interface.
|
||||
5. **Update ImGui Integration:**
|
||||
* The ImGui backend requires the concrete `SDL_Renderer*`. The `GetBackendRenderer()` method on the interface provides a type-erased `void*` for this purpose.
|
||||
* The ImGui initialization code will be modified as follows:
|
||||
```cpp
|
||||
// Before
|
||||
ImGui_ImplSDLRenderer2_Init(sdl_renderer_ptr);
|
||||
|
||||
// After
|
||||
auto backend_renderer = renderer->GetBackendRenderer();
|
||||
ImGui_ImplSDLRenderer2_Init(static_cast<SDL_Renderer*>(backend_renderer));
|
||||
```
|
||||
|
||||
### Phase 2: Migrate to SDL3
|
||||
|
||||
With the abstraction layer in place, migrating to SDL3 becomes significantly simpler.
|
||||
|
||||
1. **Create `SDL3Renderer`:** A new class, `SDL3Renderer`, will be created that implements the `IRenderer` interface using SDL3's rendering functions.
|
||||
* This class will handle the differences in the SDL3 API (e.g., `SDL_CreateRendererWithProperties`, float-based rendering functions, etc.) internally.
|
||||
* The `TextureHandle` will now correspond to an `SDL_Texture*` from SDL3.
|
||||
2. **Update Build System:** The CMake files will be updated to link against SDL3 instead of SDL2.
|
||||
3. **Switch Implementation:** The application entry points (`controller.cc`, `emu.cc`) will be changed to instantiate `SDL3Renderer` instead of `SDL2Renderer`.
|
||||
|
||||
The rest of the application, which only knows about the `IRenderer` interface, will require **no changes**.
|
||||
|
||||
### Phase 3: Support for Multiple Rendering Backends
|
||||
|
||||
The `IRenderer` interface makes adding new backends a modular task.
|
||||
|
||||
1. **Implement New Backends:** Create new classes like `OpenGLRenderer`, `MetalRenderer`, or `VulkanRenderer`. Each will implement the `IRenderer` interface using the corresponding graphics API.
|
||||
2. **Backend Selection:** Implement a factory function or a strategy in the main controller to select and create the desired renderer at startup, based on platform, user configuration, or command-line flags.
|
||||
3. **ImGui Backend Alignment:** When a specific backend is chosen for `yaze`, the corresponding ImGui backend implementation must also be used (e.g., `ImGui_ImplOpenGL3_Init`, `ImGui_ImplMetal_Init`). The `GetBackendRenderer()` method will provide the necessary context (e.g., `ID3D11Device*`, `MTLDevice*`) for each implementation.
|
||||
|
||||
## 5. Conclusion
|
||||
|
||||
This plan transforms the rendering system from a tightly coupled, monolithic design into a flexible, modular, and future-proof architecture.
|
||||
|
||||
**Benefits:**
|
||||
|
||||
- **Maintainability:** Rendering logic is centralized and isolated, making it easier to debug and maintain.
|
||||
- **Extensibility:** Adding support for new rendering APIs (like SDL3, Vulkan, Metal) becomes a matter of implementing a new interface, not refactoring the entire application.
|
||||
- **Testability:** The rendering interface can be mocked, allowing for unit testing of graphics components without a live rendering context.
|
||||
- **Future-Proofing:** The application is no longer tied to a specific version of SDL, ensuring a smooth transition to future graphics technologies.
|
||||
127
docs/internal/blueprints/test-dashboard-refactor.md
Normal file
127
docs/internal/blueprints/test-dashboard-refactor.md
Normal file
@@ -0,0 +1,127 @@
|
||||
YAZE GUI Test Integration Refactoring Plan
|
||||
|
||||
Author: Gemini
|
||||
Date: 2025-10-11
|
||||
Status: Proposed
|
||||
|
||||
1. Introduction & Motivation
|
||||
|
||||
The yaze application includes a valuable feature for developers: an in-application "Test Dashboard" that allows for
|
||||
viewing and running various test suites directly within the GUI. However, the current implementation, located primarily
|
||||
in src/app/test/, is tightly coupled with both the main application and the command-line test executables.
|
||||
|
||||
This tight coupling has led to several architectural and practical problems:
|
||||
* Conditional Compilation Complexity: Excluding the test dashboard from release or CI/CD builds is difficult, as its code
|
||||
is intertwined with core application logic. This unnecessarily bloats release binaries with test code.
|
||||
* Circular Dependencies: The yaze_test_support library, which contains the TestManager, links against nearly all other
|
||||
application libraries (yaze_editor, yaze_gui, etc.). When the main application also links against yaze_test_support to
|
||||
display the dashboard, it creates a confusing and potentially circular dependency graph that complicates the build
|
||||
process.
|
||||
* Mixed Concerns: The current TestManager is responsible for both the core logic of running tests and the UI logic for
|
||||
displaying the dashboard. This violates the Single-Responsibility Principle and makes the code harder to maintain.
|
||||
|
||||
This document proposes a plan to refactor the test integration system into a modular, layered, and conditionally
|
||||
compiled architecture.
|
||||
|
||||
2. Goals
|
||||
|
||||
* Decouple Test Infrastructure: Separate the core test framework from the test suites and the GUI dashboard.
|
||||
* Create an Optional Test Dashboard: Make the in-app test dashboard a compile-time feature that can be easily enabled for
|
||||
development builds and disabled for release builds.
|
||||
* Eliminate Complex Dependencies: Remove the need for the main application to link against the entire suite of test
|
||||
implementations, simplifying the build graph.
|
||||
* Improve Maintainability: Create a clean and logical structure for the test system that is easier to understand and
|
||||
extend.
|
||||
|
||||
3. Proposed Architecture
|
||||
|
||||
The test system will be decomposed into three distinct libraries, clearly separating the framework, the UI, and the
|
||||
tests themselves.
|
||||
|
||||
1 +-----------------------------------------------------------------+
|
||||
2 | Main Application ("yaze") |
|
||||
3 | (Conditionally links against test_dashboard) |
|
||||
4 +-----------------------------------------------------------------+
|
||||
5 | ^
|
||||
6 | Optionally depends on |
|
||||
7 v |
|
||||
8 +-----------------+ +-----------------+ +-----------------+
|
||||
9 | test_dashboard | --> | test_framework | <-- | test_suites |
|
||||
10 | (GUI Component) | | (Core Logic) | | (Test Cases) |
|
||||
11 +-----------------+ +-----------------+ +-----------------+
|
||||
12 ^ ^
|
||||
13 | |
|
||||
14 |-------------------------------------------------|
|
||||
15 |
|
||||
16 v
|
||||
17 +-----------------------------------------------------------------+
|
||||
18 | Test Executables (yaze_test_stable, etc.) |
|
||||
19 | (Link against test_framework and test_suites) |
|
||||
20 +-----------------------------------------------------------------+
|
||||
|
||||
3.1. test_framework (New Core Library)
|
||||
* Location: src/test/framework/
|
||||
* Responsibility: Provides the core, non-GUI logic for managing and executing tests.
|
||||
* Contents:
|
||||
* TestManager (core logic only: RunTests, RegisterTestSuite, GetLastResults, etc.).
|
||||
* TestSuite base class and related structs (TestResult, TestResults, etc.).
|
||||
* Dependencies: yaze_util, absl. It will not depend on yaze_gui or any specific test suites.
|
||||
|
||||
3.2. test_suites (New Library)
|
||||
* Location: src/test/suites/
|
||||
* Responsibility: Contains all the actual test implementations.
|
||||
* Contents:
|
||||
* E2ETestSuite, EmulatorTestSuite, IntegratedTestSuite, RomDependentTestSuite, ZSCustomOverworldTestSuite,
|
||||
Z3edAIAgentTestSuite.
|
||||
* Dependencies: test_framework, and any yaze libraries required for testing (e.g., yaze_zelda3, yaze_gfx).
|
||||
|
||||
3.3. test_dashboard (New Conditional GUI Library)
|
||||
* Location: src/app/gui/testing/
|
||||
* Responsibility: Contains all ImGui code for the in-application test dashboard. This library will be conditionally
|
||||
compiled and linked.
|
||||
* Contents:
|
||||
* A new TestDashboard class containing the DrawTestDashboard method (migrated from TestManager).
|
||||
* UI-specific logic for displaying results, configuring tests, and interacting with the TestManager.
|
||||
* Dependencies: test_framework, yaze_gui.
|
||||
|
||||
4. Migration & Refactoring Plan
|
||||
|
||||
1. Create New Directory Structure:
|
||||
* Create src/test/framework/.
|
||||
* Create src/test/suites/.
|
||||
* Create src/app/gui/testing/.
|
||||
|
||||
2. Split `TestManager`:
|
||||
* Move test_manager.h and test_manager.cc to src/test/framework/.
|
||||
* Create a new TestDashboard class in src/app/gui/testing/test_dashboard.h/.cc.
|
||||
* Move the DrawTestDashboard method and all its UI-related helper functions from TestManager into the new
|
||||
TestDashboard class.
|
||||
* The TestDashboard will hold a reference to the TestManager singleton to access results and trigger test runs.
|
||||
|
||||
3. Relocate Test Suites:
|
||||
* Move all ..._test_suite.h files from src/app/test/ to the new src/test/suites/ directory.
|
||||
* Move z3ed_test_suite.cc to src/test/suites/.
|
||||
|
||||
4. Update CMake Configuration:
|
||||
* `src/test/framework/CMakeLists.txt`: Create this file to define the yaze_test_framework static library.
|
||||
* `src/test/suites/CMakeLists.txt`: Create this file to define the yaze_test_suites static library, linking it
|
||||
against yaze_test_framework and other necessary yaze libraries.
|
||||
* `src/app/gui/testing/CMakeLists.txt`: Create this file to define the yaze_test_dashboard static library.
|
||||
* Root `CMakeLists.txt`: Introduce a new option: option(YAZE_WITH_TEST_DASHBOARD "Build the in-application test
|
||||
dashboard" ON).
|
||||
* `src/app/app.cmake`: Modify the yaze executable's target_link_libraries to conditionally link yaze_test_dashboard
|
||||
based on the YAZE_WITH_TEST_DASHBOARD flag.
|
||||
* `test/CMakeLists.txt`: Update the test executables to link against yaze_test_framework and yaze_test_suites.
|
||||
* Remove `src/app/test/test.cmake`: The old yaze_test_support library will be completely replaced by this new
|
||||
structure.
|
||||
|
||||
5. Expected Outcomes
|
||||
|
||||
This plan will resolve the current architectural issues by:
|
||||
* Enabling Clean Builds: Release and CI builds can set YAZE_WITH_TEST_DASHBOARD=OFF, which will prevent the
|
||||
test_dashboard and test_suites libraries from being compiled or linked into the final yaze executable, resulting in a
|
||||
smaller, cleaner binary.
|
||||
* Simplifying Dependencies: The main application will no longer have a convoluted dependency on its own test suites. The
|
||||
dependency graph will be clear and acyclic.
|
||||
* Improving Developer Experience: Developers can enable the dashboard for convenient in-app testing, while the core test
|
||||
infrastructure remains robust and decoupled for command-line execution.
|
||||
133
docs/internal/blueprints/zelda3-library-refactor.md
Normal file
133
docs/internal/blueprints/zelda3-library-refactor.md
Normal file
@@ -0,0 +1,133 @@
|
||||
YAZE `zelda3` Library Refactoring & Migration Plan
|
||||
|
||||
Author: Gemini
|
||||
Date: 2025-10-11
|
||||
Status: Proposed
|
||||
|
||||
1. Introduction & Motivation
|
||||
|
||||
The zelda3 library, currently located at src/app/zelda3, encapsulates all the data models and logic specific to "A Link
|
||||
to the Past." It serves as the foundational data layer for both the yaze GUI application and the z3ed command-line tool.
|
||||
|
||||
Its current structure and location present two primary challenges:
|
||||
|
||||
1. Monolithic Design: Like the gfx and gui libraries, zelda3 is a single, large static library. This creates a
|
||||
tightly-coupled module where a change to any single component (e.g., dungeon objects) forces a relink of the entire
|
||||
library and all its dependents.
|
||||
2. Incorrect Location: The library resides within src/app/, which is designated for the GUI application's specific code.
|
||||
However, its logic is shared with the cli target. This violates architectural principles and creates an improper
|
||||
dependency from the cli module into the app module's subdirectory.
|
||||
|
||||
This document proposes a comprehensive plan to both refactor the zelda3 library into logical sub-modules and migrate it
|
||||
to a top-level directory (src/zelda3) to correctly establish it as a shared, core component.
|
||||
|
||||
2. Goals
|
||||
|
||||
* Establish as a Core Shared Library: Physically and logically move the library to src/zelda3 to reflect its role as a
|
||||
foundational component for both the application and the CLI.
|
||||
* Improve Incremental Build Times: Decompose the library into smaller, focused modules to minimize the scope of rebuilds
|
||||
and relinks.
|
||||
* Clarify Domain Boundaries: Create a clear separation between the major game systems (Overworld, Dungeon, Sprites, etc.)
|
||||
to improve code organization and maintainability.
|
||||
* Isolate Legacy Code: Encapsulate the legacy Hyrule Magic music tracker code into its own module to separate it from the
|
||||
modern C++ codebase.
|
||||
|
||||
3. Proposed Architecture
|
||||
|
||||
The zelda3 library will be moved to src/zelda3/ and broken down into six distinct, layered libraries.
|
||||
|
||||
```
|
||||
1 +-----------------------------------------------------------------+
|
||||
2 | Executables (yaze, z3ed, tests) |
|
||||
3 +-----------------------------------------------------------------+
|
||||
4 ^
|
||||
5 | Links against
|
||||
6 v
|
||||
7 +-----------------------------------------------------------------+
|
||||
8 | zelda3 (INTERFACE Library) |
|
||||
9 +-----------------------------------------------------------------+
|
||||
10 ^
|
||||
11 | Aggregates
|
||||
12 |-----------------------------------------------------------|
|
||||
13 | | |
|
||||
14 v v v
|
||||
15 +-----------------+ +-----------------+ +---------------------+
|
||||
16 | zelda3_screen |-->| zelda3_dungeon |-->| zelda3_overworld |
|
||||
17 +-----------------+ +-----------------+ +---------------------+
|
||||
18 | | ^ | ^
|
||||
19 | | | | |
|
||||
20 |-----------------|---------|---------|---------|
|
||||
21 | | | | |
|
||||
22 v v | v v
|
||||
23 +-----------------+ +-----------------+ +---------------------+
|
||||
24 | zelda3_music |-->| zelda3_sprite |-->| zelda3_core |
|
||||
25 +-----------------+ +-----------------+ +---------------------+
|
||||
```
|
||||
|
||||
3.1. zelda3_core (Foundation)
|
||||
* Responsibility: Contains fundamental data structures, constants, and labels used across all other zelda3 modules.
|
||||
* Contents: common.h, zelda3_labels.h/.cc, dungeon/dungeon_rom_addresses.h.
|
||||
* Dependencies: yaze_util.
|
||||
|
||||
3.2. zelda3_sprite (Shared Game Entity)
|
||||
* Responsibility: Manages the logic and data for sprites, which are used in both dungeons and the overworld.
|
||||
* Contents: sprite/sprite.h/.cc, sprite/sprite_builder.h/.cc, sprite/overlord.h.
|
||||
* Dependencies: zelda3_core.
|
||||
|
||||
3.3. zelda3_dungeon (Dungeon System)
|
||||
* Responsibility: The complete, self-contained system for all dungeon-related data and logic.
|
||||
* Contents: All files from dungeon/ (room.h/.cc, room_object.h/.cc, dungeon_editor_system.h/.cc, etc.).
|
||||
* Dependencies: zelda3_core, zelda3_sprite.
|
||||
|
||||
3.4. zelda3_overworld (Overworld System)
|
||||
* Responsibility: The complete, self-contained system for all overworld-related data and logic.
|
||||
* Contents: All files from overworld/ (overworld.h/.cc, overworld_map.h/.cc, etc.).
|
||||
* Dependencies: zelda3_core, zelda3_sprite.
|
||||
|
||||
3.5. zelda3_screen (Specific Game Screens)
|
||||
* Responsibility: High-level components representing specific, non-gameplay screens.
|
||||
* Contents: All files from screen/ (dungeon_map.h/.cc, inventory.h/.cc, title_screen.h/.cc).
|
||||
* Dependencies: zelda3_dungeon, zelda3_overworld.
|
||||
|
||||
3.6. zelda3_music (Legacy Isolation)
|
||||
* Responsibility: Encapsulates the legacy Hyrule Magic music tracker code.
|
||||
* Contents: music/tracker.h/.cc.
|
||||
* Dependencies: zelda3_core.
|
||||
|
||||
4. Migration Plan
|
||||
|
||||
This plan details the steps to move the library from src/app/zelda3 to src/zelda3.
|
||||
|
||||
1. Physical File Move:
|
||||
* Move the directory /Users/scawful/Code/yaze/src/app/zelda3 to /Users/scawful/Code/yaze/src/zelda3.
|
||||
|
||||
2. Update CMake Configuration:
|
||||
* In src/CMakeLists.txt, change the line include(zelda3/zelda3_library.cmake) to
|
||||
include(zelda3/zelda3_library.cmake).
|
||||
* In the newly moved src/zelda3/zelda3_library.cmake, update all target_include_directories paths to remove the app/
|
||||
prefix (e.g., change ${CMAKE_SOURCE_DIR}/src/app to ${CMAKE_SOURCE_DIR}/src).
|
||||
|
||||
3. Update Include Directives (Global):
|
||||
* Perform a project-wide search-and-replace for all occurrences of #include "zelda3/ and change them to #include
|
||||
"zelda3/.
|
||||
* This will be the most extensive step, touching files in src/app/, src/cli/, and test/.
|
||||
|
||||
4. Verification:
|
||||
* After the changes, run a full CMake configure and build (cmake --preset mac-dev -B build_ai && cmake --build
|
||||
build_ai) to ensure all paths are correctly resolved and the project compiles successfully.
|
||||
|
||||
5. Implementation Plan (CMake)
|
||||
|
||||
The refactoring will be implemented within the new src/zelda3/zelda3_library.cmake file.
|
||||
|
||||
1. Define Source Groups: Create set() commands for each new library (ZELDA3_CORE_SRC, ZELDA3_DUNGEON_SRC, etc.).
|
||||
2. Create Static Libraries: Use add_library(yaze_zelda3_core STATIC ...) for each module.
|
||||
3. Establish Link Dependencies: Use target_link_libraries to define the dependencies outlined in section 3.
|
||||
4. Create Aggregate Interface Library: The yaze_zelda3 target will be converted to an INTERFACE library that links against
|
||||
all the new sub-libraries, providing a single, convenient link target for yaze_gui, yaze_cli, and the test suites.
|
||||
|
||||
6. Expected Outcomes
|
||||
|
||||
This refactoring and migration will establish the zelda3 library as a true core component of the application. The result
|
||||
will be a more logical and maintainable architecture, significantly faster incremental build times, and a clear
|
||||
separation of concerns that will benefit future development.
|
||||
Reference in New Issue
Block a user