mirror of https://github.com/AxioDL/metaforce.git
Initial migration to URDE-hashed object tags
This commit is contained in:
parent
c1af78e7ed
commit
2a614215c8
|
@ -21,7 +21,6 @@ add_library(DNACommon
|
||||||
ParticleCommon.cpp
|
ParticleCommon.cpp
|
||||||
DeafBabe.hpp
|
DeafBabe.hpp
|
||||||
BabeDead.hpp
|
BabeDead.hpp
|
||||||
NamedResourceCatalog.hpp
|
|
||||||
Tweaks/ITweakGame.hpp
|
Tweaks/ITweakGame.hpp
|
||||||
Tweaks/ITweakParticle.hpp
|
Tweaks/ITweakParticle.hpp
|
||||||
Tweaks/ITweakPlayer.hpp
|
Tweaks/ITweakPlayer.hpp
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include "DNACommon.hpp"
|
#include "DNACommon.hpp"
|
||||||
|
#include "PAK.hpp"
|
||||||
|
|
||||||
namespace DataSpec
|
namespace DataSpec
|
||||||
{
|
{
|
||||||
|
|
||||||
LogVisor::LogModule LogDNACommon("Retro::DNACommon");
|
LogVisor::LogModule LogDNACommon("Retro::DNACommon");
|
||||||
SpecBase* g_curSpec = nullptr;
|
SpecBase* g_curSpec = nullptr;
|
||||||
|
PAKRouterBase* g_PakRouter = nullptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace DataSpec
|
||||||
|
|
||||||
extern LogVisor::LogModule LogDNACommon;
|
extern LogVisor::LogModule LogDNACommon;
|
||||||
extern SpecBase* g_curSpec;
|
extern SpecBase* g_curSpec;
|
||||||
|
extern class PAKRouterBase* g_PakRouter;
|
||||||
|
|
||||||
/* This comes up a great deal */
|
/* This comes up a great deal */
|
||||||
typedef Athena::io::DNA<Athena::BigEndian> BigDNA;
|
typedef Athena::io::DNA<Athena::BigEndian> BigDNA;
|
||||||
|
@ -44,6 +45,64 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
using FourCC = HECL::FourCC;
|
using FourCC = HECL::FourCC;
|
||||||
|
class UniqueID32;
|
||||||
|
class UniqueID64;
|
||||||
|
class UniqueID128;
|
||||||
|
|
||||||
|
/** Common virtual interface for runtime ambiguity resolution */
|
||||||
|
class PAKRouterBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const SpecBase& m_dataSpec;
|
||||||
|
public:
|
||||||
|
PAKRouterBase(const SpecBase& dataSpec) : m_dataSpec(dataSpec) {}
|
||||||
|
HECL::Database::Project& getProject() const {return m_dataSpec.getProject();}
|
||||||
|
virtual HECL::ProjectPath getWorking(const UniqueID32&) const
|
||||||
|
{
|
||||||
|
LogDNACommon.report(LogVisor::FatalError, "PAKRouter IDType mismatch; expected UniqueID32 specialization");
|
||||||
|
return HECL::ProjectPath();
|
||||||
|
}
|
||||||
|
virtual HECL::ProjectPath getWorking(const UniqueID64&) const
|
||||||
|
{
|
||||||
|
LogDNACommon.report(LogVisor::FatalError, "PAKRouter IDType mismatch; expected UniqueID64 specialization");
|
||||||
|
return HECL::ProjectPath();
|
||||||
|
}
|
||||||
|
virtual HECL::ProjectPath getWorking(const UniqueID128&) const
|
||||||
|
{
|
||||||
|
LogDNACommon.report(LogVisor::FatalError, "PAKRouter IDType mismatch; expected UniqueID128 specialization");
|
||||||
|
return HECL::ProjectPath();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Globally-accessed manager allowing UniqueID* classes to directly
|
||||||
|
* lookup destination paths of resources */
|
||||||
|
class UniqueIDBridge
|
||||||
|
{
|
||||||
|
friend class UniqueID32;
|
||||||
|
friend class UniqueID64;
|
||||||
|
public:
|
||||||
|
template <class IDType>
|
||||||
|
static HECL::ProjectPath TranslatePakIdToPath(const IDType& id)
|
||||||
|
{
|
||||||
|
if (!g_PakRouter)
|
||||||
|
LogDNACommon.report(LogVisor::FatalError,
|
||||||
|
"UniqueIDBridge::setPakRouter must be called before translatePakIdToPath");
|
||||||
|
HECL::ProjectPath res = g_PakRouter->getWorking(id);
|
||||||
|
if (!res)
|
||||||
|
LogDNACommon.report(LogVisor::FatalError,
|
||||||
|
"unable to translate %s to path", id.toString().c_str());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
static HECL::ProjectPath MakePathFromString(const std::string& str)
|
||||||
|
{
|
||||||
|
return HECL::ProjectPath(g_PakRouter->getProject(), str);
|
||||||
|
}
|
||||||
|
template <class IDType>
|
||||||
|
static void TransformOldHashToNewHash(IDType& id)
|
||||||
|
{
|
||||||
|
id = TranslatePakIdToPath(id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** PAK 32-bit Unique ID */
|
/** PAK 32-bit Unique ID */
|
||||||
class UniqueID32 : public BigYAML
|
class UniqueID32 : public BigYAML
|
||||||
|
@ -57,9 +116,13 @@ public:
|
||||||
void write(Athena::io::IStreamWriter& writer) const
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
{writer.writeUint32Big(m_id);}
|
{writer.writeUint32Big(m_id);}
|
||||||
void read(Athena::io::YAMLDocReader& reader)
|
void read(Athena::io::YAMLDocReader& reader)
|
||||||
{m_id = reader.readUint32(nullptr);}
|
{
|
||||||
|
*this = UniqueIDBridge::MakePathFromString(reader.readString(nullptr));
|
||||||
|
}
|
||||||
void write(Athena::io::YAMLDocWriter& writer) const
|
void write(Athena::io::YAMLDocWriter& writer) const
|
||||||
{writer.writeUint32(nullptr, m_id);}
|
{
|
||||||
|
writer.writeString(nullptr, UniqueIDBridge::TranslatePakIdToPath(*this).getRelativePathUTF8());
|
||||||
|
}
|
||||||
size_t binarySize(size_t __isz) const
|
size_t binarySize(size_t __isz) const
|
||||||
{return __isz + 4;}
|
{return __isz + 4;}
|
||||||
|
|
||||||
|
@ -110,9 +173,13 @@ public:
|
||||||
void write(Athena::io::IStreamWriter& writer) const
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
{writer.writeUint64Big(m_id);}
|
{writer.writeUint64Big(m_id);}
|
||||||
void read(Athena::io::YAMLDocReader& reader)
|
void read(Athena::io::YAMLDocReader& reader)
|
||||||
{m_id = reader.readUint64(nullptr);}
|
{
|
||||||
|
*this = UniqueIDBridge::MakePathFromString(reader.readString(nullptr));
|
||||||
|
}
|
||||||
void write(Athena::io::YAMLDocWriter& writer) const
|
void write(Athena::io::YAMLDocWriter& writer) const
|
||||||
{writer.writeUint64(nullptr, m_id);}
|
{
|
||||||
|
writer.writeString(nullptr, UniqueIDBridge::TranslatePakIdToPath(*this).getRelativePathUTF8());
|
||||||
|
}
|
||||||
size_t binarySize(size_t __isz) const
|
size_t binarySize(size_t __isz) const
|
||||||
{return __isz + 8;}
|
{return __isz + 8;}
|
||||||
|
|
||||||
|
@ -186,21 +253,22 @@ public:
|
||||||
}
|
}
|
||||||
void read(Athena::io::YAMLDocReader& reader)
|
void read(Athena::io::YAMLDocReader& reader)
|
||||||
{
|
{
|
||||||
std::string str = reader.readString(nullptr);
|
*this = UniqueIDBridge::MakePathFromString(reader.readString(nullptr));
|
||||||
while (str.size() < 32)
|
|
||||||
str += '0';
|
|
||||||
std::string hStr(str.begin(), str.begin() + 16);
|
|
||||||
std::string lStr(str.begin() + 16, str.begin() + 32);
|
|
||||||
m_id[0] = strtoull(hStr.c_str(), nullptr, 16);
|
|
||||||
m_id[1] = strtoull(lStr.c_str(), nullptr, 16);
|
|
||||||
}
|
}
|
||||||
void write(Athena::io::YAMLDocWriter& writer) const
|
void write(Athena::io::YAMLDocWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.writeString(nullptr, toString().c_str());
|
writer.writeString(nullptr, UniqueIDBridge::TranslatePakIdToPath(*this).getRelativePathUTF8());
|
||||||
}
|
}
|
||||||
size_t binarySize(size_t __isz) const
|
size_t binarySize(size_t __isz) const
|
||||||
{return __isz + 16;}
|
{return __isz + 16;}
|
||||||
|
|
||||||
|
UniqueID128& operator=(const HECL::ProjectPath& path)
|
||||||
|
{
|
||||||
|
m_id[0] = path.hash().val64();
|
||||||
|
m_id[1] = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator!=(const UniqueID128& other) const
|
bool operator!=(const UniqueID128& other) const
|
||||||
{
|
{
|
||||||
#if __SSE__
|
#if __SSE__
|
||||||
|
@ -234,61 +302,6 @@ public:
|
||||||
static constexpr size_t BinarySize() {return 16;}
|
static constexpr size_t BinarySize() {return 16;}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Class that automatically converts between hash and path for DNA usage */
|
|
||||||
template <class IDTYPE>
|
|
||||||
class PAKPath : public BigYAML
|
|
||||||
{
|
|
||||||
HECL::ProjectPath m_path;
|
|
||||||
IDTYPE m_id;
|
|
||||||
public:
|
|
||||||
HECL::ProjectPath getPath() const
|
|
||||||
{
|
|
||||||
if (m_path)
|
|
||||||
return m_path;
|
|
||||||
if (!g_curSpec)
|
|
||||||
LogDNACommon.report(LogVisor::FatalError, "current DataSpec not set for PAKPath");
|
|
||||||
if (m_id)
|
|
||||||
return g_curSpec->getWorking(m_id);
|
|
||||||
return HECL::ProjectPath();
|
|
||||||
}
|
|
||||||
operator HECL::ProjectPath() const {return getPath();}
|
|
||||||
operator const IDTYPE&() const {return m_id;}
|
|
||||||
|
|
||||||
Delete _d;
|
|
||||||
void read(Athena::io::IStreamReader& reader)
|
|
||||||
{m_id.read(reader);}
|
|
||||||
void write(Athena::io::IStreamWriter& writer) const
|
|
||||||
{m_id.write(writer);}
|
|
||||||
void read(Athena::io::YAMLDocReader& reader)
|
|
||||||
{
|
|
||||||
if (!g_curSpec)
|
|
||||||
LogDNACommon.report(LogVisor::FatalError, "current DataSpec not set for PAKPath");
|
|
||||||
std::string path = reader.readString(nullptr);
|
|
||||||
if (path.empty())
|
|
||||||
{
|
|
||||||
m_path.clear();
|
|
||||||
m_id.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_path.assign(g_curSpec->getProject(), path);
|
|
||||||
m_id = m_path;
|
|
||||||
}
|
|
||||||
void write(Athena::io::YAMLDocWriter& writer) const
|
|
||||||
{
|
|
||||||
if (m_path)
|
|
||||||
{
|
|
||||||
writer.writeString(nullptr, m_path.getRelativePathUTF8());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
writer.writeString(nullptr, getPath().getRelativePathUTF8());
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t binarySize(size_t __isz) const
|
|
||||||
{return __isz + IDTYPE::BinarySize();}
|
|
||||||
};
|
|
||||||
using PAKPath32 = PAKPath<UniqueID32>;
|
|
||||||
using PAKPath64 = PAKPath<UniqueID64>;
|
|
||||||
|
|
||||||
/** Word Bitmap reader/writer */
|
/** Word Bitmap reader/writer */
|
||||||
class WordBitmap
|
class WordBitmap
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,14 +24,6 @@ bool ReadMLVLToBlender(HECL::BlenderConnection& conn,
|
||||||
if (!force && mlvlPath.getPathType() == HECL::ProjectPath::Type::File)
|
if (!force && mlvlPath.getPathType() == HECL::ProjectPath::Type::File)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Link Skybox CMDL */
|
|
||||||
const typename PAKRouter::EntryType* skyboxEntry = pakRouter.lookupEntry(mlvl.worldSkyboxId);
|
|
||||||
if (skyboxEntry)
|
|
||||||
{
|
|
||||||
HECL::ProjectPath skyboxPath = pakRouter.getWorking(skyboxEntry);
|
|
||||||
HECL::ProjectPath(outPath.getParentPath(), _S("!skybox.blend")).makeLinkTo(skyboxPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create World Blend */
|
/* Create World Blend */
|
||||||
if (!conn.createBlend(mlvlPath, HECL::BlenderConnection::BlendType::World))
|
if (!conn.createBlend(mlvlPath, HECL::BlenderConnection::BlendType::World))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,132 +0,0 @@
|
||||||
#ifndef __DNACOMMON_NAMEDRESOURCECATALOG_HPP__
|
|
||||||
#define __DNACOMMON_NAMEDRESOURCECATALOG_HPP__
|
|
||||||
|
|
||||||
#include "DNACommon.hpp"
|
|
||||||
namespace DataSpec
|
|
||||||
{
|
|
||||||
template <class IDType>
|
|
||||||
struct NamedResourceCatalog : BigYAML
|
|
||||||
{
|
|
||||||
Delete _d;
|
|
||||||
Value<atUint32> namedResCount = 0;
|
|
||||||
struct NamedResource : BigYAML
|
|
||||||
{
|
|
||||||
Delete _d;
|
|
||||||
DNAFourCC type;
|
|
||||||
String<-1> name;
|
|
||||||
IDType uid;
|
|
||||||
|
|
||||||
void read(Athena::io::IStreamReader& __dna_reader)
|
|
||||||
{
|
|
||||||
/* type */
|
|
||||||
type.read(__dna_reader);
|
|
||||||
/* name */
|
|
||||||
name = __dna_reader.readString(-1);
|
|
||||||
/* uid */
|
|
||||||
uid.read(__dna_reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(Athena::io::IStreamWriter& __dna_writer) const
|
|
||||||
{
|
|
||||||
/* type */
|
|
||||||
type.write(__dna_writer);
|
|
||||||
/* name */
|
|
||||||
__dna_writer.writeString(name, -1);
|
|
||||||
/* uid */
|
|
||||||
uid.write(__dna_writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void read(Athena::io::YAMLDocReader& __dna_docin)
|
|
||||||
{
|
|
||||||
/* type */
|
|
||||||
__dna_docin.enumerate("type", type);
|
|
||||||
/* name */
|
|
||||||
name = __dna_docin.readString("name");
|
|
||||||
/* uid */
|
|
||||||
__dna_docin.enumerate("uid", uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(Athena::io::YAMLDocWriter& __dna_docout) const
|
|
||||||
{
|
|
||||||
/* type */
|
|
||||||
__dna_docout.enumerate("type", type);
|
|
||||||
/* name */
|
|
||||||
__dna_docout.writeString("name", name);
|
|
||||||
/* uid */
|
|
||||||
__dna_docout.enumerate("uid", uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* DNAType() { return "DataSpec::DNACommon::NameResourceCatalog::NamedResource"; }
|
|
||||||
|
|
||||||
size_t binarySize(size_t __isz) const
|
|
||||||
{
|
|
||||||
__isz = type.binarySize(__isz);
|
|
||||||
__isz += name.size() + 1;
|
|
||||||
__isz = uid.binarySize(__isz);
|
|
||||||
return __isz;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Vector<NamedResource, DNA_COUNT(namedResCount)> namedResources;
|
|
||||||
|
|
||||||
void read(Athena::io::IStreamReader& __dna_reader)
|
|
||||||
{
|
|
||||||
/* namedResCount */
|
|
||||||
namedResCount = __dna_reader.readUint32Big();
|
|
||||||
/* namedResources */
|
|
||||||
__dna_reader.enumerate(namedResources, namedResCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(Athena::io::IStreamWriter& __dna_writer) const
|
|
||||||
{
|
|
||||||
/* namedResCount */
|
|
||||||
__dna_writer.writeUint32Big(namedResCount);
|
|
||||||
/* namedResources */
|
|
||||||
__dna_writer.enumerate(namedResources);
|
|
||||||
}
|
|
||||||
|
|
||||||
void read(Athena::io::YAMLDocReader& __dna_docin)
|
|
||||||
{
|
|
||||||
/* namedResCount */
|
|
||||||
namedResCount = __dna_docin.readUint32("namedResCount");
|
|
||||||
/* namedResources */
|
|
||||||
__dna_docin.enumerate("namedResources", namedResources, namedResCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(Athena::io::YAMLDocWriter& __dna_docout) const
|
|
||||||
{
|
|
||||||
/* namedResCount */
|
|
||||||
__dna_docout.writeUint32("namedResCount", namedResCount);
|
|
||||||
/* namedResources */
|
|
||||||
__dna_docout.enumerate("namedResources", namedResources);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* DNAType()
|
|
||||||
{
|
|
||||||
return "DataSpec::DNACommon::NameResourceCatalog";
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t binarySize(size_t __isz) const
|
|
||||||
{
|
|
||||||
__isz = __EnumerateSize(__isz, namedResources);
|
|
||||||
return __isz + 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addNamedResource(const std::string& name, const IDType& id, const DNAFourCC& type)
|
|
||||||
{
|
|
||||||
NamedResource res;
|
|
||||||
res.type = type;
|
|
||||||
res.name = name;
|
|
||||||
res.uid = id;
|
|
||||||
auto it = std::find_if(namedResources.begin(), namedResources.end(), [res](const NamedResource& a)->bool
|
|
||||||
{ return (a.name == res.name && a.type == res.type && a.uid == res.uid); });
|
|
||||||
|
|
||||||
if (it != namedResources.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
namedResources.push_back(std::move(res));
|
|
||||||
namedResCount++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // NAMEDRESOURCECATALOG_HPP
|
|
|
@ -2,12 +2,11 @@
|
||||||
#define __DNACOMMON_PAK_HPP__
|
#define __DNACOMMON_PAK_HPP__
|
||||||
|
|
||||||
#include "DNACommon.hpp"
|
#include "DNACommon.hpp"
|
||||||
#include "NamedResourceCatalog.hpp"
|
|
||||||
|
|
||||||
namespace DataSpec
|
namespace DataSpec
|
||||||
{
|
{
|
||||||
|
|
||||||
/* PAK entry stream reader */
|
/** PAK entry stream reader */
|
||||||
class PAKEntryReadStream : public Athena::io::IStreamReader
|
class PAKEntryReadStream : public Athena::io::IStreamReader
|
||||||
{
|
{
|
||||||
std::unique_ptr<atUint8[]> m_buf;
|
std::unique_ptr<atUint8[]> m_buf;
|
||||||
|
@ -197,7 +196,7 @@ struct UniqueResult
|
||||||
template <class BRIDGETYPE>
|
template <class BRIDGETYPE>
|
||||||
class PAKRouter;
|
class PAKRouter;
|
||||||
|
|
||||||
/* Resource extractor type */
|
/** Resource extractor type */
|
||||||
template <class PAKBRIDGE>
|
template <class PAKBRIDGE>
|
||||||
struct ResExtractor
|
struct ResExtractor
|
||||||
{
|
{
|
||||||
|
@ -211,7 +210,7 @@ struct ResExtractor
|
||||||
typename PAKBRIDGE::PAKType::Entry&)> func_name;
|
typename PAKBRIDGE::PAKType::Entry&)> func_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Level hierarchy representation */
|
/** Level hierarchy representation */
|
||||||
template <class IDType>
|
template <class IDType>
|
||||||
struct Level
|
struct Level
|
||||||
{
|
{
|
||||||
|
@ -231,9 +230,9 @@ struct Level
|
||||||
std::unordered_map<IDType, Area> areas;
|
std::unordered_map<IDType, Area> areas;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PAKRouter (for detecting shared entry locations) */
|
/** PAKRouter (for detecting shared entry locations) */
|
||||||
template <class BRIDGETYPE>
|
template <class BRIDGETYPE>
|
||||||
class PAKRouter
|
class PAKRouter : public PAKRouterBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using PAKType = typename BRIDGETYPE::PAKType;
|
using PAKType = typename BRIDGETYPE::PAKType;
|
||||||
|
@ -241,8 +240,6 @@ public:
|
||||||
using EntryType = typename PAKType::Entry;
|
using EntryType = typename PAKType::Entry;
|
||||||
using RigPair = std::pair<IDType, IDType>;
|
using RigPair = std::pair<IDType, IDType>;
|
||||||
private:
|
private:
|
||||||
NamedResourceCatalog<IDType> m_catalog;
|
|
||||||
const SpecBase& m_dataSpec;
|
|
||||||
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;
|
size_t m_curBridgeIdx = 0;
|
||||||
|
@ -257,12 +254,13 @@ private:
|
||||||
std::unordered_map<IDType, RigPair> m_cmdlRigs;
|
std::unordered_map<IDType, RigPair> m_cmdlRigs;
|
||||||
public:
|
public:
|
||||||
PAKRouter(const SpecBase& dataSpec, const HECL::ProjectPath& working, const HECL::ProjectPath& cooked)
|
PAKRouter(const SpecBase& dataSpec, const HECL::ProjectPath& working, const HECL::ProjectPath& cooked)
|
||||||
: m_dataSpec(dataSpec),
|
: PAKRouterBase(dataSpec),
|
||||||
m_gameWorking(working), m_gameCooked(cooked),
|
m_gameWorking(working), m_gameCooked(cooked),
|
||||||
m_sharedWorking(working, "Shared"), m_sharedCooked(cooked, "Shared") {}
|
m_sharedWorking(working, "Shared"), m_sharedCooked(cooked, "Shared") {}
|
||||||
|
|
||||||
void build(std::vector<BRIDGETYPE>& bridges, std::function<void(float)> progress)
|
void build(std::vector<BRIDGETYPE>& bridges, std::function<void(float)> progress)
|
||||||
{
|
{
|
||||||
|
g_PakRouter = this;
|
||||||
m_bridges = &bridges;
|
m_bridges = &bridges;
|
||||||
m_bridgePaths.clear();
|
m_bridgePaths.clear();
|
||||||
|
|
||||||
|
@ -311,21 +309,29 @@ public:
|
||||||
/* Add RigPairs to global map */
|
/* Add RigPairs to global map */
|
||||||
bridge.addCMDLRigPairs(*this, m_cmdlRigs);
|
bridge.addCMDLRigPairs(*this, m_cmdlRigs);
|
||||||
|
|
||||||
/* Add named resources to catalog */
|
|
||||||
for (const auto& namedEntry : pak.m_nameEntries)
|
|
||||||
m_catalog.addNamedResource(namedEntry.name, namedEntry.id, namedEntry.type);
|
|
||||||
|
|
||||||
progress(++count / bridgesSz);
|
progress(++count / bridgesSz);
|
||||||
++bridgeIdx;
|
++bridgeIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
HECL::SystemString catalogPath = HECL::ProjectPath(m_gameCooked, "catalog.yaml").getAbsolutePath();
|
/* Add named resources to catalog YAML */
|
||||||
FILE* catalog = HECL::Fopen(catalogPath.c_str(), _S("wb"));
|
Athena::io::YAMLDocWriter catalogWriter(nullptr);
|
||||||
if (catalog)
|
for (BRIDGETYPE& bridge : bridges)
|
||||||
{
|
{
|
||||||
m_catalog.toYAMLFile(catalog);
|
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK();
|
||||||
fclose(catalog);
|
for (const auto& namedEntry : pak.m_nameEntries)
|
||||||
|
{
|
||||||
|
catalogWriter.enterSubRecord(namedEntry.name.c_str());
|
||||||
|
catalogWriter.writeString(nullptr, getWorking(namedEntry.id).getRelativePathUTF8().c_str());
|
||||||
|
catalogWriter.leaveSubRecord();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write catalog */
|
||||||
|
HECL::SystemString catalogPath = HECL::ProjectPath(m_gameWorking, "catalog.yaml").getAbsolutePath();
|
||||||
|
FILE* catalog = HECL::Fopen(catalogPath.c_str(), _S("w"));
|
||||||
|
yaml_emitter_set_output_file(catalogWriter.getEmitter(), catalog);
|
||||||
|
catalogWriter.finish();
|
||||||
|
fclose(catalog);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enterPAKBridge(const BRIDGETYPE& pakBridge)
|
void enterPAKBridge(const BRIDGETYPE& pakBridge)
|
||||||
|
@ -347,6 +353,7 @@ public:
|
||||||
++bridgeIdx;
|
++bridgeIdx;
|
||||||
}
|
}
|
||||||
LogDNACommon.report(LogVisor::FatalError, "PAKBridge provided to PAKRouter::enterPAKBridge() was not part of build()");
|
LogDNACommon.report(LogVisor::FatalError, "PAKBridge provided to PAKRouter::enterPAKBridge() was not part of build()");
|
||||||
|
g_PakRouter = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
HECL::ProjectPath getWorking(const EntryType* entry,
|
HECL::ProjectPath getWorking(const EntryType* entry,
|
||||||
|
@ -362,11 +369,11 @@ public:
|
||||||
{
|
{
|
||||||
const HECL::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].first;
|
const HECL::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].first;
|
||||||
pakPath.makeDir();
|
pakPath.makeDir();
|
||||||
#if HECL_UCS2
|
#if HECL_UCS2
|
||||||
HECL::SystemString entName = HECL::UTF8ToWide(m_pak->bestEntryName(*entry));
|
HECL::SystemString entName = HECL::UTF8ToWide(m_pak->bestEntryName(*entry));
|
||||||
#else
|
#else
|
||||||
HECL::SystemString entName = m_pak->bestEntryName(*entry);
|
HECL::SystemString entName = m_pak->bestEntryName(*entry);
|
||||||
#endif
|
#endif
|
||||||
if (extractor.fileExts[0] && !extractor.fileExts[1])
|
if (extractor.fileExts[0] && !extractor.fileExts[1])
|
||||||
entName += extractor.fileExts[0];
|
entName += extractor.fileExts[0];
|
||||||
return HECL::ProjectPath(pakPath, entName);
|
return HECL::ProjectPath(pakPath, entName);
|
||||||
|
@ -393,7 +400,6 @@ public:
|
||||||
if (sharedSearch != m_sharedEntries.end())
|
if (sharedSearch != m_sharedEntries.end())
|
||||||
{
|
{
|
||||||
const HECL::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].first;
|
const HECL::ProjectPath& pakPath = m_bridgePaths[m_curBridgeIdx].first;
|
||||||
HECL::ProjectPath uniquePathPre = entry->unique.uniquePath(pakPath);
|
|
||||||
#if HECL_UCS2
|
#if HECL_UCS2
|
||||||
HECL::SystemString entBase = HECL::UTF8ToWide(m_pak->bestEntryName(*entry));
|
HECL::SystemString entBase = HECL::UTF8ToWide(m_pak->bestEntryName(*entry));
|
||||||
#else
|
#else
|
||||||
|
@ -403,24 +409,6 @@ public:
|
||||||
if (extractor.fileExts[0] && !extractor.fileExts[1])
|
if (extractor.fileExts[0] && !extractor.fileExts[1])
|
||||||
entName += extractor.fileExts[0];
|
entName += extractor.fileExts[0];
|
||||||
HECL::ProjectPath sharedPath(m_sharedWorking, entName);
|
HECL::ProjectPath sharedPath(m_sharedWorking, entName);
|
||||||
HECL::ProjectPath uniquePath(uniquePathPre, entName);
|
|
||||||
if (extractor.func_a || extractor.func_b)
|
|
||||||
{
|
|
||||||
if (extractor.fileExts[0] && !extractor.fileExts[1])
|
|
||||||
uniquePath.makeLinkTo(sharedPath);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int e=0 ; e<4 ; ++e)
|
|
||||||
{
|
|
||||||
if (!extractor.fileExts[e])
|
|
||||||
break;
|
|
||||||
HECL::SystemString entName = entBase + extractor.fileExts[e];
|
|
||||||
HECL::ProjectPath sharedPath(m_sharedWorking, entName);
|
|
||||||
HECL::ProjectPath uniquePath(uniquePathPre, entName);
|
|
||||||
uniquePath.makeLinkTo(sharedPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_sharedWorking.makeDir();
|
m_sharedWorking.makeDir();
|
||||||
return sharedPath;
|
return sharedPath;
|
||||||
}
|
}
|
||||||
|
@ -533,7 +521,7 @@ public:
|
||||||
float thisFac = ++count / fsz;
|
float thisFac = ++count / fsz;
|
||||||
progress(bestNameView.sys_str().c_str(), thisFac);
|
progress(bestNameView.sys_str().c_str(), thisFac);
|
||||||
|
|
||||||
/* TODO: Position after extracted item */
|
/* 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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,7 +60,7 @@ struct SpecBase : HECL::Database::IDataSpec
|
||||||
virtual HECL::ProjectPath getWorking(class UniqueID64&) {return HECL::ProjectPath();}
|
virtual HECL::ProjectPath getWorking(class UniqueID64&) {return HECL::ProjectPath();}
|
||||||
|
|
||||||
/* Project accessor */
|
/* Project accessor */
|
||||||
HECL::Database::Project& getProject() {return m_project;}
|
HECL::Database::Project& getProject() const {return m_project;}
|
||||||
|
|
||||||
SpecBase(HECL::Database::Project& project);
|
SpecBase(HECL::Database::Project& project);
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -19,10 +19,24 @@ ProjectResourceFactory::ProjectResourceFactory()
|
||||||
|
|
||||||
void ProjectResourceFactory::BuildObjectMap(const HECL::Database::Project::ProjectDataSpec &spec)
|
void ProjectResourceFactory::BuildObjectMap(const HECL::Database::Project::ProjectDataSpec &spec)
|
||||||
{
|
{
|
||||||
m_resPaths.clear();
|
m_tagToPath.clear();
|
||||||
m_namedResources.clear();
|
m_catalogNameToTag.clear();
|
||||||
HECL::SystemString catalogPath = HECL::ProjectPath(spec.cookedPath, HECL::SystemString(spec.spec.m_name) + _S("/catalog.yaml")).getAbsolutePath();
|
HECL::SystemString catalogPath = HECL::ProjectPath(spec.cookedPath, HECL::SystemString(spec.spec.m_name) + _S("/catalog.yaml")).getAbsolutePath();
|
||||||
FILE* catalogFile = HECL::Fopen(catalogPath.c_str(), _S("r"));
|
FILE* catalogFile = HECL::Fopen(catalogPath.c_str(), _S("r"));
|
||||||
|
Athena::io::YAMLDocReader reader;
|
||||||
|
yaml_parser_set_input_file(reader.getParser(), catalogFile);
|
||||||
|
reader.parse();
|
||||||
|
const Athena::io::YAMLNode* catalogRoot = reader.getRootNode();
|
||||||
|
if (catalogRoot)
|
||||||
|
{
|
||||||
|
m_catalogNameToPath.reserve(catalogRoot->m_mapChildren.size());
|
||||||
|
for (const std::pair<std::string, std::unique_ptr<Athena::io::YAMLNode>>& ch : catalogRoot->m_mapChildren)
|
||||||
|
{
|
||||||
|
if (ch.second->m_type == YAML_SCALAR_NODE)
|
||||||
|
m_catalogNameToPath[ch.first] = HECL::ProjectPath(spec.cookedPath, HECL::SystemString(ch.second->m_scalarString));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!HECL::StrCmp(spec.spec.m_name, _S("MP3")))
|
if (!HECL::StrCmp(spec.spec.m_name, _S("MP3")))
|
||||||
{
|
{
|
||||||
DataSpec::NamedResourceCatalog<DataSpec::UniqueID64> catalog;
|
DataSpec::NamedResourceCatalog<DataSpec::UniqueID64> catalog;
|
||||||
|
@ -42,8 +56,8 @@ void ProjectResourceFactory::BuildObjectMap(const HECL::Database::Project::Proje
|
||||||
std::unique_ptr<pshag::IObj> ProjectResourceFactory::Build(const pshag::SObjectTag& tag,
|
std::unique_ptr<pshag::IObj> ProjectResourceFactory::Build(const pshag::SObjectTag& tag,
|
||||||
const pshag::CVParamTransfer& paramXfer)
|
const pshag::CVParamTransfer& paramXfer)
|
||||||
{
|
{
|
||||||
auto search = m_resPaths.find(tag);
|
auto search = m_tagToPath.find(tag);
|
||||||
if (search == m_resPaths.end())
|
if (search == m_tagToPath.end())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
fprintf(stderr, "Loading resource %s\n", search->second.getRelativePath().c_str());
|
fprintf(stderr, "Loading resource %s\n", search->second.getRelativePath().c_str());
|
||||||
|
@ -68,8 +82,8 @@ void ProjectResourceFactory::CancelBuild(const pshag::SObjectTag&)
|
||||||
|
|
||||||
bool ProjectResourceFactory::CanBuild(const pshag::SObjectTag& tag)
|
bool ProjectResourceFactory::CanBuild(const pshag::SObjectTag& tag)
|
||||||
{
|
{
|
||||||
auto search = m_resPaths.find(tag);
|
auto search = m_tagToPath.find(tag);
|
||||||
if (search == m_resPaths.end())
|
if (search == m_tagToPath.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Athena::io::FileReader fr(search->second.getAbsolutePath(), 32 * 1024, false);
|
Athena::io::FileReader fr(search->second.getAbsolutePath(), 32 * 1024, false);
|
||||||
|
@ -81,9 +95,9 @@ bool ProjectResourceFactory::CanBuild(const pshag::SObjectTag& tag)
|
||||||
|
|
||||||
const pshag::SObjectTag* ProjectResourceFactory::GetResourceIdByName(const char* name) const
|
const pshag::SObjectTag* ProjectResourceFactory::GetResourceIdByName(const char* name) const
|
||||||
{
|
{
|
||||||
if (m_namedResources.find(name) == m_namedResources.end())
|
if (m_catalogNameToTag.find(name) == m_catalogNameToTag.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
const pshag::SObjectTag& tag = m_namedResources.at(name);
|
const pshag::SObjectTag& tag = m_catalogNameToTag.at(name);
|
||||||
return &tag;
|
return &tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,15 @@
|
||||||
|
|
||||||
#include "Runtime/IFactory.hpp"
|
#include "Runtime/IFactory.hpp"
|
||||||
#include "Runtime/CFactoryMgr.hpp"
|
#include "Runtime/CFactoryMgr.hpp"
|
||||||
#include "DataSpec/DNACommon/NamedResourceCatalog.hpp"
|
|
||||||
|
|
||||||
namespace URDE
|
namespace URDE
|
||||||
{
|
{
|
||||||
|
|
||||||
class ProjectResourceFactory : public pshag::IFactory
|
class ProjectResourceFactory : public pshag::IFactory
|
||||||
{
|
{
|
||||||
std::unordered_map<pshag::SObjectTag, HECL::ProjectPath> m_resPaths;
|
std::unordered_map<pshag::SObjectTag, HECL::ProjectPath> m_tagToPath;
|
||||||
std::unordered_map<std::string, pshag::SObjectTag> m_namedResources;
|
std::unordered_map<std::string, pshag::SObjectTag> m_catalogNameToTag;
|
||||||
|
std::unordered_map<std::string, HECL::ProjectPath> m_catalogNameToPath;
|
||||||
pshag::CFactoryMgr m_factoryMgr;
|
pshag::CFactoryMgr m_factoryMgr;
|
||||||
template <class IDType>
|
template <class IDType>
|
||||||
void RecursiveAddDirObjects(const HECL::ProjectPath& path, const DataSpec::NamedResourceCatalog<IDType>& catalog)
|
void RecursiveAddDirObjects(const HECL::ProjectPath& path, const DataSpec::NamedResourceCatalog<IDType>& catalog)
|
||||||
|
@ -34,8 +34,8 @@ class ProjectResourceFactory : public pshag::IFactory
|
||||||
if (id)
|
if (id)
|
||||||
{
|
{
|
||||||
pshag::SObjectTag objTag = {HECL::FourCC(entu8.c_str()), id};
|
pshag::SObjectTag objTag = {HECL::FourCC(entu8.c_str()), id};
|
||||||
if (m_resPaths.find(objTag) == m_resPaths.end())
|
if (m_tagToPath.find(objTag) == m_tagToPath.end())
|
||||||
m_resPaths[objTag] = HECL::ProjectPath(path, ent.m_name);
|
m_tagToPath[objTag] = HECL::ProjectPath(path, ent.m_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -50,8 +50,8 @@ class ProjectResourceFactory : public pshag::IFactory
|
||||||
const typename DataSpec::NamedResourceCatalog<IDType>::NamedResource& nr = *it;
|
const typename DataSpec::NamedResourceCatalog<IDType>::NamedResource& nr = *it;
|
||||||
pshag::SObjectTag objTag = GetTag<IDType>(nr);
|
pshag::SObjectTag objTag = GetTag<IDType>(nr);
|
||||||
|
|
||||||
m_namedResources[nr.name.c_str()] = objTag;
|
m_catalogNameToTag[nr.name.c_str()] = objTag;
|
||||||
m_resPaths[objTag] = HECL::ProjectPath(path, ent.m_name);
|
m_tagToPath[objTag] = HECL::ProjectPath(path, ent.m_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,17 @@ bool ResourceBrowser::navigateToPath(const HECL::ProjectPath& pathIn)
|
||||||
HECL::DirectoryEnumerator dEnum(m_path.getAbsolutePath(),
|
HECL::DirectoryEnumerator dEnum(m_path.getAbsolutePath(),
|
||||||
HECL::DirectoryEnumerator::Mode::DirsThenFilesSorted,
|
HECL::DirectoryEnumerator::Mode::DirsThenFilesSorted,
|
||||||
m_state.sortColumn==State::SortColumn::Size,
|
m_state.sortColumn==State::SortColumn::Size,
|
||||||
m_state.sortDir==Specter::SortDirection::Descending,
|
m_state.sortDir==Specter::SortDirection::Descending &&
|
||||||
|
(m_state.sortColumn == State::SortColumn::Name || m_state.sortColumn == State::SortColumn::Size),
|
||||||
true);
|
true);
|
||||||
m_fileListingBind.updateListing(dEnum);
|
m_resListingBind.updateListing(dEnum);
|
||||||
if (m_pathButtons)
|
if (m_pathButtons)
|
||||||
m_pathButtons->setButtons(m_comps);
|
m_pathButtons->setButtons(m_comps);
|
||||||
|
|
||||||
if (m_view)
|
if (m_view)
|
||||||
{
|
{
|
||||||
m_view->m_fileListing.m_view->selectRow(-1);
|
m_view->m_resListing.m_view->selectRow(-1);
|
||||||
m_view->m_fileListing.m_view->updateData();
|
m_view->m_resListing.m_view->updateData();
|
||||||
m_view->updateSize();
|
m_view->updateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,32 +56,32 @@ void ResourceBrowser::pathButtonActivated(size_t idx)
|
||||||
|
|
||||||
void ResourceBrowser::View::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
void ResourceBrowser::View::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||||
{
|
{
|
||||||
m_fileListing.mouseDown(coord, button, mod);
|
m_resListing.mouseDown(coord, button, mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceBrowser::View::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
void ResourceBrowser::View::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||||
{
|
{
|
||||||
m_fileListing.mouseUp(coord, button, mod);
|
m_resListing.mouseUp(coord, button, mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceBrowser::View::mouseMove(const boo::SWindowCoord& coord)
|
void ResourceBrowser::View::mouseMove(const boo::SWindowCoord& coord)
|
||||||
{
|
{
|
||||||
m_fileListing.mouseMove(coord);
|
m_resListing.mouseMove(coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceBrowser::View::mouseLeave(const boo::SWindowCoord& coord)
|
void ResourceBrowser::View::mouseLeave(const boo::SWindowCoord& coord)
|
||||||
{
|
{
|
||||||
m_fileListing.mouseLeave(coord);
|
m_resListing.mouseLeave(coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceBrowser::View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
void ResourceBrowser::View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||||
{
|
{
|
||||||
Specter::View::resized(root, sub);
|
Specter::View::resized(root, sub);
|
||||||
m_fileListing.m_view->resized(root, sub);
|
m_resListing.m_view->resized(root, sub);
|
||||||
}
|
}
|
||||||
void ResourceBrowser::View::draw(boo::IGraphicsCommandQueue* gfxQ)
|
void ResourceBrowser::View::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||||
{
|
{
|
||||||
m_fileListing.m_view->draw(gfxQ);
|
m_resListing.m_view->draw(gfxQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,7 @@ class ResourceBrowser : public Space, public Specter::IPathButtonsBinding
|
||||||
void setSort(size_t cIdx, Specter::SortDirection dir)
|
void setSort(size_t cIdx, Specter::SortDirection dir)
|
||||||
{
|
{
|
||||||
m_rb.m_state.sortDir = dir;
|
m_rb.m_state.sortDir = dir;
|
||||||
|
m_rb.m_state.sortColumn = State::SortColumn(cIdx);
|
||||||
m_needsUpdate = true;
|
m_needsUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,18 +163,18 @@ class ResourceBrowser : public Space, public Specter::IPathButtonsBinding
|
||||||
m_fileStr = vm.translateOr("file", "File");
|
m_fileStr = vm.translateOr("file", "File");
|
||||||
}
|
}
|
||||||
|
|
||||||
} m_fileListingBind;
|
} m_resListingBind;
|
||||||
|
|
||||||
struct View : Specter::View
|
struct View : Specter::View
|
||||||
{
|
{
|
||||||
ResourceBrowser& m_ro;
|
ResourceBrowser& m_ro;
|
||||||
Specter::ViewChild<std::unique_ptr<Specter::Table>> m_fileListing;
|
Specter::ViewChild<std::unique_ptr<Specter::Table>> m_resListing;
|
||||||
|
|
||||||
View(ResourceBrowser& ro, Specter::ViewResources& res)
|
View(ResourceBrowser& ro, Specter::ViewResources& res)
|
||||||
: Specter::View(res, ro.m_vm.rootView()), m_ro(ro)
|
: Specter::View(res, ro.m_vm.rootView()), m_ro(ro)
|
||||||
{
|
{
|
||||||
commitResources(res);
|
commitResources(res);
|
||||||
m_fileListing.m_view.reset(new Specter::Table(res, *this, &ro.m_fileListingBind, &ro.m_fileListingBind, 3));
|
m_resListing.m_view.reset(new Specter::Table(res, *this, &ro.m_resListingBind, &ro.m_resListingBind, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||||
|
@ -191,7 +192,7 @@ class ResourceBrowser : public Space, public Specter::IPathButtonsBinding
|
||||||
public:
|
public:
|
||||||
ResourceBrowser(ViewManager& vm, Space* parent)
|
ResourceBrowser(ViewManager& vm, Space* parent)
|
||||||
: Space(vm, Class::ResourceBrowser, parent),
|
: Space(vm, Class::ResourceBrowser, parent),
|
||||||
m_fileListingBind(*this, vm)
|
m_resListingBind(*this, vm)
|
||||||
{
|
{
|
||||||
reloadState();
|
reloadState();
|
||||||
}
|
}
|
||||||
|
@ -220,6 +221,12 @@ public:
|
||||||
navigateToPath(pp);
|
navigateToPath(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void think()
|
||||||
|
{
|
||||||
|
if (m_resListingBind.m_needsUpdate)
|
||||||
|
reloadState();
|
||||||
|
}
|
||||||
|
|
||||||
bool navigateToPath(const HECL::ProjectPath& path);
|
bool navigateToPath(const HECL::ProjectPath& path);
|
||||||
|
|
||||||
Space* copy(Space* parent) const
|
Space* copy(Space* parent) const
|
||||||
|
@ -230,7 +237,8 @@ public:
|
||||||
void buildToolbarView(Specter::ViewResources &res, Specter::Toolbar &tb)
|
void buildToolbarView(Specter::ViewResources &res, Specter::Toolbar &tb)
|
||||||
{
|
{
|
||||||
m_pathButtons.reset(new Specter::PathButtons(res, tb, *this, true));
|
m_pathButtons.reset(new Specter::PathButtons(res, tb, *this, true));
|
||||||
tb.push_back(m_pathButtons.get(), 0);
|
tb.push_back(m_pathButtons.get(), 1);
|
||||||
|
reloadState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Specter::View* buildContentView(Specter::ViewResources& res)
|
Specter::View* buildContentView(Specter::ViewResources& res)
|
||||||
|
|
|
@ -181,6 +181,12 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void think()
|
||||||
|
{
|
||||||
|
if (m_spaceTree)
|
||||||
|
m_spaceTree->think();
|
||||||
|
}
|
||||||
|
|
||||||
void saveState(Athena::io::IStreamWriter& w) const
|
void saveState(Athena::io::IStreamWriter& w) const
|
||||||
{
|
{
|
||||||
w.writeUint32Big(atUint32(m_class));
|
w.writeUint32Big(atUint32(m_class));
|
||||||
|
@ -272,6 +278,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void think()
|
||||||
|
{
|
||||||
|
if (m_slots[0])
|
||||||
|
m_slots[0]->think();
|
||||||
|
if (m_slots[1])
|
||||||
|
m_slots[1]->think();
|
||||||
|
}
|
||||||
|
|
||||||
void saveState(Athena::io::IStreamWriter& w) const
|
void saveState(Athena::io::IStreamWriter& w) const
|
||||||
{
|
{
|
||||||
w.writeUint32Big(atUint32(m_class));
|
w.writeUint32Big(atUint32(m_class));
|
||||||
|
@ -360,6 +374,13 @@ public:
|
||||||
: Space(vm, cls, parent) {}
|
: Space(vm, cls, parent) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GameSpace : public Space
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GameSpace(ViewManager& vm, Class cls, Space* parent)
|
||||||
|
: Space(vm, cls, parent) {}
|
||||||
|
};
|
||||||
|
|
||||||
class TestSpace : public Space
|
class TestSpace : public Space
|
||||||
{
|
{
|
||||||
std::unique_ptr<Specter::Button> m_button;
|
std::unique_ptr<Specter::Button> m_button;
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit d7ba6810af60bccd41d42d1c06112c2f414b3f98
|
Subproject commit 82333be06ce889bdb78986ba0137f17832366c45
|
|
@ -1 +1 @@
|
||||||
Subproject commit c34050a3bb9a5c55cb26636d75e7d820d589e6a3
|
Subproject commit a7c11c72d2d97e680b0f595fa57649545cc53d13
|
Loading…
Reference in New Issue