Skip to content

Commit 71b6e34

Browse files
committed
Porytiles2 MVP: Core compilation pipeline and domain architecture (#185)
This PR represents a major milestone in the Porytiles2 development effort, establishing the core architecture and outline of the primary tileset compilation pipeline (more implementation work to come). - Implemented ChainableResult type for composable error handling with context propagation - Created FormattableError system with rich formatting capabilities - Added UserDiagnostics interface with stderr implementation - Introduced PT_TRY macros for ergonomic error handling - Implemented error chain visualization with metatile and tile printers - Added provenance tracking for configuration values - Implemented RgbaTileNormalizer service for normalizing tiles to canonical form - Created NormalizedTile and NormalizedPal domain types - Added RgbaTileDenormalizer for reconstructing original tiles from normalized form - Implemented tile masking system with ShapeMask (formerly MaskPixels) - Created canonical tile types: CanonicalPixelTile and CanonicalShapeTile - Developed shape-based tile isomorphism detection system - Added batch normalization capabilities - Implemented ColorSet domain type for managing palette color collections - Created ColorSetBuilder service for constructing color sets - Added ColorIndexMapBuilder for mapping colors to palette indices - Integrated support for multiple extrinsic transparency values - Implemented PrimaryTilesetCompiler service with multi-stage pipeline architecture - Created operation framework with ConstructRgbaMetatilesOp and other pipeline operations - Added OperandBundle for managing pipeline data flow - Implemented tile validation services (e.g., validate_unique_color_count) - Implemented RgbaLayerImageMetatileizer for converting layer images to metatiles - Created RgbaImageTileizer for breaking images into tiles - Added MetatileAttribute domain model with support for pokeemerald-specific attributes - Implemented metatile decomposition capabilities - Added MetatileDecompiler service stub - Implemented ProjectTilesetArtifactReader with support for reading pokeemerald attributes - Created ProjectTilesetArtifactWriter with integration tests - Added TilesPngWorkspace for managing tiles.png operations - Enhanced artifact reading to correctly parse binary attribute formats - Refactored TextFormatter with varargs support and multiple style options - Implemented FormatParam with implicit conversion support - Removed fmtlib types from public API for better encapsulation - Added convenience formatting methods throughout codebase - Migrated from global config values to tileset-specific configuration - Implemented configuration provenance tracking with std::source_location - Added extract_simple_function_name utility for source location handling - Updated DomainConfig to use tileset-prefixed keys - Implemented lazy layered configuration evaluation - Removed legacy BGR color classes in favor of RGBA - Deleted IsoXTile types and associated services - Removed domain/model subfolder structure for simplified organization - Consolidated tile domain model package - Refactored template library into multiple focused packages (xcut, utilities) - Deleted unused code and old notes files - Created new package structure for better domain separation - Added comprehensive unit tests for normalization, color management, and metatileization - Created integration tests for artifact I/O - Added test resources for various edge cases (normalization, attributes, etc.) - Improved test organization under Resources/Tests/unit - Added debug flags and coverage build configuration - Integrated Doxygen Awesome CSS dependency - Enhanced CMake FetchContent logging - Added find_and_replace.sh utility script - Updated .gitignore and launch.json configuration - Restructured debug commands into comprehensive debug_commands.hpp - Added tileset verification command - Improved command validation - Enhanced error messaging and diagnostics output This PR establishes the foundational domain-driven design architecture for Porytiles2: - Clear separation between domain models, services, and utilities - Template-based generic programming for flexibility - Pipeline-based compilation with composable operations - Rich error handling with full context propagation - Transparent artifact I/O with format-agnostic interfaces All changes include corresponding unit and integration tests. The test suite covers: - Tile normalization and denormalization round-trips - Color set and index map generation - Metatile construction and decomposition - Artifact reading and writing - Error handling and propagation - Configuration provenance tracking Major areas: - Porytiles2/include/porytiles2/domain/ (extensive changes) - Porytiles2/lib/domain/ (extensive changes) - Porytiles2/include/porytiles2/utilities/ (new package structure) - Porytiles2/tests/ (new test coverage) - Resources/Tests/ (new test resources)
1 parent d698021 commit 71b6e34

File tree

226 files changed

+13194
-6003
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

226 files changed

+13194
-6003
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# IDE and filesystem metadata
22
.vscode/*
33
!.vscode/c_cpp_properties.json
4+
!.vscode/launch.json
45
.idea
56
.DS_Store
67
.claude
78

89
# Build artifacts and executables
910
build/**
10-
cmake-build-*/**
11+
vscode-build/**
12+
clion-build-*/**
1113

1214
# Doxygen
1315
Documentation/html/**

.vscode/launch.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "LLDB - Porytiles2 Driver Debug Command",
6+
"type": "lldb",
7+
"request": "launch",
8+
"program": "${workspaceFolder}/build/Porytiles2/tools/driver/porytiles2",
9+
"args": ["debug", "porytiles2_test"],
10+
"cwd": "${workspaceFolder}/../pokeemerald-expansion"
11+
},
12+
{
13+
"name": "LLDB - Porytiles2AllTests",
14+
"type": "lldb",
15+
"request": "launch",
16+
"program": "${workspaceFolder}/build/Porytiles2/tests/Porytiles2AllTests",
17+
"args": [],
18+
"cwd": "${workspaceFolder}"
19+
}
20+
]
21+
}

CLAUDE.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,19 @@ cmake -B build-release -DCMAKE_BUILD_TYPE=Release
3232
# Build project
3333
cmake --build build -j7
3434
```
35-
36-
### Build Variants
37-
Multiple build configurations are available:
38-
- `build/` - Debug build
39-
- `build-coverage/` - Debug build with coverage
40-
- `build-release/` - Release build
35+
Alternatively, if there is a build directory called `clion-build-debug`, use that instead of `build`.
4136

4237
## Testing
4338
- Doctests for legacy version at `./build/Porytiles1/tests/Porytiles1Tests`
4439
- GoogleTest unit tests at `./build/Porytiles2/tests/Porytiles2UnitTests`
4540
- GoogleTest integration tests at `./build/Porytiles2/tests/Porytiles2IntegrationTests`
41+
- GoogleTest all test runner at `./build/Porytiles2/tests/Porytiles2AllTests
42+
43+
Prefer to simply run all tests using the all test runner.
4644

4745
Run all tests:
4846
```bash
49-
./build/Porytiles1/tests/Porytiles1Tests
50-
./build/Porytiles2/tests/Porytiles2UnitTests
51-
./build/Porytiles2/tests/Porytiles2IntegrationTests
47+
./build/Porytiles2/tests/Porytiles2AllTests # this runs both Porytiles2UnitTests and Porytiles2IntegrationTests
5248
```
5349

5450
## Code Quality Tools
@@ -112,7 +108,7 @@ Use the following example snippet as a guide for code style.
112108
- **Never** include header files using relative paths
113109
- Follow const correctness principles
114110
- Always use namespace `porytiles2`, don't create child namespaces
115-
- When creating private helper functions, if possible **prefer to place them in an anonymous namespace in the cpp file** instead of the `private:` section of the header file
111+
- When creating private helper functions, **PREFER TO PLACE THEM IN AN ANONYMOUS NAMESPACE IN THE CPP FILE** instead of the `private:` section of the header file
116112
- Both GCC and Clang are supported compilers, so any proposed code **should not be compiler-specific**
117113
- WHEN RUNNING THE CMAKE BUILD COMMAND, SEND OUTPUT TO A TEMPORARY FILE SO YOU DON'T POLLUTE YOUR CONTEXT. You can then check if the build succeeded by looking at the exit code. If non-zero, inspect the file and see what went wrong.
118114

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ set(CMAKE_CXX_STANDARD 23)
66
set(CMAKE_CXX_STANDARD_REQUIRED ON)
77
set(CMAKE_CXX_EXTENSIONS OFF)
88
set(CMAKE_VERBOSE_MAKEFILE ON)
9+
set(FETCHCONTENT_QUIET OFF)
910

1011
# Enable compilation warnings
1112
if (MSVC)

Documentation/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ include(FetchContent)
22
FetchContent_Declare(
33
doxygen-awesome-css
44
GIT_REPOSITORY "https://github.com/jothepro/doxygen-awesome-css"
5-
GIT_TAG "v2.3.4")
5+
GIT_TAG "v2.4.0")
66
FetchContent_MakeAvailable(doxygen-awesome-css)
77
FetchContent_GetProperties(doxygen-awesome-css SOURCE_DIR AWESOME_CSS_DIR)
88

Porytiles2/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# Set a variable that points to the global include directory for Porytiles
33
set(PORYTILES2_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/Porytiles2/include)
44

5+
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -fstandalone-debug -fno-limit-debug-info -fno-omit-frame-pointer")
6+
57
add_subdirectory(lib)
68
add_subdirectory(tests)
79
add_subdirectory(tools)

Porytiles2/Notes/artifact_key_crtp.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
The following code is **not legal C++** because virtual functions cannot be templated:
66

7-
```cpp
7+
```c++
88
template<typename T>
99
[[nodiscard]] virtual ArtifactKey<T> key_for(const std::string &tileset_name, const TilesetArtifact &artifact) const = 0;
1010
```
@@ -17,7 +17,7 @@ Move the template to the class level and use static polymorphism instead of virt
1717
1818
### Basic Implementation
1919
20-
```cpp
20+
```c++
2121
template<typename T, typename Derived>
2222
class ArtifactKeyProvider {
2323
public:
@@ -42,7 +42,7 @@ public:
4242

4343
### Simple Concept Constraint
4444

45-
```cpp
45+
```c++
4646
#include <concepts>
4747
#include <type_traits>
4848

@@ -68,7 +68,7 @@ public:
6868
6969
### Comprehensive Concept with Additional Checks
7070
71-
```cpp
71+
```c++
7272
// More detailed concept with additional checks
7373
template<typename Derived, typename T>
7474
concept HasKeyForImpl = requires {
@@ -94,7 +94,7 @@ concept IsArtifactKeyProvider =
9494

9595
If you're not on C++20 or prefer static assertions:
9696

97-
```cpp
97+
```c++
9898
template<typename T, typename Derived>
9999
class ArtifactKeyProvider {
100100
private:
@@ -128,7 +128,7 @@ public:
128128
129129
### Correct Implementation
130130
131-
```cpp
131+
```c++
132132
// This will compile fine
133133
template<typename T>
134134
class GoodProvider : public ArtifactKeyProvider<T, GoodProvider<T>> {
@@ -142,7 +142,7 @@ public:
142142

143143
### Incorrect Implementation (Compile-Time Error)
144144

145-
```cpp
145+
```c++
146146
// This will fail at compile time with a clear error about not satisfying HasKeyForImpl
147147
template<typename T>
148148
class BadProvider : public ArtifactKeyProvider<T, BadProvider<T>> {

0 commit comments

Comments
 (0)