This commit is contained in:
parent
03717b5f33
commit
dea67ae5aa
2 changed files with 94 additions and 29 deletions
|
|
@ -292,36 +292,82 @@ BuildResult Crafter::Build(Configuration& config, std::unordered_map<fs::path, s
|
|||
});
|
||||
}
|
||||
|
||||
// Asset compilation: each .png/.obj listed in cfg.assets is run through
|
||||
// Crafter.Asset's library (linked into crafter-build directly — see
|
||||
// :Asset_impl) to produce the SaveCompressed .ctex/.cmesh in outputDir.
|
||||
// Skipped if the output is newer than the source. Parallel with shaders
|
||||
// and module compiles; cancellation participates in the same flag.
|
||||
auto assetOutput = [](const fs::path& asset) -> std::optional<fs::path> {
|
||||
std::string ext = asset.extension().string();
|
||||
if (ext == ".png") return fs::path(asset.filename()).replace_extension(".ctex");
|
||||
if (ext == ".obj") return fs::path(asset.filename()).replace_extension(".cmesh");
|
||||
// Asset compilation: each cfg.assets entry is either a single .png/.obj
|
||||
// file (flat output: outputDir/<filename>.ctex/cmesh — preserves the
|
||||
// original behavior) or a directory (recursed, with the relative tree
|
||||
// mirrored under outputDir/<dirname>/; .png/.obj are compressed, every
|
||||
// other file is copied through unchanged). Directory mode lets mod/map
|
||||
// trees keep their nested layout so mod.json paths like
|
||||
// "cannon/base.cmesh" resolve correctly at runtime.
|
||||
// Skipped per-file if the output is newer than the source. Each
|
||||
// compress runs in its own thread; passthrough copies are bundled into
|
||||
// a single thread to match the cfg.files pattern.
|
||||
auto compressedName = [](const fs::path& src) -> std::optional<fs::path> {
|
||||
std::string ext = src.extension().string();
|
||||
if (ext == ".png") return fs::path(src.filename()).replace_extension(".ctex");
|
||||
if (ext == ".obj") return fs::path(src.filename()).replace_extension(".cmesh");
|
||||
return std::nullopt;
|
||||
};
|
||||
for (const fs::path& asset : config.assets) {
|
||||
std::optional<fs::path> outName = assetOutput(asset);
|
||||
if (!outName) {
|
||||
buildCancelled.store(true);
|
||||
buildError = std::format("{}: unsupported asset extension (expected .png or .obj)", asset.string());
|
||||
break;
|
||||
}
|
||||
fs::path out = outputDir / *outName;
|
||||
if (fs::exists(out) && fs::exists(asset) && fs::last_write_time(asset) <= fs::last_write_time(out)) continue;
|
||||
threads.emplace_back([&asset, out = std::move(out), &buildError, &buildCancelled]() {
|
||||
Progress::Task task(std::format("Compressing asset {}", asset.filename().string()));
|
||||
auto submitCompress = [&](fs::path sourcePath, fs::path outRelative) {
|
||||
fs::path out = outputDir / outRelative;
|
||||
if (fs::exists(out) && fs::exists(sourcePath) && fs::last_write_time(sourcePath) <= fs::last_write_time(out)) return;
|
||||
threads.emplace_back([sourcePath = std::move(sourcePath), out = std::move(out), &buildError, &buildCancelled]() {
|
||||
Progress::Task task(std::format("Compressing asset {}", sourcePath.filename().string()));
|
||||
if (buildCancelled.load(std::memory_order_relaxed)) return;
|
||||
std::string result = CompressAsset(asset, out);
|
||||
std::error_code ec;
|
||||
fs::create_directories(out.parent_path(), ec);
|
||||
std::string result = CompressAsset(sourcePath, out);
|
||||
if (result.empty()) return;
|
||||
bool expected = false;
|
||||
if (buildCancelled.compare_exchange_strong(expected, true)) {
|
||||
buildError = std::move(result);
|
||||
}
|
||||
});
|
||||
};
|
||||
std::vector<std::pair<fs::path, fs::path>> assetPassthroughs;
|
||||
for (const fs::path& asset : config.assets) {
|
||||
if (fs::is_directory(asset)) {
|
||||
fs::path topName = asset.filename();
|
||||
for (const auto& entry : fs::recursive_directory_iterator(asset)) {
|
||||
if (!entry.is_regular_file()) continue;
|
||||
fs::path rel = fs::relative(entry.path(), asset);
|
||||
if (std::optional<fs::path> compName = compressedName(entry.path())) {
|
||||
submitCompress(entry.path(), topName / rel.parent_path() / *compName);
|
||||
} else {
|
||||
assetPassthroughs.emplace_back(entry.path(), topName / rel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::optional<fs::path> outName = compressedName(asset);
|
||||
if (!outName) {
|
||||
buildCancelled.store(true);
|
||||
buildError = std::format("{}: unsupported asset extension (expected .png or .obj, or a directory)", asset.string());
|
||||
break;
|
||||
}
|
||||
submitCompress(asset, *outName);
|
||||
}
|
||||
}
|
||||
if (!assetPassthroughs.empty()) {
|
||||
threads.emplace_back([passthroughs = std::move(assetPassthroughs), &outputDir, &buildCancelled, &buildError]() {
|
||||
Progress::Task task("Copying asset passthrough files");
|
||||
if (buildCancelled.load(std::memory_order_relaxed)) return;
|
||||
try {
|
||||
for (const auto& [src, rel] : passthroughs) {
|
||||
fs::path dst = outputDir / rel;
|
||||
fs::create_directories(dst.parent_path());
|
||||
if (!fs::exists(dst)) {
|
||||
fs::copy_file(src, dst);
|
||||
} else if (fs::last_write_time(src) > fs::last_write_time(dst)) {
|
||||
fs::copy_file(src, dst, fs::copy_options::overwrite_existing);
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
bool expected = false;
|
||||
if (buildCancelled.compare_exchange_strong(expected, true)) {
|
||||
buildError = e.what();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
threads.emplace_back([&config, &outputDir, &buildCancelled, &buildError]() {
|
||||
|
|
@ -679,6 +725,16 @@ BuildResult Crafter::Build(Configuration& config, std::unordered_map<fs::path, s
|
|||
copyTree(src, outputDir / additionalFile.filename());
|
||||
}
|
||||
for (const fs::path& asset : dep->assets) {
|
||||
// Directory entry: the dep already mirrored the
|
||||
// (compressed + passthrough) tree under
|
||||
// depBinDir/<asset.filename()>/. Forward it wholesale
|
||||
// so our bin dir gets the same layout.
|
||||
if (fs::is_directory(asset)) {
|
||||
fs::path src = depBinDir / asset.filename();
|
||||
if (!fs::exists(src)) continue;
|
||||
copyTree(src, outputDir / asset.filename());
|
||||
continue;
|
||||
}
|
||||
std::string ext = asset.extension().string();
|
||||
fs::path srcName = asset.filename();
|
||||
if (ext == ".png") srcName.replace_extension(".ctex");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue