Porytiles
Loading...
Searching...
No Matches
import_primary_tileset.cpp
Go to the documentation of this file.
2
3#include <map>
4#include <memory>
5#include <string>
6
17
18namespace porytiles {
19
20ChainableResult<void> ImportPrimaryTileset::import(const std::string &tileset_name) const
21{
22 // Step 1: Validate tileset exists and isn't already Porytiles-managed
23 if (!metadata_provider_->exists(tileset_name)) {
24 return FormattableError{"Tileset '{}' does not exist.", FormatParam{tileset_name, Style::bold}};
25 }
26 if (tileset_manager_->is_porytiles_managed(tileset_name)) {
27 return FormattableError{"Tileset '{}' is already Porytiles-managed.", FormatParam{tileset_name, Style::bold}};
28 }
29
30 // Step 2: Call the importer service to bring in the PorymapTilesetComponent from vanilla assets
32 imported_porymap_component,
33 importer_->import_porymap_component_from_vanilla(tileset_name),
34 void,
35 "Import job failed for '{}'.",
36 FormatParam(tileset_name, Style::bold));
37 // A blank Porytiles component carries no prior attributes.csv state, so its layer_type pin state defaults to
38 // no_csv. The decompiler below reads that as "pin every row from the bin", which is exactly what a from-scratch
39 // import should be doing. Since import always clobbers porytiles_src/, there is no prior CSV to preserve.
40 auto blank_porytiles_component = std::make_unique<PorytilesTilesetComponent>();
41 auto tileset = std::make_unique<Tileset>(
42 tileset_name, std::move(blank_porytiles_component), std::move(imported_porymap_component));
43
44 // Step 3: Decompile the PorymapTilesetComponent to produce a matching PorytilesTilesetComponent
46 decompiled_tileset,
47 decompiler_->decompile(*tileset),
48 void,
49 "Decompile job failed for '{}'.",
50 FormatParam(tileset_name, Style::bold));
51
52 // Step 4: Re-compile the decompiled tileset in locked edit mode. This forces byte-equivalence between the imported
53 // Porymap assets and the Porytiles sources we just decompiled from them, and surfaces any invalid input (e.g. a
54 // palette slot containing the extrinsic transparency color) as a proper diagnostic at import time rather than
55 // deferring the failure to a later compile.
56 //
57 // The override provider forces tiles_edit_mode and palettes_edit_mode to 'locked' without touching other user
58 // config. ET is intentionally NOT overridden here: it is a property of the Porymap palettes themselves and the
59 // user's configured value is the right thing to validate against.
60 auto import_override = std::make_unique<OverrideConfigProvider>(
61 ConfigScopeType::tileset, tileset_name, "import-tileset internal locked recompile");
62 import_override->set_tiles_edit_mode(ArtifactEditMode::locked);
63 import_override->set_palettes_edit_mode(ArtifactEditMode::locked);
64 domain_config_->add_provider(std::move(import_override));
65
67 compiled_tileset,
68 compiler_->compile(*decompiled_tileset, /*is_secondary=*/false),
69 void,
70 "Internal locked recompile failed for '{}'.",
71 FormatParam(tileset_name, Style::bold));
72
73 // Step 5: Save the compiled tileset so Porymap artifacts round-trip byte-equivalent to the Porytiles source.
75 tileset_repo_->save(*compiled_tileset),
76 void,
77 "Tileset save job failed for '{}'.",
78 FormatParam(tileset_name, Style::bold));
79
80 // Step 6: Confirmed save succeeded, now call PorytilesTilesetManager::persist_existing to persist "managed"
81 // state (which in the Project-based impls writes to tileset-manifest.json and updates various project C files).
82 // This should never fail for a reasonable cause, so we don't need to worry about rolling back or weird broken
83 // state. If it does fail for extraordinary reasons, we present a helpful message to users so they can manually
84 // recover.
86 tileset_manager_->persist_managed_existing(tileset_name),
87 void,
88 "Failed to persist Porytiles-managed state for '{}'.",
89 FormatParam(tileset_name, Style::bold));
90
91 // Step 7: Handle animation code wiring.
92 if (!compiled_tileset->porytiles_component().anims().empty()) {
93 // Tileset has animations - wire the generated code
95 tileset_manager_->wire_anim_code(tileset_name, /*is_secondary=*/false),
96 void,
97 "Failed to wire animation code for '{}'.",
98 FormatParam(tileset_name, Style::bold));
99 }
100 else {
101 // Tileset has no animations - remove any stale wiring
103 tileset_manager_->remove_wired_anim_code(tileset_name, /*is_secondary=*/false),
104 void,
105 "Failed to remove wired animation code for '{}'.",
106 FormatParam(tileset_name, Style::bold));
107 }
108
109 return {};
110}
111
112} // namespace porytiles
#define PT_TRY_ASSIGN_CHAIN_ERR(var, expr, return_type,...)
Unwraps a ChainableResult, chaining a new error message on failure.
#define PT_TRY_CALL_CHAIN_ERR(expr, return_type,...)
Unwraps a void ChainableResult, chaining a new error message on failure.
A result type that maintains a chainable sequence of errors for debugging and error reporting.
virtual void add_provider(std::unique_ptr< ConfigProvider > provider)=0
Prepends a ConfigProvider to the provider chain at highest priority.
A text parameter with associated styling for formatted output.
General-purpose error implementation with formatted message support.
Definition error.hpp:57
ChainableResult< void > import(const std::string &tileset_name) const
virtual ChainableResult< void > wire_anim_code(const std::string &tileset_name, bool is_secondary) const =0
Wires animation code for a tileset that already has its manifest persisted.
virtual ChainableResult< void > persist_managed_existing(const std::string &tileset_name) const =0
Persists managed state for an existing tileset.
virtual bool is_porytiles_managed(const std::string &tileset_name) const =0
Checks whether a tileset is managed by Porytiles.
virtual ChainableResult< void > remove_wired_anim_code(const std::string &tileset_name, bool is_secondary) const =0
Removes wired animation code for a tileset from the project.
ChainableResult< std::unique_ptr< Tileset > > decompile(const Tileset &tileset) const
virtual ChainableResult< std::unique_ptr< PorymapTilesetComponent > > import_porymap_component_from_vanilla(const std::string &tileset_name) const =0
Imports vanilla Porymap assets for the given tileset into a PorymapTilesetComponent.
static const Style bold
Bold text formatting.
ChainableResult< std::unique_ptr< Tileset > > compile(const Tileset &tileset, bool is_secondary=false, const Tileset *paired_primary=nullptr) const
Compiles the given Tileset, producing a new Tileset with compiled Porymap assets.
virtual bool exists(const std::string &tileset_name) const =0
Checks whether a tileset exists in the backing store for the given tileset name.
ChainableResult< void > save(const Tileset &tileset) const
Persists a given Tileset and caches new artifact checksums.
@ locked
Artifacts cannot be edited; must use existing from base tileset.
@ tileset
Configuration scoped to a specific tileset.