13namespace asset_compiler
18auto hash_file(
const fs::path& file_path) -> std::string
20 const bool is_text = !
ex::is_binary(file_path.extension().string());
31 const std::vector<fs::path>& dependency_paths)
37 if(dependency_paths.empty())
42 APPLOG_ERROR(
"Failed to fingerprint source file: {}", source_file_path.string());
49 std::vector<std::string> fingerprints;
50 fingerprints.reserve(dependency_paths.size() + 1);
52 const auto source_fingerprint_part = hash_file(source_file_path);
53 if(!source_fingerprint_part.empty())
55 fingerprints.push_back(source_fingerprint_part);
58 for(
const auto& dep_path : dependency_paths)
60 fs::error_code dep_ec;
61 if(!fs::exists(dep_path, dep_ec) || dep_ec)
65 const auto fingerprint = hash_file(dep_path);
66 if(fingerprint.empty())
70 fingerprints.push_back(fingerprint);
73 if(fingerprints.empty())
78 if(fingerprints.size() == 1)
84 fingerprints.data() + 1,
85 fingerprints.size() - 1);
87 catch(
const std::exception& e)
89 APPLOG_ERROR(
"Exception while fingerprinting {}: {}", source_file_path.string(), e.what());
96 return compiled_asset_path.string() +
".manifest";
103 std::ofstream file(manifest_path);
106 APPLOG_ERROR(
"Failed to open manifest file for writing: {}", manifest_path.string());
111 success &=
try_save(archive, ser20::make_nvp(
"source_fingerprint", manifest.source_fingerprint));
112 success &=
try_save(archive, ser20::make_nvp(
"format_version", manifest.format_version));
113 success &=
try_save(archive, ser20::make_nvp(
"fingerprint_version", manifest.fingerprint_version));
116 catch(
const std::exception& e)
118 APPLOG_ERROR(
"Exception while saving manifest {}: {}", manifest_path.string(), e.what());
127 std::ifstream file(manifest_path);
130 APPLOG_ERROR(
"Failed to open manifest file for reading: {}", manifest_path.string());
134 try_load(archive, ser20::make_nvp(
"source_fingerprint", manifest.source_fingerprint));
135 try_load(archive, ser20::make_nvp(
"format_version", manifest.format_version));
136 try_load(archive, ser20::make_nvp(
"fingerprint_version", manifest.fingerprint_version));
139 catch(
const std::exception& e)
141 APPLOG_ERROR(
"Exception while loading manifest {}: {}", manifest_path.string(), e.what());
148auto resolve_manifest_input_file(
const fs::path& key) -> fs::path
152 if(source_key.extension() ==
".meta")
154 source_key.replace_extension();
169 APPLOG_WARNING(
"Fingerprint algorithm changed for {}, recompilation needed", source_path.string());
172 auto source_key = resolve_manifest_input_file(source_path);
180 const std::vector<fs::path>& dependency_paths) ->
bool
184 APPLOG_WARNING(
"Fingerprint algorithm changed for {}, recompilation needed", source_path.string());
187 auto source_key = resolve_manifest_input_file(source_path);
195 auto source_key = resolve_manifest_input_file(source_path);
196 auto extension = source_key.extension().string();
198 return manifest.format_version != current_version;
#define APPLOG_WARNING(...)
#define APPLOG_ERROR(...)
auto get_data_directory(const std::string &prefix={}) -> std::string
auto get_meta_directory(const std::string &prefix={}) -> std::string
auto is_binary(const std::string &ex) -> bool
auto get_format_version() -> uint64_t
auto hash_file_fingerprint(const path &file_path, bool normalize_text_line_endings) -> std::string
Hash a file's contents. Text assets normalize CRLF to LF before hashing.
auto combine_file_fingerprints(const std::string &first_fingerprint, const std::string *additional_fingerprints, size_t additional_count) -> std::string
Combine per-file fingerprints (raw 128-bit digests) into one hex fingerprint.
path resolve_protocol(const path &_path)
Given the specified path/filename, resolve the final full filename. This will be based on either the ...
constexpr uint64_t current_source_fingerprint_version
xxHash3 128-bit fingerprints (hex). Bump when the hashing or dependency-ordering scheme changes.
path replace(const path &_path, const path &_sequence, const path &_new_sequence)
Replacing any occurences of the specified path sequence with another.
path convert_to_protocol(const path &_path)
Oposite of the resolve_protocol this function tries to convert to protocol path from an absolute one.
auto create_oarchive_associative(std::ostream &stream)
auto create_iarchive_associative(std::istream &stream)
auto get_manifest_path(const fs::path &compiled_asset_path) -> fs::path
Generate manifest file path from compiled asset path.
auto is_compiled_format_changed(const fs::path &source_path, const asset_manifest &manifest) -> bool
auto is_fingerprint_algorithm_current(const asset_manifest &manifest) -> bool
auto save_manifest(const fs::path &manifest_path, const asset_manifest &manifest) -> bool
Save manifest to file.
auto is_source_file_changed(const fs::path &source_path, const asset_manifest &manifest) -> bool
Check if source file has changed compared to manifest (source-only)
auto load_manifest(const fs::path &manifest_path, asset_manifest &manifest) -> bool
Load manifest from file.
auto try_save(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
auto try_load(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
Manifest data for compiled assets.
std::string source_fingerprint
Content fingerprint of source inputs (xxHash3 128-bit hex).
void compute_source_fingerprint(const fs::path &source_key)
Compute fingerprint from source file only.
uint64_t fingerprint_version
Fingerprint algorithm version. Legacy manifests use 0 (SHA1).