diff --git a/DataSpec/DNACommon/PAK.cpp b/DataSpec/DNACommon/PAK.cpp index c35922bef..3a9048439 100644 --- a/DataSpec/DNACommon/PAK.cpp +++ b/DataSpec/DNACommon/PAK.cpp @@ -211,7 +211,8 @@ void PAKRouter::build(std::vector& bridges, std::functio } /* Write catalog */ - const hecl::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].first; + intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); + const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; hecl::SystemString catalogPath = hecl::ProjectPath(pakPath, "catalog.yaml").getAbsolutePath(); FILE* catalog = hecl::Fopen(catalogPath.c_str(), _S("w")); yaml_emitter_set_output_file(catalogWriter.getEmitter(), catalog); @@ -232,9 +233,9 @@ void PAKRouter::enterPAKBridge(const BRIDGETYPE& pakBridge) { pit->first.makeDir(); pit->second.makeDir(); - m_pak = &pakBridge.getPAK(); - m_node = &pakBridge.getNode(); - m_curBridgeIdx = bridgeIdx; + m_pak.reset(&pakBridge.getPAK()); + m_node.reset(&pakBridge.getNode()); + m_curBridgeIdx.reset(reinterpret_cast(bridgeIdx)); return; } ++pit; @@ -250,15 +251,17 @@ hecl::ProjectPath PAKRouter::getWorking(const EntryType* entry, { if (!entry) return hecl::ProjectPath(); - if (!m_pak) + const PAKType* pak = m_pak.get(); + intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); + if (!pak) LogDNACommon.report(logvisor::Fatal, "PAKRouter::enterPAKBridge() must be called before PAKRouter::getWorkingPath()"); - if (m_pak->m_noShare) + if (pak->m_noShare) { - const EntryType* singleSearch = m_pak->lookupEntry(entry->id); + const EntryType* singleSearch = pak->lookupEntry(entry->id); if (singleSearch) { - const hecl::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].first; + const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; pakPath.makeDir(); #if HECL_UCS2 hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry)); @@ -334,15 +337,17 @@ hecl::ProjectPath PAKRouter::getCooked(const EntryType* entry) const { if (!entry) return hecl::ProjectPath(); - if (!m_pak) + const PAKType* pak = m_pak.get(); + intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); + if (!pak) LogDNACommon.report(logvisor::Fatal, "PAKRouter::enterPAKBridge() must be called before PAKRouter::getCookedPath()"); - if (m_pak->m_noShare) + if (pak->m_noShare) { - const EntryType* singleSearch = m_pak->lookupEntry(entry->id); + const EntryType* singleSearch = pak->lookupEntry(entry->id); if (singleSearch) { - const hecl::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].second; + const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].second; pakPath.makeDir(); return hecl::ProjectPath(pakPath, getBestEntryName(*entry)); } @@ -382,7 +387,8 @@ hecl::ProjectPath PAKRouter::getCooked(const IDType& id) const template hecl::SystemString PAKRouter::getResourceRelativePath(const EntryType& a, const IDType& b) const { - if (!m_pak) + const PAKType* pak = m_pak.get(); + if (!pak) LogDNACommon.report(logvisor::Fatal, "PAKRouter::enterPAKBridge() must be called before PAKRouter::getResourceRelativePath()"); const typename BRIDGETYPE::PAKType::Entry* be = lookupEntry(b); @@ -431,7 +437,8 @@ std::string PAKRouter::getBestEntryName(const IDType& entry) const } template -bool PAKRouter::extractResources(const BRIDGETYPE& pakBridge, bool force, +bool PAKRouter::extractResources(const BRIDGETYPE& pakBridge, bool force, bool precedenceSharesOnly, + hecl::BlenderToken& btok, std::function progress) { enterPAKBridge(pakBridge); @@ -446,16 +453,28 @@ bool PAKRouter::extractResources(const BRIDGETYPE& pakBridge, bool f if (extractor.weight != w) continue; + if (precedenceSharesOnly) + { + auto sharedSearch = m_sharedEntries.find(item->id); + if (sharedSearch != m_sharedEntries.cend()) + { + if (sharedSearch->second.first != reinterpret_cast(m_curBridgeIdx.get())) + continue; + } + } + std::string bestName = getBestEntryName(*item); hecl::SystemStringView bestNameView(bestName); float thisFac = ++count / fsz; progress(bestNameView.sys_str().c_str(), thisFac); + const nod::Node* node = m_node.get(); + /* Extract first, so they start out invalid */ hecl::ProjectPath cooked = getCooked(item); if (force || cooked.getPathType() == hecl::ProjectPath::Type::None) { - PAKEntryReadStream s = item->beginReadStream(*m_node); + PAKEntryReadStream s = item->beginReadStream(*node); FILE* fout = hecl::Fopen(cooked.getAbsolutePath().c_str(), _S("wb")); fwrite(s.data(), 1, s.length(), fout); fclose(fout); @@ -466,7 +485,7 @@ bool PAKRouter::extractResources(const BRIDGETYPE& pakBridge, bool f { if (force || working.getPathType() == hecl::ProjectPath::Type::None) { - PAKEntryReadStream s = item->beginReadStream(*m_node); + PAKEntryReadStream s = item->beginReadStream(*node); extractor.func_a(s, working); } } @@ -474,8 +493,8 @@ bool PAKRouter::extractResources(const BRIDGETYPE& pakBridge, bool f { if (force || working.getPathType() == hecl::ProjectPath::Type::None) { - PAKEntryReadStream s = item->beginReadStream(*m_node); - extractor.func_b(m_dataSpec, s, working, *this, *item, force, + PAKEntryReadStream s = item->beginReadStream(*node); + extractor.func_b(m_dataSpec, s, working, *this, *item, force, btok, [&progress, thisFac](const hecl::SystemChar* update) { progress(update, thisFac); @@ -501,13 +520,15 @@ const typename BRIDGETYPE::PAKType::Entry* PAKRouter::lookupEntry(co LogDNACommon.report(logvisor::Fatal, "PAKRouter::build() must be called before PAKRouter::lookupEntry()"); - if (m_pak) + const PAKType* pak = m_pak.get(); + const nod::Node* node = m_node.get(); + if (pak) { - const EntryType* ent = m_pak->lookupEntry(entry); + const EntryType* ent = pak->lookupEntry(entry); if (ent) { if (nodeOut) - *nodeOut = m_node; + *nodeOut = node; return ent; } } diff --git a/DataSpec/DNACommon/PAK.hpp b/DataSpec/DNACommon/PAK.hpp index 8f342eb0a..a251cc39f 100644 --- a/DataSpec/DNACommon/PAK.hpp +++ b/DataSpec/DNACommon/PAK.hpp @@ -2,6 +2,7 @@ #define __DNACOMMON_PAK_HPP__ #include "DNACommon.hpp" +#include "boo/ThreadLocalPtr.hpp" namespace DataSpec { @@ -81,7 +82,7 @@ struct ResExtractor { std::function func_a; std::function&, - const typename PAKBRIDGE::PAKType::Entry&, bool, + const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::BlenderToken&, std::function)> func_b; const hecl::SystemChar* fileExts[4]; unsigned weight; @@ -121,13 +122,13 @@ public: private: const std::vector* m_bridges = nullptr; std::vector> m_bridgePaths; - size_t m_curBridgeIdx = 0; + ThreadLocalPtr m_curBridgeIdx; const hecl::ProjectPath& m_gameWorking; const hecl::ProjectPath& m_gameCooked; hecl::ProjectPath m_sharedWorking; hecl::ProjectPath m_sharedCooked; - const PAKType* m_pak = nullptr; - const nod::Node* m_node = nullptr; + ThreadLocalPtr m_pak; + ThreadLocalPtr m_node; std::unordered_map> m_uniqueEntries; std::unordered_map> m_sharedEntries; std::unordered_map m_cmdlRigs; @@ -147,14 +148,19 @@ public: hecl::ProjectPath getWorking(const IDType& id) const; hecl::ProjectPath getCooked(const EntryType* entry) const; hecl::ProjectPath getCooked(const IDType& id) const; - bool isShared() { return m_pak ? !m_pak->m_noShare : false; } + bool isShared() + { + const PAKType* pak = m_pak.get(); + return pak ? !pak->m_noShare : false; + } hecl::SystemString getResourceRelativePath(const EntryType& a, const IDType& b) const; std::string getBestEntryName(const EntryType& entry) const; std::string getBestEntryName(const IDType& entry) const; - bool extractResources(const BRIDGETYPE& pakBridge, bool force, + bool extractResources(const BRIDGETYPE& pakBridge, bool force, bool precedenceSharesOnly, + hecl::BlenderToken& btok, std::function progress); const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry, diff --git a/DataSpec/DNAMP1/ANCS.hpp b/DataSpec/DNAMP1/ANCS.hpp index 0d5aff532..51d3f80d4 100644 --- a/DataSpec/DNAMP1/ANCS.hpp +++ b/DataSpec/DNAMP1/ANCS.hpp @@ -394,6 +394,7 @@ struct ANCS : BigYAML PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml")); @@ -417,7 +418,7 @@ struct ANCS : BigYAML if (force || blendType == hecl::ProjectPath::Type::None) { - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); DNAANCS::ReadANCSToBlender, ANCS, MaterialSet, DNACMDL::SurfaceHeader_1, 2> (conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); } diff --git a/DataSpec/DNAMP1/CMDL.hpp b/DataSpec/DNAMP1/CMDL.hpp index fcee64a17..1d774a1a2 100644 --- a/DataSpec/DNAMP1/CMDL.hpp +++ b/DataSpec/DNAMP1/CMDL.hpp @@ -23,6 +23,7 @@ struct CMDL PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { /* Check for RigPair */ @@ -39,7 +40,7 @@ struct CMDL } /* Do extract */ - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh)) return false; DNACMDL::ReadCMDLToBlender, MaterialSet, std::pair, DNACMDL::SurfaceHeader_1, 2> diff --git a/DataSpec/DNAMP1/FRME.cpp b/DataSpec/DNAMP1/FRME.cpp index 3783784fe..912c03703 100644 --- a/DataSpec/DNAMP1/FRME.cpp +++ b/DataSpec/DNAMP1/FRME.cpp @@ -311,12 +311,19 @@ size_t FRME::Widget::TXPNInfo::binarySize(size_t __isz) const return __isz + (version == 1 ? 78 : 66); } -bool FRME::Extract(const SpecBase &dataSpec, PAKEntryReadStream &rs, const hecl::ProjectPath &outPath, PAKRouter &pakRouter, const PAK::Entry &entry, bool force, std::function fileChanged) +bool FRME::Extract(const SpecBase &dataSpec, + PAKEntryReadStream &rs, + const hecl::ProjectPath &outPath, + PAKRouter &pakRouter, + const PAK::Entry &entry, + bool force, + hecl::BlenderToken& btok, + std::function fileChanged) { FRME frme; frme.read(rs); - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); #if 0 if (!force && outPath.getPathType() == hecl::ProjectPath::Type::File) diff --git a/DataSpec/DNAMP1/FRME.hpp b/DataSpec/DNAMP1/FRME.hpp index 0d9d3fd0b..3d7daca38 100644 --- a/DataSpec/DNAMP1/FRME.hpp +++ b/DataSpec/DNAMP1/FRME.hpp @@ -262,6 +262,7 @@ struct FRME : BigDNA PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged); }; diff --git a/DataSpec/DNAMP1/MAPA.hpp b/DataSpec/DNAMP1/MAPA.hpp index 406458203..7128ac644 100644 --- a/DataSpec/DNAMP1/MAPA.hpp +++ b/DataSpec/DNAMP1/MAPA.hpp @@ -20,11 +20,12 @@ struct MAPA : DNAMAPA::MAPA PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { MAPA mapa; mapa.read(rs); - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); } }; diff --git a/DataSpec/DNAMP1/MLVL.hpp b/DataSpec/DNAMP1/MLVL.hpp index 8beb7fbe1..de221aafd 100644 --- a/DataSpec/DNAMP1/MLVL.hpp +++ b/DataSpec/DNAMP1/MLVL.hpp @@ -112,6 +112,7 @@ struct MLVL : BigYAML PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { MLVL mlvl; @@ -119,7 +120,7 @@ struct MLVL : BigYAML FILE* fp = hecl::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("w")); mlvl.toYAMLFile(fp); fclose(fp); - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); } diff --git a/DataSpec/DNAMP1/MREA.cpp b/DataSpec/DNAMP1/MREA.cpp index fd4eee563..a5a77dffd 100644 --- a/DataSpec/DNAMP1/MREA.cpp +++ b/DataSpec/DNAMP1/MREA.cpp @@ -57,6 +57,7 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function) { using RigPair = std::pair; @@ -78,7 +79,7 @@ bool MREA::Extract(const SpecBase& dataSpec, head.read(rs); rs.seekAlign32(); - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); if (!conn.createBlend(mreaPath, hecl::BlenderConnection::BlendType::Area)) return false; diff --git a/DataSpec/DNAMP1/MREA.hpp b/DataSpec/DNAMP1/MREA.hpp index 584c66805..09c188f8b 100644 --- a/DataSpec/DNAMP1/MREA.hpp +++ b/DataSpec/DNAMP1/MREA.hpp @@ -113,6 +113,7 @@ struct MREA PAKRouter& pakRouter, const PAK::Entry& entry, bool, + hecl::BlenderToken& btok, std::function); static void Name(const SpecBase& dataSpec, diff --git a/DataSpec/DNAMP2/ANCS.hpp b/DataSpec/DNAMP2/ANCS.hpp index dc95d7ee6..e5c6c8d24 100644 --- a/DataSpec/DNAMP2/ANCS.hpp +++ b/DataSpec/DNAMP2/ANCS.hpp @@ -217,6 +217,7 @@ struct ANCS : BigYAML PAKRouter& pakRouter, const DNAMP1::PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml")); @@ -240,7 +241,7 @@ struct ANCS : BigYAML if (force || blendType == hecl::ProjectPath::Type::None) { - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); DNAANCS::ReadANCSToBlender, ANCS, MaterialSet, DNACMDL::SurfaceHeader_2, 4> (conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); } diff --git a/DataSpec/DNAMP2/CMDL.hpp b/DataSpec/DNAMP2/CMDL.hpp index 00aff3812..71f101f6a 100644 --- a/DataSpec/DNAMP2/CMDL.hpp +++ b/DataSpec/DNAMP2/CMDL.hpp @@ -21,6 +21,7 @@ struct CMDL PAKRouter& pakRouter, const DNAMP1::PAK::Entry& entry, bool, + hecl::BlenderToken& btok, std::function) { /* Check for RigPair */ @@ -37,7 +38,7 @@ struct CMDL } /* Do extract */ - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh)) return false; DNACMDL::ReadCMDLToBlender, MaterialSet, std::pair, DNACMDL::SurfaceHeader_2, 4> diff --git a/DataSpec/DNAMP2/MAPA.hpp b/DataSpec/DNAMP2/MAPA.hpp index 671dd2533..b3353d9d3 100644 --- a/DataSpec/DNAMP2/MAPA.hpp +++ b/DataSpec/DNAMP2/MAPA.hpp @@ -17,11 +17,12 @@ struct MAPA : DNAMAPA::MAPA PAKRouter& pakRouter, const DNAMP1::PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { MAPA mapa; mapa.read(rs); - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); } }; diff --git a/DataSpec/DNAMP2/MLVL.hpp b/DataSpec/DNAMP2/MLVL.hpp index 49785beaf..69a0bd219 100644 --- a/DataSpec/DNAMP2/MLVL.hpp +++ b/DataSpec/DNAMP2/MLVL.hpp @@ -100,6 +100,7 @@ struct MLVL : BigYAML PAKRouter& pakRouter, const DNAMP1::PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { MLVL mlvl; @@ -107,7 +108,7 @@ struct MLVL : BigYAML FILE* fp = hecl::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("wb")); mlvl.toYAMLFile(fp); fclose(fp); - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); } diff --git a/DataSpec/DNAMP2/MREA.cpp b/DataSpec/DNAMP2/MREA.cpp index ec0bf41d0..dca1606e1 100644 --- a/DataSpec/DNAMP2/MREA.cpp +++ b/DataSpec/DNAMP2/MREA.cpp @@ -163,6 +163,7 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKRouter& pakRouter, const DNAMP1::PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function) { using RigPair = std::pair; @@ -197,7 +198,7 @@ bool MREA::Extract(const SpecBase& dataSpec, drs.seek(0, athena::Begin); /* Start up blender connection */ - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); if (!conn.createBlend(mreaPath, hecl::BlenderConnection::BlendType::Area)) return false; diff --git a/DataSpec/DNAMP2/MREA.hpp b/DataSpec/DNAMP2/MREA.hpp index 545483c59..bb9e9bf58 100644 --- a/DataSpec/DNAMP2/MREA.hpp +++ b/DataSpec/DNAMP2/MREA.hpp @@ -123,6 +123,7 @@ struct MREA PAKRouter& pakRouter, const DNAMP1::PAK::Entry& entry, bool, + hecl::BlenderToken& btok, std::function); }; diff --git a/DataSpec/DNAMP3/CHAR.hpp b/DataSpec/DNAMP3/CHAR.hpp index f443f1d36..060255cc5 100644 --- a/DataSpec/DNAMP3/CHAR.hpp +++ b/DataSpec/DNAMP3/CHAR.hpp @@ -312,6 +312,7 @@ struct CHAR : BigYAML PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml")); @@ -335,7 +336,7 @@ struct CHAR : BigYAML if (force || blendType == hecl::ProjectPath::Type::None) { - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); DNAANCS::ReadANCSToBlender, CHAR, MaterialSet, DNACMDL::SurfaceHeader_3, 4> (conn, aChar, blendPath, pakRouter, entry, dataSpec, fileChanged, force); } diff --git a/DataSpec/DNAMP3/CMDL.hpp b/DataSpec/DNAMP3/CMDL.hpp index c2126dc41..a902a85fe 100644 --- a/DataSpec/DNAMP3/CMDL.hpp +++ b/DataSpec/DNAMP3/CMDL.hpp @@ -21,6 +21,7 @@ struct CMDL PAKRouter& pakRouter, const PAK::Entry& entry, bool, + hecl::BlenderToken& btok, std::function) { /* Check for RigPair */ @@ -37,7 +38,7 @@ struct CMDL } /* Do extract */ - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh)) return false; DNACMDL::ReadCMDLToBlender, MaterialSet, std::pair, DNACMDL::SurfaceHeader_3, 5> diff --git a/DataSpec/DNAMP3/MAPA.hpp b/DataSpec/DNAMP3/MAPA.hpp index 787ea361c..12d657ad6 100644 --- a/DataSpec/DNAMP3/MAPA.hpp +++ b/DataSpec/DNAMP3/MAPA.hpp @@ -17,11 +17,12 @@ struct MAPA : DNAMAPA::MAPA PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { MAPA mapa; mapa.read(rs); - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); } }; diff --git a/DataSpec/DNAMP3/MLVL.hpp b/DataSpec/DNAMP3/MLVL.hpp index 8a9b77a18..d7cb0923b 100644 --- a/DataSpec/DNAMP3/MLVL.hpp +++ b/DataSpec/DNAMP3/MLVL.hpp @@ -89,6 +89,7 @@ struct MLVL : BigYAML PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function fileChanged) { MLVL mlvl; @@ -96,7 +97,7 @@ struct MLVL : BigYAML FILE* fp = hecl::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("wb")); mlvl.toYAMLFile(fp); fclose(fp); - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); } diff --git a/DataSpec/DNAMP3/MREA.cpp b/DataSpec/DNAMP3/MREA.cpp index a628b2ca4..62e4d3542 100644 --- a/DataSpec/DNAMP3/MREA.cpp +++ b/DataSpec/DNAMP3/MREA.cpp @@ -72,6 +72,7 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKRouter& pakRouter, const PAK::Entry& entry, bool force, + hecl::BlenderToken& btok, std::function) { using RigPair = std::pair; @@ -109,7 +110,7 @@ bool MREA::Extract(const SpecBase& dataSpec, /* Start up blender connection */ - hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); if (!conn.createBlend(mreaPath, hecl::BlenderConnection::BlendType::Area)) return false; diff --git a/DataSpec/DNAMP3/MREA.hpp b/DataSpec/DNAMP3/MREA.hpp index 42e36406f..559165a3c 100644 --- a/DataSpec/DNAMP3/MREA.hpp +++ b/DataSpec/DNAMP3/MREA.hpp @@ -120,6 +120,7 @@ struct MREA PAKRouter& pakRouter, const PAK::Entry& entry, bool, + hecl::BlenderToken& btok, std::function); static bool ExtractLayerDeps(PAKEntryReadStream& rs, PAKBridge::Level::Area& areaOut); diff --git a/DataSpec/SpecMP1.cpp b/DataSpec/SpecMP1.cpp index 4667dab43..24ba97aed 100644 --- a/DataSpec/SpecMP1.cpp +++ b/DataSpec/SpecMP1.cpp @@ -16,6 +16,8 @@ #include "DNACommon/CRSC.hpp" #include "DNACommon/DPSC.hpp" +#include "hecl/ClientProcess.hpp" + namespace DataSpec { @@ -252,6 +254,8 @@ struct SpecMP1 : SpecBase } progress(_S("MP1 Root"), _S(""), 3, 1.0); + std::mutex msgLock; + hecl::ClientProcess process; int compIdx = 4; prog = 0; for (std::pair pair : m_orderedPaks) @@ -263,13 +267,20 @@ struct SpecMP1 : SpecBase const std::string& name = pak.getName(); hecl::SystemStringView sysName(name); - progress(sysName.sys_str().c_str(), _S(""), compIdx, 0.0); - m_pakRouter.extractResources(pak, force, - [&progress, &sysName, &compIdx](const hecl::SystemChar* substr, float factor) { - progress(sysName.sys_str().c_str(), substr, compIdx, factor); + std::unique_lock lk(msgLock); + progress(sysName.sys_str().c_str(), _S(""), compIdx, 0.0); + } + hecl::SystemString pakName = sysName.sys_str(); + process.addLambdaTransaction([&, pakName](hecl::BlenderToken& btok) + { + m_pakRouter.extractResources(pak, force, true, btok, + [&](const hecl::SystemChar* substr, float factor) + { + std::unique_lock lk(msgLock); + progress(pakName.c_str(), substr, compIdx, factor); + }); }); - progress(sysName.sys_str().c_str(), _S(""), compIdx++, 1.0); } return true; diff --git a/DataSpec/SpecMP2.cpp b/DataSpec/SpecMP2.cpp index 9b3836ff5..8226c40e2 100644 --- a/DataSpec/SpecMP2.cpp +++ b/DataSpec/SpecMP2.cpp @@ -6,6 +6,8 @@ #include "DNAMP2/MLVL.hpp" #include "DNAMP2/STRG.hpp" +#include "hecl/ClientProcess.hpp" + namespace DataSpec { @@ -234,6 +236,8 @@ struct SpecMP2 : SpecBase } progress(_S("MP2 Root"), _S(""), 3, 1.0); + std::mutex msgLock; + hecl::ClientProcess process; int compIdx = 4; prog = 0; for (std::pair pair : m_orderedPaks) @@ -245,13 +249,20 @@ struct SpecMP2 : SpecBase const std::string& name = pak.getName(); hecl::SystemStringView sysName(name); - progress(sysName.sys_str().c_str(), _S(""), compIdx, 0.0); - m_pakRouter.extractResources(pak, force, - [&progress, &sysName, &compIdx](const hecl::SystemChar* substr, float factor) { - progress(sysName.sys_str().c_str(), substr, compIdx, factor); + std::unique_lock lk(msgLock); + progress(sysName.sys_str().c_str(), _S(""), compIdx, 0.0); + } + hecl::SystemString pakName = sysName.sys_str(); + process.addLambdaTransaction([&, pakName](hecl::BlenderToken& btok) + { + m_pakRouter.extractResources(pak, force, true, btok, + [&](const hecl::SystemChar* substr, float factor) + { + std::unique_lock lk(msgLock); + progress(pakName.c_str(), substr, compIdx, factor); + }); }); - progress(sysName.sys_str().c_str(), _S(""), compIdx++, 1.0); } return true; diff --git a/DataSpec/SpecMP3.cpp b/DataSpec/SpecMP3.cpp index c2c5b4a48..c08f4043f 100644 --- a/DataSpec/SpecMP3.cpp +++ b/DataSpec/SpecMP3.cpp @@ -8,6 +8,8 @@ #include "DNAMP3/STRG.hpp" #include "DNAMP2/STRG.hpp" +#include "hecl/ClientProcess.hpp" + namespace DataSpec { @@ -366,6 +368,8 @@ struct SpecMP3 : SpecBase progress(currentTarget.c_str(), _S(""), compIdx++, 1.0); + std::mutex msgLock; + hecl::ClientProcess process; prog = 0; for (std::pair pair : m_orderedPaks) { @@ -376,13 +380,20 @@ struct SpecMP3 : SpecBase const std::string& name = pak.getName(); hecl::SystemStringView sysName(name); - progress(sysName.sys_str().c_str(), _S(""), compIdx, 0.0); - m_pakRouter.extractResources(pak, force, - [&progress, &sysName, &compIdx](const hecl::SystemChar* substr, float factor) { - progress(sysName.sys_str().c_str(), substr, compIdx, factor); + std::unique_lock lk(msgLock); + progress(sysName.sys_str().c_str(), _S(""), compIdx, 0.0); + } + hecl::SystemString pakName = sysName.sys_str(); + process.addLambdaTransaction([&, pakName](hecl::BlenderToken& btok) + { + m_pakRouter.extractResources(pak, force, true, btok, + [&](const hecl::SystemChar* substr, float factor) + { + std::unique_lock lk(msgLock); + progress(pakName.c_str(), substr, compIdx, factor); + }); }); - progress(sysName.sys_str().c_str(), _S(""), compIdx++, 1.0); } } @@ -417,6 +428,8 @@ struct SpecMP3 : SpecBase } progress(currentTarget.c_str(), _S(""), compIdx++, 1.0); + std::mutex msgLock; + hecl::ClientProcess process; prog = 0; for (std::pair pair : m_feOrderedPaks) { @@ -427,13 +440,20 @@ struct SpecMP3 : SpecBase const std::string& name = pak.getName(); hecl::SystemStringView sysName(name); - progress(sysName.sys_str().c_str(), _S(""), compIdx, 0.0); - m_fePakRouter.extractResources(pak, force, - [&progress, &sysName, &compIdx](const hecl::SystemChar* substr, float factor) { - progress(sysName.sys_str().c_str(), substr, compIdx, factor); + std::unique_lock lk(msgLock); + progress(sysName.sys_str().c_str(), _S(""), compIdx, 0.0); + } + hecl::SystemString pakName = sysName.sys_str(); + process.addLambdaTransaction([&, pakName](hecl::BlenderToken& btok) + { + m_fePakRouter.extractResources(pak, force, true, btok, + [&](const hecl::SystemChar* substr, float factor) + { + std::unique_lock lk(msgLock); + progress(pakName.c_str(), substr, compIdx, factor); + }); }); - progress(sysName.sys_str().c_str(), _S(""), compIdx++, 1.0); } } return true; diff --git a/Runtime/CToken.hpp b/Runtime/CToken.hpp index 4dc064e5d..0fc6c62d9 100644 --- a/Runtime/CToken.hpp +++ b/Runtime/CToken.hpp @@ -308,10 +308,8 @@ class TLockedToken : public TCachedToken { public: TLockedToken() = default; - TLockedToken(const CToken& other) : TCachedToken(other) - {TCachedToken::m_obj = TToken::GetObj();} - TLockedToken(CToken&& other) : TCachedToken(std::move(other)) - {TCachedToken::m_obj = TToken::GetObj();} + TLockedToken(const CToken& other) : TCachedToken(other) {CToken::Lock();} + TLockedToken(CToken&& other) : TCachedToken(std::move(other)) {CToken::Lock();} }; } diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index cd4cc061d..4ecb46258 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -170,7 +170,6 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(const UVAnimation& anim) { case UVAnimation::Mode::MvInvNoTranslation: { - matrixOut = CGraphics::g_ViewMatrix.inverse().multiplyIgnoreTranslation( CGraphics::g_GXModelMatrix).toMatrix4f(); matrixOut.vec[3].zeroOut(); diff --git a/hecl b/hecl index 51349be32..26f586dbc 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 51349be32ab052618e02a82a8e21b495b5b00432 +Subproject commit 26f586dbc2a7a614abe0fb5b86bb2bc32c43b5f9