Porytiles
Loading...
Searching...
No Matches
compile_primary_tileset.cpp
Go to the documentation of this file.
2
3#include <memory>
4#include <string>
5
11
12namespace porytiles {
13
14ChainableResult<void> CompilePrimaryTileset::compile(const std::string &tileset_name) const
15{
16 // 1. Precondition: tileset must exist. Check if it is Porytiles-managed. If not, abort with error.
17 assert_or_panic(metadata_provider_->exists(tileset_name), "precondition violated: tileset must exist");
18 if (!tileset_manager_->is_porytiles_managed(tileset_name)) {
19 return FormattableError{
20 "Tileset '{}' exists but is not Porytiles-managed.", FormatParam{tileset_name, Style::bold}};
21 }
22
23 // 2. Load the tileset into a `Tileset` aggregate.
25 tileset,
26 tileset_repo_->load(tileset_name),
27 void,
28 diag_->formatter().format("Failed to load tileset '{}'.", FormatParam(tileset_name, Style::bold)));
29
30 PT_UNWRAP_TILESET_CONFIG_PTR(app_config_, verify_checksums, tileset_name, void);
31 if (!tileset_repo_->checksum_provider().cached_checksums_exist(tileset_name) && verify_checksums) {
32 std::vector<std::string> err_msg{};
33 err_msg.emplace_back(diag_->formatter().format(
34 "No cached checksums found for tileset '{}'.", FormatParam{tileset_name, Style::bold}));
35 err_msg.emplace_back(diag_->formatter().format(
36 "Expected to find file '{}'.",
37 FormatParam{"porytiles/tilesets/" + tileset_name + "/tileset.cache.json", Style::bold}));
38 err_msg.emplace_back("Checksum verification requested via configuration.");
39 err_msg.append_range(format_config_note_with_separator(diag_->formatter(), verify_checksums));
40
42 }
43
44 // Only perform the checksum checks if: 1) cached checksums exist and 2) the user is requesting checksum validation
45 if (tileset_repo_->checksum_provider().cached_checksums_exist(tileset_name) && verify_checksums.value()) {
46 // 3. If `PorymapTilesetComponent` is not empty, compare with cached checksums in `tileset.cache.json`. If
47 // any differ, bail with the message "unimported changes present in Porymap asset X."
48 if (!tileset->porymap_component().is_empty()) {
50 porymap_keys,
51 tileset_repo_->key_provider().get_porymap_artifact_keys(tileset_name),
52 void,
53 "Failed to get Porymap artifact keys.");
54 const auto mismatched_keys =
55 tileset_repo_->checksum_provider().find_unsynced_tileset_artifacts(tileset_name, porymap_keys);
56 if (!mismatched_keys.empty()) {
57 std::vector<std::string> err_msg{};
58 err_msg.emplace_back("Changes present in Porymap assets:");
59 for (const auto &key : mismatched_keys) {
60 err_msg.emplace_back(diag_->formatter().format(" {}", FormatParam{key.key(), Style::bold}));
61 }
62 err_msg.emplace_back("");
63 err_msg.emplace_back("Compiling now would clobber your Porymap asset changes.");
64 err_msg.emplace_back("To resolve:");
65 err_msg.emplace_back(diag_->formatter().format(
66 " - Run '{} {}' to synchronize assets.",
67 FormatParam{"decompile-tileset", Style::bold},
68 FormatParam{tileset_name, Style::bold}));
69 err_msg.emplace_back(diag_->formatter().format(
70 " - {} disable checksum verification to allow the clobber.", FormatParam{"OR", Style::bold}));
71 err_msg.emplace_back(diag_->formatter().format(
72 " - {} delete '{}' cache file.",
74 FormatParam{"porytiles/tilesets/" + tileset_name + "/tileset.cache.json", Style::bold}));
75 err_msg.append_range(format_config_note_with_separator(diag_->formatter(), verify_checksums));
77 }
78 }
79
80 // 4. If all `PorytilesTilesetComponent` checksums match those cached in `tileset.cache.json`, bail with
81 // the message "nothing to do."
83 porytiles_keys,
84 tileset_repo_->key_provider().get_porytiles_artifact_keys(tileset_name),
85 void,
86 "Failed to get Porytiles artifact keys.");
87 if (tileset_repo_->checksum_provider().all_checksums_tileset_match(tileset_name, porytiles_keys)) {
88 diag_->warning(
89 "nothing-to-do",
90 "Skipping compilation for '{}', no changes found.",
91 FormatParam{tileset_name, Style::bold});
92 return {};
93 }
94 }
95
96 // 5. Compile the `Tileset`, generating a new modified `Tileset`.
98 new_tileset,
99 compiler_->compile(*tileset, /*is_secondary=*/false),
100 void,
101 "Compilation job failed for '{}'.",
102 FormatParam(tileset_name, Style::bold));
103
104 // 6. Persist the `Tileset` (which also caches the checksums).
106 tileset_repo_->save(*new_tileset),
107 void,
108 "Tileset save job failed for '{}'.",
109 FormatParam(tileset_name, Style::bold));
110
111 // 7. Handle animation code wiring
112 if (!new_tileset->porymap_component().anims().empty()) {
113 // Tileset has animations - wire the generated code
115 tileset_manager_->wire_anim_code(tileset_name, /*is_secondary=*/false),
116 void,
117 "Failed to wire animation code for '{}'.",
118 FormatParam(tileset_name, Style::bold));
119 }
120 else {
121 // Tileset has no animations - remove any stale wiring
123 tileset_manager_->remove_wired_anim_code(tileset_name, /*is_secondary=*/false),
124 void,
125 "Failed to remove wired animation code for '{}'.",
126 FormatParam(tileset_name, Style::bold));
127 }
128
129 return {};
130}
131
132} // 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.
bool all_checksums_tileset_match(const std::string &name, const std::vector< ArtifactKey > &artifact_keys) const
Checks if all artifact checksums for the given Tileset match their cached values.
std::vector< ArtifactKey > find_unsynced_tileset_artifacts(const std::string &name, const std::vector< ArtifactKey > &keys_to_check) const
Finds all artifacts for the given Tileset with unsynced changes compared to cached checksums.
bool cached_checksums_exist(const std::string &name) const
Check if any cached checksums exist for the given tileset.
A result type that maintains a chainable sequence of errors for debugging and error reporting.
ChainableResult< void > compile(const std::string &tileset_name) const
Compiles the primary Tileset with the given tileset name.
A text parameter with associated styling for formatted output.
General-purpose error implementation with formatted message support.
Definition error.hpp:63
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 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.
static const Style bold
Bold text formatting.
virtual std::string format(const std::string &format_str, const std::vector< FormatParam > &params) const
Formats a string with styled parameters using fmtlib syntax.
virtual ChainableResult< std::vector< ArtifactKey > > get_porytiles_artifact_keys(const std::string &tileset_name) const
Gets the keys for all Porytiles artifacts present in the given Tileset.
virtual ChainableResult< std::vector< ArtifactKey > > get_porymap_artifact_keys(const std::string &tileset_name) const
Gets the keys for all Porymap artifacts present in the given Tileset.
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.
ChainableResult< std::unique_ptr< Tileset > > load(const std::string &name) const
Loads an existing Tileset from storage.
const TilesetArtifactKeyProvider & key_provider() const
Gets a reference to the TilesetArtifactKeyProvider for this repo.
const ArtifactChecksumProvider & checksum_provider() const
Gets a reference to the ArtifactChecksumProvider for this repo.
const TextFormatter & formatter() const
virtual void warning(const std::string &tag, const std::vector< std::string > &lines) const =0
Display a tagged warning message.
void assert_or_panic(bool condition, const StringViewSourceLoc &s)
Conditionally panics if the given condition is false.
Definition panic.cpp:53
std::vector< std::string > format_config_note_with_separator(const TextFormatter &format, const ConfigValue< T > &config)
Format a ConfigValue into diagnostic note lines with a separator.
@ tileset
Configuration scoped to a specific tileset.
#define PT_UNWRAP_TILESET_CONFIG_PTR(ptr, config, tileset_name, return_type)
Unwraps a tileset-scoped config value via pointer access, returning early if the value is not availab...