2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-08 23:07:42 +00:00

Explicit Asset ID refactor

This commit is contained in:
Jack Andersen
2019-09-30 21:38:03 -10:00
parent c7ffe725ae
commit 16ca0d24c2
113 changed files with 1782 additions and 2057 deletions

View File

@@ -56,66 +56,6 @@ static const hecl::SystemString regP = _SYS_STR("PAL");
void SpecBase::setThreadProject() { UniqueIDBridge::SetThreadProject(m_project); }
template <typename IDType>
IDRestorer<IDType>::IDRestorer(const hecl::ProjectPath& yamlPath, const hecl::Database::Project& project) {
using ValType = typename IDType::value_type;
if (!yamlPath.isFile())
return;
athena::io::YAMLDocReader r;
athena::io::FileReader fr(yamlPath.getAbsolutePath());
if (!fr.isOpen() || !r.parse(&fr))
return;
m_newToOrig.reserve(r.getRootNode()->m_mapChildren.size());
m_origToNew.reserve(r.getRootNode()->m_mapChildren.size());
for (const auto& node : r.getRootNode()->m_mapChildren) {
char* end = const_cast<char*>(node.first.c_str());
ValType id = strtoull(end, &end, 16);
if (end != node.first.c_str() + sizeof(ValType) * 2)
continue;
hecl::ProjectPath path(project.getProjectWorkingPath(), node.second->m_scalarString.c_str());
m_newToOrig.push_back(std::make_pair(IDType{path.hash().valT<ValType>(), true}, IDType{id, true}));
m_origToNew.push_back(std::make_pair(IDType{id, true}, IDType{path.hash().valT<ValType>(), true}));
}
std::sort(m_newToOrig.begin(), m_newToOrig.end(),
[](const std::pair<IDType, IDType>& a, const std::pair<IDType, IDType>& b)
{ return a.first.toUint64() < b.first.toUint64(); });
std::sort(m_origToNew.begin(), m_origToNew.end(),
[](const std::pair<IDType, IDType>& a, const std::pair<IDType, IDType>& b)
{ return a.first.toUint64() < b.first.toUint64(); });
Log.report(logvisor::Info, fmt(_SYS_STR("Loaded Original IDs '{}'")), yamlPath.getRelativePath());
}
template <typename IDType>
IDType IDRestorer<IDType>::newToOriginal(IDType id) const {
if (!id.isValid())
return {};
auto search =
rstl::binary_find(m_newToOrig.cbegin(), m_newToOrig.cend(), id, [](const auto& id) { return id.first; });
if (search == m_newToOrig.cend())
return {};
return search->second;
}
template <typename IDType>
IDType IDRestorer<IDType>::originalToNew(IDType id) const {
if (!id.isValid())
return {};
auto search =
rstl::binary_find(m_origToNew.cbegin(), m_origToNew.cend(), id, [](const auto& id) { return id.first; });
if (search == m_origToNew.cend())
return {};
return search->second;
}
template class IDRestorer<UniqueID32>;
template class IDRestorer<UniqueID64>;
template class IDRestorer<UniqueID128>;
bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps) {
m_disc = nod::OpenDiscFromImage(info.srcpath, m_isWii);
if (!m_disc)
@@ -186,12 +126,11 @@ bool IsPathAudioGroup(const hecl::ProjectPath& path) {
}
static bool IsPathSong(const hecl::ProjectPath& path) {
if (path.getPathType() != hecl::ProjectPath::Type::Glob || !path.getWithExtension(_SYS_STR(".mid"), true).isFile() ||
if (path.getPathType() != hecl::ProjectPath::Type::Glob ||
!path.getWithExtension(_SYS_STR(".mid"), true).isFile() ||
!path.getWithExtension(_SYS_STR(".yaml"), true).isFile()) {
if (path.isFile() && !hecl::StrCmp(_SYS_STR("mid"), path.getLastComponentExt().data()) &&
path.getWithExtension(_SYS_STR(".yaml"), true).isFile())
return true;
return false;
return path.isFile() && path.getLastComponentExt() == _SYS_STR("mid") &&
path.getWithExtension(_SYS_STR(".yaml"), true).isFile();
}
return true;
}
@@ -280,6 +219,11 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co
cookColMesh(cookedPath, path, ds, fast, btok, progress);
break;
}
case hecl::blender::BlendType::Armature: {
hecl::blender::DataStream ds = conn.beginData();
cookArmature(cookedPath, path, ds, fast, btok, progress);
break;
}
case hecl::blender::BlendType::PathMesh: {
hecl::blender::DataStream ds = conn.beginData();
cookPathMesh(cookedPath, path, ds, fast, btok, progress);
@@ -325,7 +269,7 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co
TXTR::Cook(path, cookedPath);
} else if (hecl::IsPathYAML(path)) {
athena::io::FileReader reader(path.getAbsolutePath());
cookYAML(cookedPath, path, reader, progress);
cookYAML(cookedPath, path, reader, btok, progress);
} else if (IsPathAudioGroup(path)) {
cookAudioGroup(cookedPath, path, progress);
} else if (IsPathSong(path)) {
@@ -348,6 +292,8 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
}
case hecl::blender::BlendType::Actor: {
hecl::ProjectPath asGlob = in.getWithExtension(_SYS_STR(".*"), true);
hecl::ProjectPath parentPath = asGlob.getParentPath();
hecl::DirectoryEnumerator dEnum(parentPath.getAbsolutePath());
hecl::blender::DataStream ds = conn.beginData();
hecl::blender::Actor actor = ds.compileActorCharacterOnly();
auto actNames = ds.getActionNames();
@@ -361,19 +307,20 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
}
hecl::SystemStringConv chSysName(sub.name);
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(chSysName.sys_str()) + _SYS_STR(".CSKR")));
pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.CSKR")), chSysName, sub.cskrId)));
const auto& arm = actor.armatures[sub.armature];
hecl::SystemStringConv armSysName(arm.name);
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(armSysName.sys_str()) + _SYS_STR(".CINF")));
if (hecl::IsPathBlend(arm.path))
pathsOut.push_back(arm.path);
for (const auto& overlay : sub.overlayMeshes) {
hecl::SystemStringConv ovelaySys(overlay.first);
if (hecl::IsPathBlend(overlay.second)) {
flattenDependenciesBlend(overlay.second, pathsOut, btok);
pathsOut.push_back(overlay.second);
hecl::SystemStringConv overlaySys(overlay.name);
if (hecl::IsPathBlend(overlay.mesh)) {
flattenDependenciesBlend(overlay.mesh, pathsOut, btok);
pathsOut.push_back(overlay.mesh);
}
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(chSysName.sys_str()) + _SYS_STR('.') +
ovelaySys.c_str() + _SYS_STR(".CSKR")));
pathsOut.push_back(asGlob.ensureAuxInfo(
fmt::format(fmt(_SYS_STR("{}.{}_{}.CSKR")), chSysName, overlaySys, overlay.cskrId)));
}
}
};
@@ -391,21 +338,29 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
hecl::SystemStringConv chSysName(att.name);
pathsOut.push_back(
asGlob.ensureAuxInfo(hecl::SystemString(_SYS_STR("ATTACH.")) + chSysName.c_str() + _SYS_STR(".CSKR")));
asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("ATTACH.{}_{}.CSKR")), chSysName, att.cskrId)));
if (att.armature >= 0) {
const auto& arm = actor.armatures[att.armature];
hecl::SystemStringConv armSysName(arm.name);
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(armSysName.sys_str()) + _SYS_STR(".CINF")));
if (hecl::IsPathBlend(arm.path))
pathsOut.push_back(arm.path);
}
}
for (const auto& act : actNames) {
hecl::SystemStringConv actSysName(act);
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(actSysName.sys_str()) + _SYS_STR(".ANIM")));
hecl::ProjectPath evntPath =
asGlob.ensureAuxInfo(hecl::SystemStringView{})
.getWithExtension(fmt::format(fmt(_SYS_STR(".{}.evnt.yaml")), actSysName).c_str(), true);
hecl::SystemStringConv actSysName(act.first);
hecl::SystemStringConv actAnimId(act.second);
pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.ANIM")), actSysName, actAnimId)));
hecl::SystemString searchPrefix(asGlob.getWithExtension(
fmt::format(fmt(_SYS_STR(".{}_")), actSysName).c_str(), true).getLastComponent());
hecl::ProjectPath evntPath;
for (const auto& ent : dEnum) {
if (hecl::StringUtils::BeginsWith(ent.m_name, searchPrefix.c_str()) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".evnt.yaml"))) {
evntPath = hecl::ProjectPath(parentPath, ent.m_name);
break;
}
}
if (evntPath.isFile())
pathsOut.push_back(evntPath);
}
@@ -518,19 +473,18 @@ void SpecBase::copyBuildListData(std::vector<std::tuple<size_t, size_t, bool>>&
hecl::SystemString str = fmt::format(fmt(_SYS_STR("Copying {}")), tag);
progress.print(str.c_str(), nullptr, ++loadIdx / float(buildList.size()));
fileIndex.emplace_back();
auto& thisIdx = fileIndex.back();
auto& [positionOut, sizeOut, compressedOut] = fileIndex.emplace_back();
if (tag.type == FOURCC('MLVL')) {
auto search = mlvlData.find(tag.id);
if (search == mlvlData.end())
Log.report(logvisor::Fatal, fmt(_SYS_STR("Unable to find MLVL {}")), tag.id);
std::get<0>(thisIdx) = pakOut.position();
std::get<1>(thisIdx) = ROUND_UP_32(search->second.size());
std::get<2>(thisIdx) = false;
positionOut = pakOut.position();
sizeOut = ROUND_UP_32(search->second.size());
compressedOut = false;
pakOut.writeUBytes(search->second.data(), search->second.size());
for (atUint64 i = search->second.size(); i < std::get<1>(thisIdx); ++i)
for (atUint64 i = search->second.size(); i < sizeOut; ++i)
pakOut.writeUByte(0xff);
continue;
@@ -545,25 +499,34 @@ void SpecBase::copyBuildListData(std::vector<std::tuple<size_t, size_t, bool>>&
auto data = r.readUBytes(size);
auto compData = compressPakData(tag, data.get(), size);
if (compData.first) {
std::get<0>(thisIdx) = pakOut.position();
std::get<1>(thisIdx) = ROUND_UP_32(compData.second + 4);
std::get<2>(thisIdx) = true;
positionOut = pakOut.position();
sizeOut = ROUND_UP_32(compData.second + 4);
compressedOut = true;
pakOut.writeUint32Big(atUint32(size));
pakOut.writeUBytes(compData.first.get(), compData.second);
for (atUint64 i = compData.second + 4; i < std::get<1>(thisIdx); ++i)
for (atUint64 i = compData.second + 4; i < sizeOut; ++i)
pakOut.writeUByte(0xff);
} else {
std::get<0>(thisIdx) = pakOut.position();
std::get<1>(thisIdx) = ROUND_UP_32(size);
std::get<2>(thisIdx) = false;
positionOut = pakOut.position();
sizeOut = ROUND_UP_32(size);
compressedOut = false;
pakOut.writeUBytes(data.get(), size);
for (atUint64 i = size; i < std::get<1>(thisIdx); ++i)
for (atUint64 i = size; i < sizeOut; ++i)
pakOut.writeUByte(0xff);
}
}
progress.startNewLine();
}
static bool IsWorldBlend(const hecl::ProjectPath& path) {
if (path.isFile()) {
auto lastComp = path.getLastComponent();
return hecl::StringUtils::BeginsWith(lastComp, _SYS_STR("!world_")) &&
hecl::StringUtils::EndsWith(lastComp, _SYS_STR(".blend"));
}
return false;
}
void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry, bool fast,
hecl::blender::Token& btok, const hecl::MultiProgressPrinter& progress,
hecl::ClientProcess* cp) {
@@ -590,8 +553,7 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
atUint64 resTableOffset = 0;
std::unordered_map<urde::CAssetId, std::vector<uint8_t>> mlvlData;
if (path.getPathType() == hecl::ProjectPath::Type::File &&
!hecl::StrCmp(path.getLastComponent().data(), _SYS_STR("!world.blend"))) /* World PAK */
if (IsWorldBlend(path)) /* World PAK */
{
/* Force-cook MLVL and write resource list structure */
m_project.cookPath(path, progress, false, true, fast, entry, cp);
@@ -700,6 +662,25 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
void SpecBase::interruptCook() { cancelBackgroundIndex(); }
std::optional<hecl::blender::World> SpecBase::compileWorldFromDir(const hecl::ProjectPath& dir,
hecl::blender::Token& btok) const {
hecl::ProjectPath asBlend;
for (const auto& ent : hecl::DirectoryEnumerator(dir.getAbsolutePath())) {
if (hecl::StringUtils::BeginsWith(ent.m_name, _SYS_STR("!world_"))) {
asBlend = hecl::ProjectPath(dir, ent.m_name).getWithExtension(_SYS_STR(".blend"), true);
break;
}
}
if (hecl::IsPathBlend(asBlend)) {
hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.openBlend(asBlend))
return {};
hecl::blender::DataStream ds = conn.beginData();
return {ds.compileWorld()};
}
return {};
}
hecl::ProjectPath SpecBase::getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const {
const hecl::Database::DataSpecEntry* spec = &getOriginalSpec();
if (pcTarget)
@@ -872,11 +853,12 @@ void SpecBase::enumerateNamedResources(
static void WriteTag(athena::io::YAMLDocWriter& cacheWriter, const urde::SObjectTag& pathTag,
const hecl::ProjectPath& path) {
if (auto v = cacheWriter.enterSubVector(fmt::format(fmt("{}"), pathTag.id).c_str())) {
cacheWriter.writeString(nullptr, pathTag.type.toString().c_str());
cacheWriter.writeString(nullptr, path.getAuxInfo().size() ? (std::string(path.getRelativePathUTF8()) + '|' +
path.getAuxInfoUTF8().data())
: path.getRelativePathUTF8());
auto key = fmt::format(fmt("{}"), pathTag.id);
if (auto* existing = cacheWriter.getCurNode()->findMapChild(key)) {
existing->m_seqChildren.emplace_back(athena::io::ValToNode(path.getEncodableStringUTF8()));
} else if (auto v = cacheWriter.enterSubVector(key)) {
cacheWriter.writeString(pathTag.type.toString());
cacheWriter.writeString(path.getEncodableStringUTF8());
}
}
@@ -947,7 +929,7 @@ void SpecBase::backgroundIndexRecursiveCatalogs(const hecl::ProjectPath& dir, at
continue;
/* Read catalog.yaml for .pak directory if exists */
if (level == 1 && !ent.m_name.compare(_SYS_STR("!catalog.yaml"))) {
if (level == 1 && ent.m_name == _SYS_STR("!catalog.yaml")) {
readCatalog(path, nameWriter);
continue;
}
@@ -959,11 +941,27 @@ void SpecBase::backgroundIndexRecursiveCatalogs(const hecl::ProjectPath& dir, at
}
}
#if DUMP_CACHE_FILL
static void DumpCacheAdd(const urde::SObjectTag& pathTag, const hecl::ProjectPath& path) {
fmt::print(stderr, fmt("{} {}\n"), pathTag, path.getRelativePathUTF8());
}
void SpecBase::insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const urde::SObjectTag& tag,
const hecl::ProjectPath& path, bool dump) {
#if 0
auto search = m_tagToPath.find(tag);
/* ANCS subresources are allowed to be weak-linked */
if (search != m_tagToPath.end() && search->second != path &&
tag.type != FOURCC('CINF') && tag.type != FOURCC('CSKR') &&
tag.type != FOURCC('ANIM') && tag.type != FOURCC('EVNT')) {
Log.report(logvisor::Fatal, fmt(_SYS_STR("'{}|{}' already exists for tag {} as '{}|{}'")),
path.getRelativePath(), path.getAuxInfo(), tag,
search->second.getRelativePath(), search->second.getAuxInfo());
}
#endif
m_tagToPath.insert(std::make_pair(tag, path));
m_pathToTag[path.hash()] = tag;
WriteTag(cacheWriter, tag, path);
#if DUMP_CACHE_FILL
if (dump)
fmt::print(stderr, fmt("{} {}\n"), tag, path.getRelativePathUTF8());
#endif
}
bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter) {
/* Avoid redundant filesystem access for re-caches */
@@ -988,109 +986,49 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
return false;
/* Transform tag to glob */
pathTag = {SBIG('ANCS'), asGlob.hash().val32()};
pathTag = {SBIG('ANCS'), asGlob.parsedHash32()};
useGlob = true;
hecl::blender::DataStream ds = conn.beginData();
std::vector<std::string> armatureNames = ds.getArmatureNames();
std::vector<std::string> subtypeNames = ds.getSubtypeNames();
std::vector<std::string> actionNames = ds.getActionNames();
std::vector<std::pair<std::string, std::string>> subtypeNames = ds.getSubtypeNames();
std::vector<std::pair<std::string, std::string>> actionNames = ds.getActionNames();
for (const std::string& arm : armatureNames) {
hecl::SystemStringConv sysStr(arm);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".CINF"));
urde::SObjectTag pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
}
for (const auto& sub : subtypeNames) {
hecl::SystemStringConv subName(sub.first);
hecl::SystemStringConv cskrId(sub.second);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.CSKR")), subName, cskrId));
insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
for (const std::string& sub : subtypeNames) {
hecl::SystemStringConv sysStr(sub);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".CSKR"));
urde::SObjectTag pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
std::vector<std::string> overlayNames = ds.getSubtypeOverlayNames(sub);
std::vector<std::pair<std::string, std::string>> overlayNames = ds.getSubtypeOverlayNames(sub.first);
for (const auto& overlay : overlayNames) {
hecl::SystemStringConv overlaySys(overlay);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR('.') +
overlaySys.c_str() + _SYS_STR(".CSKR"));
urde::SObjectTag pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
hecl::SystemStringConv overlaySys(overlay.first);
hecl::SystemStringConv overlayCskrId(overlay.second);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(
fmt::format(fmt(_SYS_STR("{}.{}_{}.CSKR")), subName, overlaySys, overlayCskrId));
insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
}
}
std::vector<std::string> attachmentNames = ds.getAttachmentNames();
std::vector<std::pair<std::string, std::string>> attachmentNames = ds.getAttachmentNames();
for (const auto& attachment : attachmentNames) {
hecl::SystemStringConv attachmentSys(attachment);
hecl::SystemStringConv attachmentSys(attachment.first);
hecl::SystemStringConv attachmentCskrId(attachment.second);
hecl::ProjectPath subPath =
asGlob.ensureAuxInfo(hecl::SystemString(_SYS_STR("ATTACH.")) + attachmentSys.c_str() + _SYS_STR(".CSKR"));
urde::SObjectTag pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("ATTACH.{}_{}.CSKR")), attachmentSys, attachmentCskrId));
insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
}
for (const std::string& act : actionNames) {
hecl::SystemStringConv sysStr(act);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".ANIM"));
urde::SObjectTag pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
for (const auto& act : actionNames) {
hecl::SystemStringConv sysStr(act.first);
hecl::SystemStringConv animId(act.second);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.ANIM")), sysStr, animId));
insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
}
} else if (pathTag.type == SBIG('MLVL')) {
/* Transform tag to glob */
pathTag = {SBIG('MLVL'), asGlob.hash().val32()};
useGlob = true;
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(_SYS_STR("MAPW"));
urde::SObjectTag pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
subPath = asGlob.ensureAuxInfo(_SYS_STR("SAVW"));
pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
}
/* Cache in-memory */
const hecl::ProjectPath& usePath = useGlob ? asGlob : path;
m_tagToPath[pathTag] = usePath;
m_pathToTag[usePath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, usePath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, usePath);
#endif
insertPathTag(cacheWriter, pathTag, usePath);
}
return true;
@@ -1111,10 +1049,11 @@ void SpecBase::backgroundIndexRecursiveProc(const hecl::ProjectPath& dir, athena
if (ent.m_isDir) {
/* Index AGSC here */
if (hecl::ProjectPath(path, "!project.yaml").isFile() && hecl::ProjectPath(path, "!pool.yaml").isFile()) {
urde::SObjectTag pathTag(SBIG('AGSC'), path.hash().val32());
m_tagToPath[pathTag] = path;
m_pathToTag[path.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, path);
/* Avoid redundant filesystem access for re-caches */
if (m_pathToTag.find(path.hash()) == m_pathToTag.cend()) {
urde::SObjectTag pathTag(SBIG('AGSC'), path.parsedHash32());
insertPathTag(cacheWriter, pathTag, path);
}
} else {
backgroundIndexRecursiveProc(path, cacheWriter, nameWriter, level + 1);
}
@@ -1123,7 +1062,7 @@ void SpecBase::backgroundIndexRecursiveProc(const hecl::ProjectPath& dir, athena
continue;
/* Read catalog.yaml for .pak directory if exists */
if (level == 1 && !ent.m_name.compare(_SYS_STR("!catalog.yaml"))) {
if (level == 1 && ent.m_name == _SYS_STR("!catalog.yaml")) {
readCatalog(path, nameWriter);
continue;
}
@@ -1142,8 +1081,8 @@ void SpecBase::backgroundIndexProc() {
hecl::ProjectPath specRoot(m_project.getProjectWorkingPath(), getOriginalSpec().m_name);
/* Cache will be overwritten with validated entries afterwards */
athena::io::YAMLDocWriter cacheWriter(nullptr);
athena::io::YAMLDocWriter nameWriter(nullptr);
athena::io::YAMLDocWriter cacheWriter;
athena::io::YAMLDocWriter nameWriter;
/* Read in tag cache */
if (tagCachePath.isFile()) {
@@ -1162,15 +1101,15 @@ void SpecBase::backgroundIndexProc() {
return;
const athena::io::YAMLNode& node = *child.second;
unsigned long id = strtoul(child.first.c_str(), nullptr, 16);
hecl::FourCC type(node.m_seqChildren.at(0)->m_scalarString.c_str());
hecl::ProjectPath path(m_project.getProjectWorkingPath(), node.m_seqChildren.at(1)->m_scalarString);
if (path.isFileOrGlob()) {
if (node.m_seqChildren.size() >= 2) {
unsigned long id = strtoul(child.first.c_str(), nullptr, 16);
hecl::FourCC type(node.m_seqChildren[0]->m_scalarString.c_str());
urde::SObjectTag pathTag(type, id);
m_tagToPath[pathTag] = path;
m_pathToTag[path.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, path);
for (auto I = node.m_seqChildren.begin() + 1, E = node.m_seqChildren.end(); I != E; ++I) {
hecl::ProjectPath path(m_project.getProjectWorkingPath(), (*I)->m_scalarString);
if (!path.isNone())
insertPathTag(cacheWriter, pathTag, path, false);
}
}
++loadIdx;
@@ -1209,14 +1148,6 @@ void SpecBase::backgroundIndexProc() {
}
}
/* Add special original IDs resource if exists (not name-cached to disk) */
hecl::ProjectPath oidsPath(specRoot, "!original_ids.yaml");
urde::SObjectTag oidsTag = buildTagFromPath(oidsPath);
if (oidsTag) {
m_catalogNameToTag["mp1originalids"] = oidsTag;
m_catalogTagToNames[oidsTag].insert("MP1OriginalIDs");
}
Log.report(logvisor::Info, fmt(_SYS_STR("Background index of '{}' started")), getOriginalSpec().m_name);
backgroundIndexRecursiveProc(specRoot, cacheWriter, nameWriter, 0);