Thread-safe extraction

This commit is contained in:
Jack Andersen 2016-03-31 18:25:00 -10:00
parent 9fcce94a7a
commit 8fc0d57500
28 changed files with 162 additions and 70 deletions

View File

@ -211,7 +211,8 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
} }
/* Write catalog */ /* Write catalog */
const hecl::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].first; intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get());
const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first;
hecl::SystemString catalogPath = hecl::ProjectPath(pakPath, "catalog.yaml").getAbsolutePath(); hecl::SystemString catalogPath = hecl::ProjectPath(pakPath, "catalog.yaml").getAbsolutePath();
FILE* catalog = hecl::Fopen(catalogPath.c_str(), _S("w")); FILE* catalog = hecl::Fopen(catalogPath.c_str(), _S("w"));
yaml_emitter_set_output_file(catalogWriter.getEmitter(), catalog); yaml_emitter_set_output_file(catalogWriter.getEmitter(), catalog);
@ -232,9 +233,9 @@ void PAKRouter<BRIDGETYPE>::enterPAKBridge(const BRIDGETYPE& pakBridge)
{ {
pit->first.makeDir(); pit->first.makeDir();
pit->second.makeDir(); pit->second.makeDir();
m_pak = &pakBridge.getPAK(); m_pak.reset(&pakBridge.getPAK());
m_node = &pakBridge.getNode(); m_node.reset(&pakBridge.getNode());
m_curBridgeIdx = bridgeIdx; m_curBridgeIdx.reset(reinterpret_cast<void*>(bridgeIdx));
return; return;
} }
++pit; ++pit;
@ -250,15 +251,17 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
{ {
if (!entry) if (!entry)
return hecl::ProjectPath(); return hecl::ProjectPath();
if (!m_pak) const PAKType* pak = m_pak.get();
intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get());
if (!pak)
LogDNACommon.report(logvisor::Fatal, LogDNACommon.report(logvisor::Fatal,
"PAKRouter::enterPAKBridge() must be called before PAKRouter::getWorkingPath()"); "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) if (singleSearch)
{ {
const hecl::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].first; const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first;
pakPath.makeDir(); pakPath.makeDir();
#if HECL_UCS2 #if HECL_UCS2
hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry)); hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry));
@ -334,15 +337,17 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const
{ {
if (!entry) if (!entry)
return hecl::ProjectPath(); return hecl::ProjectPath();
if (!m_pak) const PAKType* pak = m_pak.get();
intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get());
if (!pak)
LogDNACommon.report(logvisor::Fatal, LogDNACommon.report(logvisor::Fatal,
"PAKRouter::enterPAKBridge() must be called before PAKRouter::getCookedPath()"); "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) if (singleSearch)
{ {
const hecl::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].second; const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].second;
pakPath.makeDir(); pakPath.makeDir();
return hecl::ProjectPath(pakPath, getBestEntryName(*entry)); return hecl::ProjectPath(pakPath, getBestEntryName(*entry));
} }
@ -382,7 +387,8 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const IDType& id) const
template <class BRIDGETYPE> template <class BRIDGETYPE>
hecl::SystemString PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryType& a, const IDType& b) const hecl::SystemString PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryType& a, const IDType& b) const
{ {
if (!m_pak) const PAKType* pak = m_pak.get();
if (!pak)
LogDNACommon.report(logvisor::Fatal, LogDNACommon.report(logvisor::Fatal,
"PAKRouter::enterPAKBridge() must be called before PAKRouter::getResourceRelativePath()"); "PAKRouter::enterPAKBridge() must be called before PAKRouter::getResourceRelativePath()");
const typename BRIDGETYPE::PAKType::Entry* be = lookupEntry(b); const typename BRIDGETYPE::PAKType::Entry* be = lookupEntry(b);
@ -431,7 +437,8 @@ std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const IDType& entry) const
} }
template <class BRIDGETYPE> template <class BRIDGETYPE>
bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool force, bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool force, bool precedenceSharesOnly,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*, float)> progress) std::function<void(const hecl::SystemChar*, float)> progress)
{ {
enterPAKBridge(pakBridge); enterPAKBridge(pakBridge);
@ -446,16 +453,28 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
if (extractor.weight != w) if (extractor.weight != w)
continue; continue;
if (precedenceSharesOnly)
{
auto sharedSearch = m_sharedEntries.find(item->id);
if (sharedSearch != m_sharedEntries.cend())
{
if (sharedSearch->second.first != reinterpret_cast<intptr_t>(m_curBridgeIdx.get()))
continue;
}
}
std::string bestName = getBestEntryName(*item); std::string bestName = getBestEntryName(*item);
hecl::SystemStringView bestNameView(bestName); hecl::SystemStringView bestNameView(bestName);
float thisFac = ++count / fsz; float thisFac = ++count / fsz;
progress(bestNameView.sys_str().c_str(), thisFac); progress(bestNameView.sys_str().c_str(), thisFac);
const nod::Node* node = m_node.get();
/* Extract first, so they start out invalid */ /* Extract first, so they start out invalid */
hecl::ProjectPath cooked = getCooked(item); hecl::ProjectPath cooked = getCooked(item);
if (force || cooked.getPathType() == hecl::ProjectPath::Type::None) 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")); FILE* fout = hecl::Fopen(cooked.getAbsolutePath().c_str(), _S("wb"));
fwrite(s.data(), 1, s.length(), fout); fwrite(s.data(), 1, s.length(), fout);
fclose(fout); fclose(fout);
@ -466,7 +485,7 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
{ {
if (force || working.getPathType() == hecl::ProjectPath::Type::None) if (force || working.getPathType() == hecl::ProjectPath::Type::None)
{ {
PAKEntryReadStream s = item->beginReadStream(*m_node); PAKEntryReadStream s = item->beginReadStream(*node);
extractor.func_a(s, working); extractor.func_a(s, working);
} }
} }
@ -474,8 +493,8 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
{ {
if (force || working.getPathType() == hecl::ProjectPath::Type::None) if (force || working.getPathType() == hecl::ProjectPath::Type::None)
{ {
PAKEntryReadStream s = item->beginReadStream(*m_node); PAKEntryReadStream s = item->beginReadStream(*node);
extractor.func_b(m_dataSpec, s, working, *this, *item, force, extractor.func_b(m_dataSpec, s, working, *this, *item, force, btok,
[&progress, thisFac](const hecl::SystemChar* update) [&progress, thisFac](const hecl::SystemChar* update)
{ {
progress(update, thisFac); progress(update, thisFac);
@ -501,13 +520,15 @@ const typename BRIDGETYPE::PAKType::Entry* PAKRouter<BRIDGETYPE>::lookupEntry(co
LogDNACommon.report(logvisor::Fatal, LogDNACommon.report(logvisor::Fatal,
"PAKRouter::build() must be called before PAKRouter::lookupEntry()"); "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 (ent)
{ {
if (nodeOut) if (nodeOut)
*nodeOut = m_node; *nodeOut = node;
return ent; return ent;
} }
} }

View File

@ -2,6 +2,7 @@
#define __DNACOMMON_PAK_HPP__ #define __DNACOMMON_PAK_HPP__
#include "DNACommon.hpp" #include "DNACommon.hpp"
#include "boo/ThreadLocalPtr.hpp"
namespace DataSpec namespace DataSpec
{ {
@ -81,7 +82,7 @@ struct ResExtractor
{ {
std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func_a; std::function<bool(PAKEntryReadStream&, const hecl::ProjectPath&)> func_a;
std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&, std::function<bool(const SpecBase&, PAKEntryReadStream&, const hecl::ProjectPath&, PAKRouter<PAKBRIDGE>&,
const typename PAKBRIDGE::PAKType::Entry&, bool, const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::BlenderToken&,
std::function<void(const hecl::SystemChar*)>)> func_b; std::function<void(const hecl::SystemChar*)>)> func_b;
const hecl::SystemChar* fileExts[4]; const hecl::SystemChar* fileExts[4];
unsigned weight; unsigned weight;
@ -121,13 +122,13 @@ public:
private: private:
const std::vector<BRIDGETYPE>* m_bridges = nullptr; const std::vector<BRIDGETYPE>* m_bridges = nullptr;
std::vector<std::pair<hecl::ProjectPath,hecl::ProjectPath>> m_bridgePaths; std::vector<std::pair<hecl::ProjectPath,hecl::ProjectPath>> m_bridgePaths;
size_t m_curBridgeIdx = 0; ThreadLocalPtr<void> m_curBridgeIdx;
const hecl::ProjectPath& m_gameWorking; const hecl::ProjectPath& m_gameWorking;
const hecl::ProjectPath& m_gameCooked; const hecl::ProjectPath& m_gameCooked;
hecl::ProjectPath m_sharedWorking; hecl::ProjectPath m_sharedWorking;
hecl::ProjectPath m_sharedCooked; hecl::ProjectPath m_sharedCooked;
const PAKType* m_pak = nullptr; ThreadLocalPtr<const PAKType> m_pak;
const nod::Node* m_node = nullptr; ThreadLocalPtr<const nod::Node> m_node;
std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_uniqueEntries; std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_uniqueEntries;
std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_sharedEntries; std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_sharedEntries;
std::unordered_map<IDType, RigPair> m_cmdlRigs; std::unordered_map<IDType, RigPair> m_cmdlRigs;
@ -147,14 +148,19 @@ public:
hecl::ProjectPath getWorking(const IDType& id) const; hecl::ProjectPath getWorking(const IDType& id) const;
hecl::ProjectPath getCooked(const EntryType* entry) const; hecl::ProjectPath getCooked(const EntryType* entry) const;
hecl::ProjectPath getCooked(const IDType& id) 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; hecl::SystemString getResourceRelativePath(const EntryType& a, const IDType& b) const;
std::string getBestEntryName(const EntryType& entry) const; std::string getBestEntryName(const EntryType& entry) const;
std::string getBestEntryName(const IDType& 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<void(const hecl::SystemChar*, float)> progress); std::function<void(const hecl::SystemChar*, float)> progress);
const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry, const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry,

View File

@ -394,6 +394,7 @@ struct ANCS : BigYAML
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml")); hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
@ -417,7 +418,7 @@ struct ANCS : BigYAML
if (force || blendType == hecl::ProjectPath::Type::None) if (force || blendType == hecl::ProjectPath::Type::None)
{ {
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, DNACMDL::SurfaceHeader_1, 2> DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, DNACMDL::SurfaceHeader_1, 2>
(conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); (conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force);
} }

View File

@ -23,6 +23,7 @@ struct CMDL
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
/* Check for RigPair */ /* Check for RigPair */
@ -39,7 +40,7 @@ struct CMDL
} }
/* Do extract */ /* Do extract */
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh)) if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_1, 2> DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_1, 2>

View File

@ -311,12 +311,19 @@ size_t FRME::Widget::TXPNInfo::binarySize(size_t __isz) const
return __isz + (version == 1 ? 78 : 66); return __isz + (version == 1 ? 78 : 66);
} }
bool FRME::Extract(const SpecBase &dataSpec, PAKEntryReadStream &rs, const hecl::ProjectPath &outPath, PAKRouter<PAKBridge> &pakRouter, const PAK::Entry &entry, bool force, std::function<void (const hecl::SystemChar *)> fileChanged) bool FRME::Extract(const SpecBase &dataSpec,
PAKEntryReadStream &rs,
const hecl::ProjectPath &outPath,
PAKRouter<PAKBridge> &pakRouter,
const PAK::Entry &entry,
bool force,
hecl::BlenderToken& btok,
std::function<void (const hecl::SystemChar *)> fileChanged)
{ {
FRME frme; FRME frme;
frme.read(rs); frme.read(rs);
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
#if 0 #if 0
if (!force && outPath.getPathType() == hecl::ProjectPath::Type::File) if (!force && outPath.getPathType() == hecl::ProjectPath::Type::File)

View File

@ -262,6 +262,7 @@ struct FRME : BigDNA
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged); std::function<void(const hecl::SystemChar*)> fileChanged);
}; };

View File

@ -20,11 +20,12 @@ struct MAPA : DNAMAPA::MAPA
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
MAPA mapa; MAPA mapa;
mapa.read(rs); mapa.read(rs);
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force);
} }
}; };

View File

@ -112,6 +112,7 @@ struct MLVL : BigYAML
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
MLVL mlvl; MLVL mlvl;
@ -119,7 +120,7 @@ struct MLVL : BigYAML
FILE* fp = hecl::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("w")); FILE* fp = hecl::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("w"));
mlvl.toYAMLFile(fp); mlvl.toYAMLFile(fp);
fclose(fp); fclose(fp);
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter,
entry, force, fileChanged); entry, force, fileChanged);
} }

View File

@ -57,6 +57,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)>) std::function<void(const hecl::SystemChar*)>)
{ {
using RigPair = std::pair<CSKR*, CINF*>; using RigPair = std::pair<CSKR*, CINF*>;
@ -78,7 +79,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
head.read(rs); head.read(rs);
rs.seekAlign32(); rs.seekAlign32();
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
if (!conn.createBlend(mreaPath, hecl::BlenderConnection::BlendType::Area)) if (!conn.createBlend(mreaPath, hecl::BlenderConnection::BlendType::Area))
return false; return false;

View File

@ -113,6 +113,7 @@ struct MREA
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool, bool,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)>); std::function<void(const hecl::SystemChar*)>);
static void Name(const SpecBase& dataSpec, static void Name(const SpecBase& dataSpec,

View File

@ -217,6 +217,7 @@ struct ANCS : BigYAML
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const DNAMP1::PAK::Entry& entry, const DNAMP1::PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml")); hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
@ -240,7 +241,7 @@ struct ANCS : BigYAML
if (force || blendType == hecl::ProjectPath::Type::None) if (force || blendType == hecl::ProjectPath::Type::None)
{ {
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, DNACMDL::SurfaceHeader_2, 4> DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, DNACMDL::SurfaceHeader_2, 4>
(conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); (conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force);
} }

View File

@ -21,6 +21,7 @@ struct CMDL
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const DNAMP1::PAK::Entry& entry, const DNAMP1::PAK::Entry& entry,
bool, bool,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)>) std::function<void(const hecl::SystemChar*)>)
{ {
/* Check for RigPair */ /* Check for RigPair */
@ -37,7 +38,7 @@ struct CMDL
} }
/* Do extract */ /* Do extract */
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh)) if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_2, 4> DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_2, 4>

View File

@ -17,11 +17,12 @@ struct MAPA : DNAMAPA::MAPA
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const DNAMP1::PAK::Entry& entry, const DNAMP1::PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
MAPA mapa; MAPA mapa;
mapa.read(rs); mapa.read(rs);
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force);
} }
}; };

View File

@ -100,6 +100,7 @@ struct MLVL : BigYAML
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const DNAMP1::PAK::Entry& entry, const DNAMP1::PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
MLVL mlvl; MLVL mlvl;
@ -107,7 +108,7 @@ struct MLVL : BigYAML
FILE* fp = hecl::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("wb")); FILE* fp = hecl::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("wb"));
mlvl.toYAMLFile(fp); mlvl.toYAMLFile(fp);
fclose(fp); fclose(fp);
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter,
entry, force, fileChanged); entry, force, fileChanged);
} }

View File

@ -163,6 +163,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const DNAMP1::PAK::Entry& entry, const DNAMP1::PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)>) std::function<void(const hecl::SystemChar*)>)
{ {
using RigPair = std::pair<CSKR*, CINF*>; using RigPair = std::pair<CSKR*, CINF*>;
@ -197,7 +198,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
drs.seek(0, athena::Begin); drs.seek(0, athena::Begin);
/* Start up blender connection */ /* Start up blender connection */
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
if (!conn.createBlend(mreaPath, hecl::BlenderConnection::BlendType::Area)) if (!conn.createBlend(mreaPath, hecl::BlenderConnection::BlendType::Area))
return false; return false;

View File

@ -123,6 +123,7 @@ struct MREA
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const DNAMP1::PAK::Entry& entry, const DNAMP1::PAK::Entry& entry,
bool, bool,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)>); std::function<void(const hecl::SystemChar*)>);
}; };

View File

@ -312,6 +312,7 @@ struct CHAR : BigYAML
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml")); hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
@ -335,7 +336,7 @@ struct CHAR : BigYAML
if (force || blendType == hecl::ProjectPath::Type::None) if (force || blendType == hecl::ProjectPath::Type::None)
{ {
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, CHAR, MaterialSet, DNACMDL::SurfaceHeader_3, 4> DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, CHAR, MaterialSet, DNACMDL::SurfaceHeader_3, 4>
(conn, aChar, blendPath, pakRouter, entry, dataSpec, fileChanged, force); (conn, aChar, blendPath, pakRouter, entry, dataSpec, fileChanged, force);
} }

View File

@ -21,6 +21,7 @@ struct CMDL
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool, bool,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)>) std::function<void(const hecl::SystemChar*)>)
{ {
/* Check for RigPair */ /* Check for RigPair */
@ -37,7 +38,7 @@ struct CMDL
} }
/* Do extract */ /* Do extract */
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh)) if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_3, 5> DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_3, 5>

View File

@ -17,11 +17,12 @@ struct MAPA : DNAMAPA::MAPA
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
MAPA mapa; MAPA mapa;
mapa.read(rs); mapa.read(rs);
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force);
} }
}; };

View File

@ -89,6 +89,7 @@ struct MLVL : BigYAML
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
MLVL mlvl; MLVL mlvl;
@ -96,7 +97,7 @@ struct MLVL : BigYAML
FILE* fp = hecl::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("wb")); FILE* fp = hecl::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("wb"));
mlvl.toYAMLFile(fp); mlvl.toYAMLFile(fp);
fclose(fp); fclose(fp);
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter,
entry, force, fileChanged); entry, force, fileChanged);
} }

View File

@ -72,6 +72,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool force, bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)>) std::function<void(const hecl::SystemChar*)>)
{ {
using RigPair = std::pair<CSKR*, CINF*>; using RigPair = std::pair<CSKR*, CINF*>;
@ -109,7 +110,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
/* Start up blender connection */ /* Start up blender connection */
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
if (!conn.createBlend(mreaPath, hecl::BlenderConnection::BlendType::Area)) if (!conn.createBlend(mreaPath, hecl::BlenderConnection::BlendType::Area))
return false; return false;

View File

@ -120,6 +120,7 @@ struct MREA
PAKRouter<PAKBridge>& pakRouter, PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry, const PAK::Entry& entry,
bool, bool,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)>); std::function<void(const hecl::SystemChar*)>);
static bool ExtractLayerDeps(PAKEntryReadStream& rs, PAKBridge::Level::Area& areaOut); static bool ExtractLayerDeps(PAKEntryReadStream& rs, PAKBridge::Level::Area& areaOut);

View File

@ -16,6 +16,8 @@
#include "DNACommon/CRSC.hpp" #include "DNACommon/CRSC.hpp"
#include "DNACommon/DPSC.hpp" #include "DNACommon/DPSC.hpp"
#include "hecl/ClientProcess.hpp"
namespace DataSpec namespace DataSpec
{ {
@ -252,6 +254,8 @@ struct SpecMP1 : SpecBase
} }
progress(_S("MP1 Root"), _S(""), 3, 1.0); progress(_S("MP1 Root"), _S(""), 3, 1.0);
std::mutex msgLock;
hecl::ClientProcess process;
int compIdx = 4; int compIdx = 4;
prog = 0; prog = 0;
for (std::pair<std::string, DNAMP1::PAKBridge*> pair : m_orderedPaks) for (std::pair<std::string, DNAMP1::PAKBridge*> pair : m_orderedPaks)
@ -263,13 +267,20 @@ struct SpecMP1 : SpecBase
const std::string& name = pak.getName(); const std::string& name = pak.getName();
hecl::SystemStringView sysName(name); 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<std::mutex> 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<std::mutex> lk(msgLock);
progress(pakName.c_str(), substr, compIdx, factor);
});
}); });
progress(sysName.sys_str().c_str(), _S(""), compIdx++, 1.0);
} }
return true; return true;

View File

@ -6,6 +6,8 @@
#include "DNAMP2/MLVL.hpp" #include "DNAMP2/MLVL.hpp"
#include "DNAMP2/STRG.hpp" #include "DNAMP2/STRG.hpp"
#include "hecl/ClientProcess.hpp"
namespace DataSpec namespace DataSpec
{ {
@ -234,6 +236,8 @@ struct SpecMP2 : SpecBase
} }
progress(_S("MP2 Root"), _S(""), 3, 1.0); progress(_S("MP2 Root"), _S(""), 3, 1.0);
std::mutex msgLock;
hecl::ClientProcess process;
int compIdx = 4; int compIdx = 4;
prog = 0; prog = 0;
for (std::pair<std::string, DNAMP2::PAKBridge*> pair : m_orderedPaks) for (std::pair<std::string, DNAMP2::PAKBridge*> pair : m_orderedPaks)
@ -245,13 +249,20 @@ struct SpecMP2 : SpecBase
const std::string& name = pak.getName(); const std::string& name = pak.getName();
hecl::SystemStringView sysName(name); 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<std::mutex> 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<std::mutex> lk(msgLock);
progress(pakName.c_str(), substr, compIdx, factor);
});
}); });
progress(sysName.sys_str().c_str(), _S(""), compIdx++, 1.0);
} }
return true; return true;

View File

@ -8,6 +8,8 @@
#include "DNAMP3/STRG.hpp" #include "DNAMP3/STRG.hpp"
#include "DNAMP2/STRG.hpp" #include "DNAMP2/STRG.hpp"
#include "hecl/ClientProcess.hpp"
namespace DataSpec namespace DataSpec
{ {
@ -366,6 +368,8 @@ struct SpecMP3 : SpecBase
progress(currentTarget.c_str(), _S(""), compIdx++, 1.0); progress(currentTarget.c_str(), _S(""), compIdx++, 1.0);
std::mutex msgLock;
hecl::ClientProcess process;
prog = 0; prog = 0;
for (std::pair<std::string, DNAMP3::PAKBridge*> pair : m_orderedPaks) for (std::pair<std::string, DNAMP3::PAKBridge*> pair : m_orderedPaks)
{ {
@ -376,13 +380,20 @@ struct SpecMP3 : SpecBase
const std::string& name = pak.getName(); const std::string& name = pak.getName();
hecl::SystemStringView sysName(name); 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<std::mutex> 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<std::mutex> 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); progress(currentTarget.c_str(), _S(""), compIdx++, 1.0);
std::mutex msgLock;
hecl::ClientProcess process;
prog = 0; prog = 0;
for (std::pair<std::string, DNAMP3::PAKBridge*> pair : m_feOrderedPaks) for (std::pair<std::string, DNAMP3::PAKBridge*> pair : m_feOrderedPaks)
{ {
@ -427,13 +440,20 @@ struct SpecMP3 : SpecBase
const std::string& name = pak.getName(); const std::string& name = pak.getName();
hecl::SystemStringView sysName(name); 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<std::mutex> 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<std::mutex> lk(msgLock);
progress(pakName.c_str(), substr, compIdx, factor);
});
}); });
progress(sysName.sys_str().c_str(), _S(""), compIdx++, 1.0);
} }
} }
return true; return true;

View File

@ -308,10 +308,8 @@ class TLockedToken : public TCachedToken<T>
{ {
public: public:
TLockedToken() = default; TLockedToken() = default;
TLockedToken(const CToken& other) : TCachedToken<T>(other) TLockedToken(const CToken& other) : TCachedToken<T>(other) {CToken::Lock();}
{TCachedToken<T>::m_obj = TToken<T>::GetObj();} TLockedToken(CToken&& other) : TCachedToken<T>(std::move(other)) {CToken::Lock();}
TLockedToken(CToken&& other) : TCachedToken<T>(std::move(other))
{TCachedToken<T>::m_obj = TToken<T>::GetObj();}
}; };
} }

View File

@ -170,7 +170,6 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(const UVAnimation& anim)
{ {
case UVAnimation::Mode::MvInvNoTranslation: case UVAnimation::Mode::MvInvNoTranslation:
{ {
matrixOut = CGraphics::g_ViewMatrix.inverse().multiplyIgnoreTranslation( matrixOut = CGraphics::g_ViewMatrix.inverse().multiplyIgnoreTranslation(
CGraphics::g_GXModelMatrix).toMatrix4f(); CGraphics::g_GXModelMatrix).toMatrix4f();
matrixOut.vec[3].zeroOut(); matrixOut.vec[3].zeroOut();

2
hecl

@ -1 +1 @@
Subproject commit 51349be32ab052618e02a82a8e21b495b5b00432 Subproject commit 26f586dbc2a7a614abe0fb5b86bb2bc32c43b5f9