Unravel Engine C++ Reference
Loading...
Searching...
No Matches
asset_manifest.cpp
Go to the documentation of this file.
1#include "asset_manifest.h"
2#include <logging/logging.h>
3#include <fstream>
4#include <array>
9
10namespace unravel
11{
12namespace asset_compiler
13{
14
15
17{
18 fs::error_code ec;
19 if(!fs::exists(source_file_path, ec) || ec)
20 {
21 APPLOG_WARNING("Source file does not exist for SHA computation: {}", source_file_path.string());
22 source_sha = "";
23 return;
24 }
25
26 try
27 {
28 std::ifstream file(source_file_path, std::ios::binary);
29 if(!file.is_open())
30 {
31 APPLOG_ERROR("Failed to open source file for SHA computation: {}", source_file_path.string());
32 source_sha = "";
33 return;
34 }
35
36 auto hasher = hpp::sha1::compute_file_sha1(file);
37
38 std::array<char, SHA1_HEX_SIZE> hex_buffer{};
39 hasher.print_hex(hex_buffer.data(), true, false);
40 source_sha = std::string(hex_buffer.data());
41 }
42 catch(const std::exception& e)
43 {
44 APPLOG_ERROR("Exception while computing SHA for {}: {}", source_file_path.string(), e.what());
45 source_sha = "";
46 }
47}
48
49auto get_manifest_path(const fs::path& compiled_asset_path) -> fs::path
50{
51 return compiled_asset_path.string() + ".manifest";
52}
53
54auto save_manifest(const fs::path& manifest_path, const asset_manifest& manifest) -> bool
55{
56 try
57 {
58 std::ofstream file(manifest_path);
59 if(!file.is_open())
60 {
61 APPLOG_ERROR("Failed to open manifest file for writing: {}", manifest_path.string());
62 return false;
63 }
64
65 auto archive = ser20::create_oarchive_associative(file);
66
67 archive(ser20::make_nvp("source_path", manifest.source_file_path.generic_string()));
68 archive(ser20::make_nvp("source_sha", manifest.source_sha));
69 archive(ser20::make_nvp("source_timestamp", manifest.source_timestamp));
70
71 return true;
72 }
73 catch(const std::exception& e)
74 {
75 APPLOG_ERROR("Exception while saving manifest {}: {}", manifest_path.string(), e.what());
76 return false;
77 }
78}
79
80auto load_manifest(const fs::path& manifest_path, asset_manifest& manifest) -> bool
81{
82 try
83 {
84 fs::error_code ec;
85 if(!fs::exists(manifest_path, ec) || ec)
86 {
87 return false;
88 }
89
90 std::ifstream file(manifest_path);
91 if(!file.is_open())
92 {
93 APPLOG_ERROR("Failed to open manifest file for reading: {}", manifest_path.string());
94 return false;
95 }
96
97 auto archive = ser20::create_iarchive_associative(file);
98
99 std::string source_path;
100 archive(ser20::make_nvp("source_path", source_path));
101 manifest.source_file_path = fs::path(source_path);
102 archive(ser20::make_nvp("source_sha", manifest.source_sha));
103 archive(ser20::make_nvp("source_timestamp", manifest.source_timestamp));
104 return true;
105 }
106 catch(const std::exception& e)
107 {
108 APPLOG_ERROR("Exception while loading manifest {}: {}", manifest_path.string(), e.what());
109 return false;
110 }
111}
112
113auto is_source_file_changed(const fs::path& source_path, const asset_manifest& manifest) -> bool
114{
115 auto resolve_input_file = [](const fs::path& key) -> fs::path
116 {
117 fs::path absolute_path = fs::convert_to_protocol(key);
119 if(absolute_path.extension() == ".meta")
120 {
121 absolute_path.replace_extension();
122 }
123 return absolute_path;
124 };
125
126 auto source_file_path = resolve_input_file(source_path);
127 // Create a temporary manifest to compute current SHA
128 asset_manifest current_manifest(source_file_path);
129
130 if(current_manifest.source_timestamp == manifest.source_timestamp)
131 {
132 return false;
133 }
134
135 current_manifest.compute_source_sha();
136 // Compare SHA values
137 return current_manifest.source_sha != manifest.source_sha;
138}
139
140} // namespace asset_compiler
141} // namespace unravel
#define APPLOG_WARNING(...)
Definition logging.h:19
#define APPLOG_ERROR(...)
Definition logging.h:20
auto get_data_directory(const std::string &prefix={}) -> std::string
auto get_meta_directory(const std::string &prefix={}) -> std::string
path resolve_protocol(const path &_path)
Given the specified path/filename, resolve the final full filename. This will be based on either the ...
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 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.
auto load_manifest(const fs::path &manifest_path, asset_manifest &manifest) -> bool
Load manifest from file.
Manifest data for compiled assets.
fs::path source_file_path
Path to the source file.
fs::file_time_type::clock::time_point source_timestamp
Timestamp when the asset was compiled.
std::string source_sha
SHA1 hash of the source file content.