Resource factories now provided with self-ref

This commit is contained in:
Jack Andersen 2016-09-02 09:32:57 -10:00
parent 6dff9b241a
commit f4ea728a61
43 changed files with 201 additions and 135 deletions

View File

@ -335,7 +335,8 @@ bool ProjectResourceFactoryBase::SyncCook(const hecl::ProjectPath& working)
CFactoryFnReturn ProjectResourceFactoryBase::BuildSync(const SObjectTag& tag, CFactoryFnReturn ProjectResourceFactoryBase::BuildSync(const SObjectTag& tag,
const hecl::ProjectPath& path, const hecl::ProjectPath& path,
const CVParamTransfer& paramXfer) const CVParamTransfer& paramXfer,
CObjectReference* selfRef)
{ {
/* Ensure cooked rep is on the filesystem */ /* Ensure cooked rep is on the filesystem */
std::experimental::optional<athena::io::FileReader> fr; std::experimental::optional<athena::io::FileReader> fr;
@ -347,10 +348,10 @@ CFactoryFnReturn ProjectResourceFactoryBase::BuildSync(const SObjectTag& tag,
{ {
u32 length = fr->length(); u32 length = fr->length();
std::unique_ptr<u8[]> memBuf = fr->readUBytes(length); std::unique_ptr<u8[]> memBuf = fr->readUBytes(length);
return m_factoryMgr.MakeObjectFromMemory(tag, std::move(memBuf), length, false, paramXfer); return m_factoryMgr.MakeObjectFromMemory(tag, std::move(memBuf), length, false, paramXfer, selfRef);
} }
return m_factoryMgr.MakeObject(tag, *fr, paramXfer); return m_factoryMgr.MakeObject(tag, *fr, paramXfer, selfRef);
} }
void ProjectResourceFactoryBase::AsyncTask::EnsurePath(const urde::SObjectTag& tag, void ProjectResourceFactoryBase::AsyncTask::EnsurePath(const urde::SObjectTag& tag,
@ -518,7 +519,8 @@ ProjectResourceFactoryBase::PrepForReadSync(const SObjectTag& tag,
} }
std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjectTag& tag, std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjectTag& tag,
const urde::CVParamTransfer& paramXfer) const urde::CVParamTransfer& paramXfer,
CObjectReference* selfRef)
{ {
const hecl::ProjectPath* resPath = nullptr; const hecl::ProjectPath* resPath = nullptr;
if (!WaitForTagReady(tag, resPath)) if (!WaitForTagReady(tag, resPath))
@ -540,12 +542,12 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
if (m_factoryMgr.CanMakeMemory(task.x0_tag)) if (m_factoryMgr.CanMakeMemory(task.x0_tag))
{ {
newObj = m_factoryMgr.MakeObjectFromMemory(tag, std::move(task.x10_loadBuffer), newObj = m_factoryMgr.MakeObjectFromMemory(tag, std::move(task.x10_loadBuffer),
task.x14_resSize, false, task.x18_cvXfer); task.x14_resSize, false, task.x18_cvXfer, selfRef);
} }
else else
{ {
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize); athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer); newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, selfRef);
} }
*task.xc_targetObjPtr = newObj.get(); *task.xc_targetObjPtr = newObj.get();
@ -564,24 +566,26 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
} }
/* Fall-back to sync build */ /* Fall-back to sync build */
return BuildSync(tag, *resPath, paramXfer); return BuildSync(tag, *resPath, paramXfer, selfRef);
} }
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask> std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag, ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag,
const urde::CVParamTransfer& paramXfer, const urde::CVParamTransfer& paramXfer,
urde::IObj** objOut) urde::IObj** objOut,
CObjectReference* selfRef)
{ {
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end()) if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
return {}; return {};
return m_asyncLoadList.emplace(std::make_pair(tag, std::make_unique<AsyncTask>(*this, tag, objOut, paramXfer))).first->second; return m_asyncLoadList.emplace(std::make_pair(tag, std::make_unique<AsyncTask>(*this, tag, objOut, paramXfer, selfRef))).first->second;
} }
void ProjectResourceFactoryBase::BuildAsync(const urde::SObjectTag& tag, void ProjectResourceFactoryBase::BuildAsync(const urde::SObjectTag& tag,
const urde::CVParamTransfer& paramXfer, const urde::CVParamTransfer& paramXfer,
urde::IObj** objOut) urde::IObj** objOut,
CObjectReference* selfRef)
{ {
BuildAsyncInternal(tag, paramXfer, objOut); BuildAsyncInternal(tag, paramXfer, objOut, selfRef);
} }
u32 ProjectResourceFactoryBase::ResourceSize(const SObjectTag& tag) u32 ProjectResourceFactoryBase::ResourceSize(const SObjectTag& tag)
@ -765,12 +769,13 @@ void ProjectResourceFactoryBase::AsyncIdle()
if (m_factoryMgr.CanMakeMemory(task.x0_tag)) if (m_factoryMgr.CanMakeMemory(task.x0_tag))
{ {
newObj = m_factoryMgr.MakeObjectFromMemory(task.x0_tag, std::move(task.x10_loadBuffer), newObj = m_factoryMgr.MakeObjectFromMemory(task.x0_tag, std::move(task.x10_loadBuffer),
task.x14_resSize, false, task.x18_cvXfer); task.x14_resSize, false, task.x18_cvXfer,
task.m_selfRef);
} }
else else
{ {
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize); athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer); newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, task.m_selfRef);
} }
*task.xc_targetObjPtr = newObj.release(); *task.xc_targetObjPtr = newObj.release();

View File

@ -32,6 +32,7 @@ public:
u32 x14_resSize = UINT32_MAX; u32 x14_resSize = UINT32_MAX;
u32 x14_resOffset = 0; u32 x14_resOffset = 0;
CVParamTransfer x18_cvXfer; CVParamTransfer x18_cvXfer;
CObjectReference* m_selfRef = nullptr;
hecl::ProjectPath m_workingPath; hecl::ProjectPath m_workingPath;
hecl::ProjectPath m_cookedPath; hecl::ProjectPath m_cookedPath;
@ -50,8 +51,8 @@ public:
x14_resOffset(off) {} x14_resOffset(off) {}
AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag, AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag,
IObj** ptr, const CVParamTransfer& xfer) IObj** ptr, const CVParamTransfer& xfer, CObjectReference* selfRef)
: m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer) {} : m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer), m_selfRef(selfRef) {}
void EnsurePath(const urde::SObjectTag& tag, void EnsurePath(const urde::SObjectTag& tag,
const hecl::ProjectPath& path); const hecl::ProjectPath& path);
@ -104,13 +105,13 @@ protected:
hecl::ProjectPath GetCookedPath(const hecl::ProjectPath& working, bool pcTarget) const; hecl::ProjectPath GetCookedPath(const hecl::ProjectPath& working, bool pcTarget) const;
bool SyncCook(const hecl::ProjectPath& working); bool SyncCook(const hecl::ProjectPath& working);
CFactoryFnReturn BuildSync(const SObjectTag& tag, const hecl::ProjectPath& path, CFactoryFnReturn BuildSync(const SObjectTag& tag, const hecl::ProjectPath& path,
const CVParamTransfer& paramXfer); const CVParamTransfer& paramXfer, CObjectReference* selfRef);
public: public:
ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {} ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {}
std::unique_ptr<urde::IObj> Build(const urde::SObjectTag&, const urde::CVParamTransfer&); std::unique_ptr<urde::IObj> Build(const urde::SObjectTag&, const urde::CVParamTransfer&, CObjectReference* selfRef);
void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**); void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**, CObjectReference* selfRef);
std::shared_ptr<AsyncTask> BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**); std::shared_ptr<AsyncTask> BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**, CObjectReference* selfRef);
void CancelBuild(const urde::SObjectTag&); void CancelBuild(const urde::SObjectTag&);
bool CanBuild(const urde::SObjectTag&); bool CanBuild(const urde::SObjectTag&);
const urde::SObjectTag* GetResourceIdByName(const char*) const; const urde::SObjectTag* GetResourceIdByName(const char*) const;

View File

@ -31,7 +31,8 @@ CAudioGroupSet::CAudioGroupSet(std::unique_ptr<u8[]>&& in)
CFactoryFnReturn FAudioGroupSetDataFactory(const urde::SObjectTag& tag, CFactoryFnReturn FAudioGroupSetDataFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len, std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms) const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)
{ {
return TToken<CAudioGroupSet>::GetIObjObjectFor(std::make_unique<CAudioGroupSet>(std::move(in))); return TToken<CAudioGroupSet>::GetIObjObjectFor(std::make_unique<CAudioGroupSet>(std::move(in)));
} }

View File

@ -25,7 +25,8 @@ public:
CFactoryFnReturn FAudioGroupSetDataFactory(const urde::SObjectTag& tag, CFactoryFnReturn FAudioGroupSetDataFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len, std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms); const urde::CVParamTransfer& vparms,
CObjectReference* selfRef);
} }

View File

@ -16,7 +16,8 @@ void CDependencyGroup::ReadFromStream(CInputStream& in)
x0_objectTags.emplace_back(in); x0_objectTags.emplace_back(in);
} }
CFactoryFnReturn FDependencyGroupFactory(const SObjectTag& /*tag*/, CInputStream& in, const CVParamTransfer& /*param*/) CFactoryFnReturn FDependencyGroupFactory(const SObjectTag& /*tag*/, CInputStream& in, const CVParamTransfer& /*param*/,
CObjectReference* selfRef)
{ {
return TToken<CDependencyGroup>::GetIObjObjectFor(std::unique_ptr<CDependencyGroup>(new CDependencyGroup(in))); return TToken<CDependencyGroup>::GetIObjObjectFor(std::unique_ptr<CDependencyGroup>(new CDependencyGroup(in)));
} }

View File

@ -14,7 +14,8 @@ public:
std::vector<SObjectTag> GetObjectTagVector() const { return x0_objectTags; } std::vector<SObjectTag> GetObjectTagVector() const { return x0_objectTags; }
}; };
CFactoryFnReturn FDependencyGroupFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param); CFactoryFnReturn FDependencyGroupFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param,
CObjectReference* selfRef);
} }
#endif // CDEPENDENCYGROUP_HPP #endif // CDEPENDENCYGROUP_HPP

View File

@ -5,13 +5,13 @@ namespace urde
{ {
CFactoryFnReturn CFactoryMgr::MakeObject(const SObjectTag& tag, urde::CInputStream& in, CFactoryFnReturn CFactoryMgr::MakeObject(const SObjectTag& tag, urde::CInputStream& in,
const CVParamTransfer& paramXfer) const CVParamTransfer& paramXfer, CObjectReference* selfRef)
{ {
auto search = m_factories.find(tag.type); auto search = m_factories.find(tag.type);
if (search == m_factories.end()) if (search == m_factories.end())
return {}; return {};
return search->second(tag, in, paramXfer); return search->second(tag, in, paramXfer, selfRef);
} }
bool CFactoryMgr::CanMakeMemory(const urde::SObjectTag& tag) const bool CFactoryMgr::CanMakeMemory(const urde::SObjectTag& tag) const
@ -21,7 +21,8 @@ bool CFactoryMgr::CanMakeMemory(const urde::SObjectTag& tag) const
} }
CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, std::unique_ptr<u8[]>&& buf, int size, CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, std::unique_ptr<u8[]>&& buf, int size,
bool compressed, const CVParamTransfer& paramXfer) bool compressed, const CVParamTransfer& paramXfer,
CObjectReference* selfRef)
{ {
std::unique_ptr<u8[]> localBuf = std::move(buf); std::unique_ptr<u8[]> localBuf = std::move(buf);
@ -35,11 +36,11 @@ CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, std::u
u32 decompLen = compRead->readUint32Big(); u32 decompLen = compRead->readUint32Big();
CZipInputStream r(std::move(compRead)); CZipInputStream r(std::move(compRead));
std::unique_ptr<u8[]> decompBuf = r.readUBytes(decompLen); std::unique_ptr<u8[]> decompBuf = r.readUBytes(decompLen);
return search->second(tag, std::move(decompBuf), decompLen, paramXfer); return search->second(tag, std::move(decompBuf), decompLen, paramXfer, selfRef);
} }
else else
{ {
return search->second(tag, std::move(localBuf), size, paramXfer); return search->second(tag, std::move(localBuf), size, paramXfer, selfRef);
} }
} }
else else
@ -54,12 +55,12 @@ CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, std::u
std::make_unique<athena::io::MemoryReader>(localBuf.get(), size); std::make_unique<athena::io::MemoryReader>(localBuf.get(), size);
u32 decompLen = compRead->readUint32Big(); u32 decompLen = compRead->readUint32Big();
CZipInputStream r(std::move(compRead)); CZipInputStream r(std::move(compRead));
return search->second(tag, r, paramXfer); return search->second(tag, r, paramXfer, selfRef);
} }
else else
{ {
CMemoryInStream r(localBuf.get(), size); CMemoryInStream r(localBuf.get(), size);
return search->second(tag, r, paramXfer); return search->second(tag, r, paramXfer, selfRef);
} }
} }
} }

View File

@ -18,12 +18,13 @@ class CFactoryMgr
std::unordered_map<FourCC, FMemFactoryFunc> m_memFactories; std::unordered_map<FourCC, FMemFactoryFunc> m_memFactories;
public: public:
CFactoryFnReturn MakeObject(const SObjectTag& tag, urde::CInputStream& in, CFactoryFnReturn MakeObject(const SObjectTag& tag, urde::CInputStream& in,
const CVParamTransfer& paramXfer); const CVParamTransfer& paramXfer, CObjectReference* selfRef);
bool CanMakeMemory(const urde::SObjectTag& tag) const; bool CanMakeMemory(const urde::SObjectTag& tag) const;
CFactoryFnReturn MakeObjectFromMemory(const SObjectTag& tag, CFactoryFnReturn MakeObjectFromMemory(const SObjectTag& tag,
std::unique_ptr<u8[]>&& buf, std::unique_ptr<u8[]>&& buf,
int size, bool compressed, int size, bool compressed,
const CVParamTransfer& paramXfer); const CVParamTransfer& paramXfer,
CObjectReference* selfRef);
void AddFactory(FourCC key, FFactoryFunc func) {m_factories[key] = func;} void AddFactory(FourCC key, FFactoryFunc func) {m_factories[key] = func;}
void AddFactory(FourCC key, FMemFactoryFunc func) {m_memFactories[key] = func;} void AddFactory(FourCC key, FMemFactoryFunc func) {m_memFactories[key] = func;}
}; };

View File

@ -74,7 +74,7 @@ class CObjectReference
if (!x10_object && !x3_loading) if (!x10_object && !x3_loading)
{ {
IFactory& fac = xC_objectStore->GetFactory(); IFactory& fac = xC_objectStore->GetFactory();
fac.BuildAsync(x4_objTag, x14_params, &x10_object); fac.BuildAsync(x4_objTag, x14_params, &x10_object, this);
x3_loading = true; x3_loading = true;
} }
} }
@ -102,7 +102,7 @@ class CObjectReference
if (!x10_object) if (!x10_object)
{ {
IFactory& factory = xC_objectStore->GetFactory(); IFactory& factory = xC_objectStore->GetFactory();
x10_object = factory.Build(x4_objTag, x14_params).release(); x10_object = factory.Build(x4_objTag, x14_params, this).release();
} }
x3_loading = false; x3_loading = false;
return x10_object; return x10_object;
@ -128,6 +128,7 @@ public:
class CToken class CToken
{ {
friend class CSimplePool; friend class CSimplePool;
friend class CModel;
CObjectReference* x0_objRef = nullptr; CObjectReference* x0_objRef = nullptr;
bool x4_lockHeld = false; bool x4_lockHeld = false;

View File

@ -69,7 +69,8 @@ CAllFormatsAnimSource::CAllFormatsAnimSource(CInputStream& in,
: CAnimFormatUnion(in, store), x74_tag(tag) {} : CAnimFormatUnion(in, store), x74_tag(tag) {}
CFactoryFnReturn AnimSourceFactory(const SObjectTag& tag, CInputStream& in, CFactoryFnReturn AnimSourceFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& params) const CVParamTransfer& params,
CObjectReference* selfRef)
{ {
CSimplePool* sp = static_cast<CSimplePool*>( CSimplePool* sp = static_cast<CSimplePool*>(
static_cast<TObjOwnerParam<IObjectStore*>*>( static_cast<TObjOwnerParam<IObjectStore*>*>(

View File

@ -47,7 +47,8 @@ public:
const CCharAnimTime& startTime); const CCharAnimTime& startTime);
}; };
CFactoryFnReturn AnimSourceFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params); CFactoryFnReturn AnimSourceFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
CObjectReference* selfRef);
} }

View File

@ -7,7 +7,8 @@ namespace urde
CAnimCharacterSet::CAnimCharacterSet(CInputStream& in) CAnimCharacterSet::CAnimCharacterSet(CInputStream& in)
: x0_version(in.readUint16Big()), x4_characterSet(in), x1c_animationSet(in) {} : x0_version(in.readUint16Big()), x4_characterSet(in), x1c_animationSet(in) {}
CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream& in, const CVParamTransfer&) CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream& in, const CVParamTransfer&,
CObjectReference* selfRef)
{ {
return TToken<CAnimCharacterSet>::GetIObjObjectFor(std::make_unique<CAnimCharacterSet>(in)); return TToken<CAnimCharacterSet>::GetIObjObjectFor(std::make_unique<CAnimCharacterSet>(in));
} }

View File

@ -19,7 +19,8 @@ public:
const CAnimationSet& GetAnimationSet() const {return x1c_animationSet;} const CAnimationSet& GetAnimationSet() const {return x1c_animationSet;}
}; };
CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream&, const CVParamTransfer&); CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream&, const CVParamTransfer&,
CObjectReference* selfRef);
} }

View File

@ -32,7 +32,8 @@ CAnimPOIData::CAnimPOIData(CInputStream& in)
} }
CFactoryFnReturn AnimPOIDataFactory(const SObjectTag& tag, CInputStream& in, CFactoryFnReturn AnimPOIDataFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& parms) const CVParamTransfer& parms,
CObjectReference* selfRef)
{ {
return TToken<CAnimPOIData>::GetIObjObjectFor(std::make_unique<CAnimPOIData>(in)); return TToken<CAnimPOIData>::GetIObjObjectFor(std::make_unique<CAnimPOIData>(in));
} }

View File

@ -27,7 +27,8 @@ public:
}; };
CFactoryFnReturn AnimPOIDataFactory(const SObjectTag& tag, CInputStream& in, CFactoryFnReturn AnimPOIDataFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& parms); const CVParamTransfer& parms,
CObjectReference* selfRef);
} }

View File

@ -9,7 +9,8 @@ namespace urde
{ {
CFactoryFnReturn CCharacterFactoryBuilder::CDummyFactory::Build(const SObjectTag& tag, CFactoryFnReturn CCharacterFactoryBuilder::CDummyFactory::Build(const SObjectTag& tag,
const CVParamTransfer&) const CVParamTransfer&,
CObjectReference* selfRef)
{ {
TLockedToken<CAnimCharacterSet> ancs = TLockedToken<CAnimCharacterSet> ancs =
g_SimplePool->GetObj({SBIG('ANCS'), tag.id}); g_SimplePool->GetObj({SBIG('ANCS'), tag.id});
@ -19,9 +20,10 @@ CFactoryFnReturn CCharacterFactoryBuilder::CDummyFactory::Build(const SObjectTag
void CCharacterFactoryBuilder::CDummyFactory::BuildAsync(const SObjectTag& tag, void CCharacterFactoryBuilder::CDummyFactory::BuildAsync(const SObjectTag& tag,
const CVParamTransfer& parms, const CVParamTransfer& parms,
IObj** objOut) IObj** objOut,
CObjectReference* selfRef)
{ {
*objOut = Build(tag, parms).release(); *objOut = Build(tag, parms, selfRef).release();
} }
void CCharacterFactoryBuilder::CDummyFactory::CancelBuild(const SObjectTag&) void CCharacterFactoryBuilder::CDummyFactory::CancelBuild(const SObjectTag&)

View File

@ -17,8 +17,8 @@ public:
class CDummyFactory : public IFactory class CDummyFactory : public IFactory
{ {
public: public:
CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&); CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef);
void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**); void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**, CObjectReference* selfRef);
void CancelBuild(const SObjectTag&); void CancelBuild(const SObjectTag&);
bool CanBuild(const SObjectTag&); bool CanBuild(const SObjectTag&);
const SObjectTag* GetResourceIdByName(const char*) const; const SObjectTag* GetResourceIdByName(const char*) const;

View File

@ -50,7 +50,8 @@ CCharLayoutInfo::CCharLayoutInfo(CInputStream& in)
} }
} }
CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream& in, const CVParamTransfer&) CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream& in, const CVParamTransfer&,
CObjectReference* selfRef)
{ {
return TToken<CCharLayoutInfo>::GetIObjObjectFor(std::make_unique<CCharLayoutInfo>(in)); return TToken<CCharLayoutInfo>::GetIObjObjectFor(std::make_unique<CCharLayoutInfo>(in));
} }

View File

@ -39,7 +39,8 @@ public:
zeus::CVector3f GetFromParentUnrotated(const CSegId& id) const; zeus::CVector3f GetFromParentUnrotated(const CSegId& id) const;
}; };
CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream&, const CVParamTransfer&); CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream&, const CVParamTransfer&,
CObjectReference* selfRef);
} }

View File

@ -18,7 +18,8 @@ namespace urde
{ {
CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag, CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag,
const CVParamTransfer& params) const CVParamTransfer& params,
CObjectReference* selfRef)
{ {
const CCharacterInfo& charInfo = const CCharacterInfo& charInfo =
@ -49,9 +50,10 @@ CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag,
void CCharacterFactory::CDummyFactory::BuildAsync(const SObjectTag& tag, void CCharacterFactory::CDummyFactory::BuildAsync(const SObjectTag& tag,
const CVParamTransfer& parms, const CVParamTransfer& parms,
IObj** objOut) IObj** objOut,
CObjectReference* selfRef)
{ {
*objOut = Build(tag, parms).release(); *objOut = Build(tag, parms, selfRef).release();
} }
void CCharacterFactory::CDummyFactory::CancelBuild(const SObjectTag&) void CCharacterFactory::CDummyFactory::CancelBuild(const SObjectTag&)

View File

@ -26,8 +26,8 @@ public:
class CDummyFactory : public IFactory class CDummyFactory : public IFactory
{ {
public: public:
CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&); CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef);
void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**); void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**, CObjectReference* selfRef);
void CancelBuild(const SObjectTag&); void CancelBuild(const SObjectTag&);
bool CanBuild(const SObjectTag&); bool CanBuild(const SObjectTag&);
const SObjectTag* GetResourceIdByName(const char*) const; const SObjectTag* GetResourceIdByName(const char*) const;

View File

@ -29,6 +29,7 @@ CModelData::CModelData(const CStaticRes& res)
x1c_normalModel = g_SimplePool->GetObj({SBIG('CMDL'), res.GetId()}); x1c_normalModel = g_SimplePool->GetObj({SBIG('CMDL'), res.GetId()});
if (!x1c_normalModel) if (!x1c_normalModel)
Log.report(logvisor::Fatal, "unable to find CMDL %08X", res.GetId()); Log.report(logvisor::Fatal, "unable to find CMDL %08X", res.GetId());
m_normalModelInst = x1c_normalModel->MakeNewInstance(0);
} }
CModelData::CModelData(const CAnimRes& res) CModelData::CModelData(const CAnimRes& res)
@ -82,20 +83,20 @@ CSkinnedModel& CModelData::PickAnimatedModel(EWhichModel which) const
return *x10_animData->xd8_modelData.GetObj(); return *x10_animData->xd8_modelData.GetObj();
} }
TLockedToken<CModel>& CModelData::PickStaticModel(EWhichModel which) std::unique_ptr<CBooModel>& CModelData::PickStaticModel(EWhichModel which)
{ {
TLockedToken<CModel>* ret = nullptr; std::unique_ptr<CBooModel>* ret = nullptr;
switch (which) switch (which)
{ {
case EWhichModel::XRay: case EWhichModel::XRay:
ret = &x2c_xrayModel; ret = &m_xrayModelInst;
case EWhichModel::Thermal: case EWhichModel::Thermal:
ret = &x3c_infraModel; ret = &m_infraModelInst;
default: break; default: break;
} }
if (ret) if (ret)
return *ret; return *ret;
return x1c_normalModel; return m_normalModelInst;
} }
void CModelData::SetXRayModel(const std::pair<ResId, ResId>& modelSkin) void CModelData::SetXRayModel(const std::pair<ResId, ResId>& modelSkin)
@ -113,6 +114,9 @@ void CModelData::SetXRayModel(const std::pair<ResId, ResId>& modelSkin)
else else
{ {
x2c_xrayModel = g_SimplePool->GetObj({SBIG('CMDL'), modelSkin.first}); x2c_xrayModel = g_SimplePool->GetObj({SBIG('CMDL'), modelSkin.first});
if (!x2c_xrayModel)
Log.report(logvisor::Fatal, "unable to find CMDL %08X", modelSkin.first);
m_xrayModelInst = x2c_xrayModel->MakeNewInstance(0);
} }
} }
} }
@ -133,6 +137,9 @@ void CModelData::SetInfraModel(const std::pair<ResId, ResId>& modelSkin)
else else
{ {
x3c_infraModel = g_SimplePool->GetObj({SBIG('CMDL'), modelSkin.first}); x3c_infraModel = g_SimplePool->GetObj({SBIG('CMDL'), modelSkin.first});
if (!x3c_infraModel)
Log.report(logvisor::Fatal, "unable to find CMDL %08X", modelSkin.first);
m_infraModelInst = x3c_infraModel->MakeNewInstance(0);
} }
} }
} }
@ -143,12 +150,12 @@ bool CModelData::IsDefinitelyOpaque(EWhichModel which)
if (x10_animData) if (x10_animData)
{ {
CSkinnedModel& model = PickAnimatedModel(which); CSkinnedModel& model = PickAnimatedModel(which);
return model.GetModel()->GetInstance().IsOpaque(); return model.GetModelInst()->IsOpaque();
} }
else else
{ {
TLockedToken<CModel>& model = PickStaticModel(which); std::unique_ptr<CBooModel>& model = PickStaticModel(which);
return model->GetInstance().IsOpaque(); return model->IsOpaque();
} }
} }
@ -301,8 +308,8 @@ void CModelData::RenderThermal(const zeus::CTransform& xf,
} }
else else
{ {
TLockedToken<CModel>& model = PickStaticModel(EWhichModel::Thermal); std::unique_ptr<CBooModel>& model = PickStaticModel(EWhichModel::Thermal);
model->Draw(drawFlags); model->Draw(drawFlags, nullptr, nullptr);
} }
} }
@ -318,13 +325,13 @@ void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform&
CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_particleScale)); CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_particleScale));
TLockedToken<CModel>& model = PickStaticModel(which); std::unique_ptr<CBooModel>& model = PickStaticModel(which);
if (lights) if (lights)
lights->ActivateLights(model->GetInstance()); lights->ActivateLights(*model);
else else
model->GetInstance().ActivateLights({}); model->ActivateLights({});
model->DrawUnsortedParts(drawFlags); model->DrawNormal(drawFlags, nullptr, nullptr);
// Set ambient to white // Set ambient to white
CGraphics::DisableAllLights(); CGraphics::DisableAllLights();
const_cast<CModelData*>(this)->x14_24_renderSorted = true; const_cast<CModelData*>(this)->x14_24_renderSorted = true;
@ -346,24 +353,24 @@ void CModelData::Render(EWhichModel which, const zeus::CTransform& xf,
{ {
CSkinnedModel& model = PickAnimatedModel(which); CSkinnedModel& model = PickAnimatedModel(which);
if (lights) if (lights)
lights->ActivateLights(model.GetModel()->GetInstance()); lights->ActivateLights(*model.GetModelInst());
else else
model.GetModel()->GetInstance().ActivateLights({}); model.GetModelInst()->ActivateLights({});
x10_animData->Render(model, drawFlags, {}, nullptr); x10_animData->Render(model, drawFlags, {}, nullptr);
} }
else else
{ {
TLockedToken<CModel>& model = PickStaticModel(which); std::unique_ptr<CBooModel>& model = PickStaticModel(which);
if (lights) if (lights)
lights->ActivateLights(model->GetInstance()); lights->ActivateLights(*model);
else else
model->GetInstance().ActivateLights({}); model->ActivateLights({});
if (x14_24_renderSorted) if (x14_24_renderSorted)
model->DrawSortedParts(drawFlags); model->DrawAlpha(drawFlags, nullptr, nullptr);
else else
model->Draw(drawFlags); model->Draw(drawFlags, nullptr, nullptr);
} }
// Set ambient to white // Set ambient to white

View File

@ -7,6 +7,7 @@
#include "RetroTypes.hpp" #include "RetroTypes.hpp"
#include "CToken.hpp" #include "CToken.hpp"
#include "CAnimData.hpp" #include "CAnimData.hpp"
#include "Graphics/CModel.hpp"
namespace urde namespace urde
{ {
@ -78,10 +79,15 @@ class CModelData
u32 _flags = 0; u32 _flags = 0;
}; };
zeus::CColor x18_ambientColor; zeus::CColor x18_ambientColor;
TLockedToken<CModel> x1c_normalModel; TLockedToken<CModel> x1c_normalModel;
TLockedToken<CModel> x2c_xrayModel; TLockedToken<CModel> x2c_xrayModel;
TLockedToken<CModel> x3c_infraModel; TLockedToken<CModel> x3c_infraModel;
std::unique_ptr<CBooModel> m_normalModelInst;
std::unique_ptr<CBooModel> m_xrayModelInst;
std::unique_ptr<CBooModel> m_infraModelInst;
public: public:
enum class EWhichModel enum class EWhichModel
{ {
@ -105,7 +111,7 @@ public:
const CActorLights* lights, const CModelFlags& drawFlags); const CActorLights* lights, const CModelFlags& drawFlags);
EWhichModel GetRenderingModel(const CStateManager& stateMgr) const; EWhichModel GetRenderingModel(const CStateManager& stateMgr) const;
CSkinnedModel& PickAnimatedModel(EWhichModel which) const; CSkinnedModel& PickAnimatedModel(EWhichModel which) const;
TLockedToken<CModel>& PickStaticModel(EWhichModel which); std::unique_ptr<CBooModel>& PickStaticModel(EWhichModel which);
void SetXRayModel(const std::pair<ResId, ResId>& modelSkin); void SetXRayModel(const std::pair<ResId, ResId>& modelSkin);
void SetInfraModel(const std::pair<ResId, ResId>& modelSkin); void SetInfraModel(const std::pair<ResId, ResId>& modelSkin);
bool IsDefinitelyOpaque(EWhichModel); bool IsDefinitelyOpaque(EWhichModel);

View File

@ -12,7 +12,8 @@ CSkinRules::CSkinRules(CInputStream& in)
x0_skinBanks.emplace_back(in); x0_skinBanks.emplace_back(in);
} }
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params) CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
CObjectReference* selfRef)
{ {
return TToken<CSkinRules>::GetIObjObjectFor(std::make_unique<CSkinRules>(in)); return TToken<CSkinRules>::GetIObjObjectFor(std::make_unique<CSkinRules>(in));
} }

View File

@ -22,7 +22,8 @@ public:
} }
}; };
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params); CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
CObjectReference* selfRef);
} }

View File

@ -65,7 +65,8 @@ void CCollidableOBBTreeGroup::SetStaticTableIndex(u32 index)
} }
CFactoryFnReturn FCollidableOBBTreeGroupFactory(const SObjectTag &tag, CInputStream& in, CFactoryFnReturn FCollidableOBBTreeGroupFactory(const SObjectTag &tag, CInputStream& in,
const CVParamTransfer &vparms) const CVParamTransfer& vparms,
CObjectReference* selfRef)
{ {
return TToken<CCollidableOBBTreeGroup>::GetIObjObjectFor(std::make_unique<CCollidableOBBTreeGroup>(in)); return TToken<CCollidableOBBTreeGroup>::GetIObjObjectFor(std::make_unique<CCollidableOBBTreeGroup>(in));
} }

View File

@ -31,7 +31,8 @@ public:
}; };
CFactoryFnReturn FCollidableOBBTreeGroupFactory(const SObjectTag &tag, CInputStream& in, CFactoryFnReturn FCollidableOBBTreeGroupFactory(const SObjectTag &tag, CInputStream& in,
const CVParamTransfer &vparms); const CVParamTransfer& vparms,
CObjectReference* selfRef);
} }

View File

@ -19,6 +19,7 @@ class CTexture;
class CLight; class CLight;
class CSkinRules; class CSkinRules;
class CPoseAsTransforms; class CPoseAsTransforms;
class CModel;
struct CModelFlags struct CModelFlags
{ {
@ -73,19 +74,23 @@ public:
std::vector<TCachedToken<CTexture>> x0_textures; std::vector<TCachedToken<CTexture>> x0_textures;
std::vector<std::vector<boo::IShaderPipeline*>> m_shaders; std::vector<std::vector<boo::IShaderPipeline*>> m_shaders;
MaterialSet m_matSet; MaterialSet m_matSet;
int m_matSetIdx;
SShader(int idx) : m_matSetIdx(idx) {}
void UnlockTextures(); void UnlockTextures();
}; };
private: private:
TLockedToken<CModel> m_model;
std::vector<CBooSurface>* x0_surfaces; std::vector<CBooSurface>* x0_surfaces;
const MaterialSet* x4_matSet; const MaterialSet* x4_matSet;
int m_matSetIdx = -1;
const std::vector<std::vector<boo::IShaderPipeline*>>* m_pipelines; const std::vector<std::vector<boo::IShaderPipeline*>>* m_pipelines;
boo::IVertexFormat* m_vtxFmt; boo::IVertexFormat* m_vtxFmt;
boo::IGraphicsBufferS* x8_vbo; boo::IGraphicsBufferS* x8_vbo;
boo::IGraphicsBufferS* xc_ibo; boo::IGraphicsBufferS* xc_ibo;
size_t m_weightVecCount; size_t m_weightVecCount;
size_t m_skinBankCount; size_t m_skinBankCount;
std::vector<TCachedToken<CTexture>>* x1c_textures; std::vector<TCachedToken<CTexture>> x1c_textures;
zeus::CAABox x20_aabb; zeus::CAABox x20_aabb;
CBooSurface* x38_firstUnsortedSurface = nullptr; CBooSurface* x38_firstUnsortedSurface = nullptr;
CBooSurface* x3c_firstSortedSurface = nullptr; CBooSurface* x3c_firstSortedSurface = nullptr;
@ -114,8 +119,10 @@ private:
void DrawSurfaces(const CModelFlags& flags) const; void DrawSurfaces(const CModelFlags& flags) const;
void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const; void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const;
void VerifyCurrentShader(int shaderIdx);
public: public:
CBooModel(std::vector<CBooSurface>* surfaces, SShader& shader, CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo, boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb); size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb);
@ -128,6 +135,7 @@ public:
void RemapMaterialData(SShader& shader); void RemapMaterialData(SShader& shader);
bool TryLockTextures() const; bool TryLockTextures() const;
void UnlockTextures() const; void UnlockTextures() const;
void Touch(int shaderIdx) const;
void UpdateUniformData(const CModelFlags& flags, void UpdateUniformData(const CModelFlags& flags,
const CSkinRules* cskr, const CSkinRules* cskr,
const CPoseAsTransforms* pose) const; const CPoseAsTransforms* pose) const;
@ -152,8 +160,10 @@ public:
class CModel class CModel
{ {
friend class CBooModel;
//std::unique_ptr<u8[]> x0_data; //std::unique_ptr<u8[]> x0_data;
//u32 x4_dataLen; //u32 x4_dataLen;
TToken<CModel> m_selfToken; /* DO NOT LOCK! */
zeus::CAABox m_aabb; zeus::CAABox m_aabb;
std::vector<CBooSurface> x8_surfaces; std::vector<CBooSurface> x8_surfaces;
std::vector<CBooModel::SShader> x18_matSets; std::vector<CBooModel::SShader> x18_matSets;
@ -167,16 +177,13 @@ class CModel
boo::IGraphicsBufferS* m_ibo; boo::IGraphicsBufferS* m_ibo;
boo::IVertexFormat* m_vtxFmt; boo::IVertexFormat* m_vtxFmt;
void VerifyCurrentShader(int shaderIdx) const;
public: public:
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet; using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store); CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store, CObjectReference* selfRef);
void DrawSortedParts(const CModelFlags& flags) const; void DrawSortedParts(const CModelFlags& flags) const;
void DrawUnsortedParts(const CModelFlags& flags) const; void DrawUnsortedParts(const CModelFlags& flags) const;
void Draw(const CModelFlags& flags) const; void Draw(const CModelFlags& flags) const;
void Touch(int shaderIdx) const;
bool IsLoaded(int shaderIdx) const; bool IsLoaded(int shaderIdx) const;
const zeus::CAABox& GetAABB() const {return m_aabb;} const zeus::CAABox& GetAABB() const {return m_aabb;}
@ -187,7 +194,8 @@ public:
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag, CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len, std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms); const urde::CVParamTransfer& vparms,
CObjectReference* selfRef);
} }

View File

@ -16,12 +16,12 @@ namespace urde
static logvisor::Module Log("urde::CBooModel"); static logvisor::Module Log("urde::CBooModel");
bool CBooModel::g_DrawingOccluders = false; bool CBooModel::g_DrawingOccluders = false;
CBooModel::CBooModel(std::vector<CBooSurface>* surfaces, SShader& shader, CBooModel::CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo, boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb) size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb)
: x0_surfaces(surfaces), x4_matSet(&shader.m_matSet), m_pipelines(&shader.m_shaders), : m_model(token), x0_surfaces(surfaces), x4_matSet(&shader.m_matSet), m_matSetIdx(shader.m_matSetIdx),
m_vtxFmt(vtxFmt), x8_vbo(vbo), xc_ibo(ibo), m_weightVecCount(weightVecCount), m_pipelines(&shader.m_shaders), m_vtxFmt(vtxFmt), x8_vbo(vbo), xc_ibo(ibo), m_weightVecCount(weightVecCount),
m_skinBankCount(skinBankCount), x1c_textures(&shader.x0_textures), x20_aabb(aabb), m_skinBankCount(skinBankCount), x1c_textures(shader.x0_textures), x20_aabb(aabb),
x40_24_texturesLoaded(false), x40_25_modelVisible(0) x40_24_texturesLoaded(false), x40_25_modelVisible(0)
{ {
for (CBooSurface& surf : *x0_surfaces) for (CBooSurface& surf : *x0_surfaces)
@ -131,7 +131,7 @@ void CBooModel::BuildGfxToken()
texs.reserve(8); texs.reserve(8);
for (atUint32 idx : mat.textureIdxs) for (atUint32 idx : mat.textureIdxs)
{ {
TCachedToken<CTexture>& tex = (*x1c_textures)[idx]; TCachedToken<CTexture>& tex = x1c_textures[idx];
texs.push_back(tex.GetObj()->GetBooTexture()); texs.push_back(tex.GetObj()->GetBooTexture());
} }
texs.resize(8); texs.resize(8);
@ -235,7 +235,8 @@ void CBooModel::ActivateLights(const std::vector<CLight>& lights)
void CBooModel::RemapMaterialData(SShader& shader) void CBooModel::RemapMaterialData(SShader& shader)
{ {
x4_matSet = &shader.m_matSet; x4_matSet = &shader.m_matSet;
x1c_textures = &shader.x0_textures; m_matSetIdx = shader.m_matSetIdx;
x1c_textures = shader.x0_textures;
m_pipelines = &shader.m_shaders; m_pipelines = &shader.m_shaders;
x40_24_texturesLoaded = false; x40_24_texturesLoaded = false;
m_gfxToken.doDestroy(); m_gfxToken.doDestroy();
@ -246,7 +247,7 @@ bool CBooModel::TryLockTextures() const
if (!x40_24_texturesLoaded) if (!x40_24_texturesLoaded)
{ {
bool allLoad = true; bool allLoad = true;
for (TCachedToken<CTexture>& tex : *x1c_textures) for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures))
{ {
tex.Lock(); tex.Lock();
if (!tex.IsLoaded()) if (!tex.IsLoaded())
@ -263,7 +264,7 @@ bool CBooModel::TryLockTextures() const
void CBooModel::UnlockTextures() const void CBooModel::UnlockTextures() const
{ {
for (TCachedToken<CTexture>& tex : *x1c_textures) for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures))
tex.Unlock(); tex.Unlock();
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = false; const_cast<CBooModel*>(this)->x40_24_texturesLoaded = false;
} }
@ -615,11 +616,12 @@ std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx)
{ {
if (shaderIdx >= x18_matSets.size()) if (shaderIdx >= x18_matSets.size())
shaderIdx = 0; shaderIdx = 0;
return std::make_unique<CBooModel>(&x8_surfaces, x18_matSets[shaderIdx], return std::make_unique<CBooModel>(m_selfToken, &x8_surfaces, x18_matSets[shaderIdx],
m_vtxFmt, m_vbo, m_ibo, 0, 0, m_aabb); m_vtxFmt, m_vbo, m_ibo, 0, 0, m_aabb);
} }
CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* store) CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* store, CObjectReference* selfRef)
: m_selfToken(selfRef)
{ {
std::unique_ptr<u8[]> data = std::move(in); std::unique_ptr<u8[]> data = std::move(in);
@ -637,7 +639,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
{ {
u32 matSetSz = hecl::SBig(*secSizeCur); u32 matSetSz = hecl::SBig(*secSizeCur);
const u8* sec = MemoryFromPartData(dataCur, secSizeCur); const u8* sec = MemoryFromPartData(dataCur, secSizeCur);
x18_matSets.emplace_back(); x18_matSets.emplace_back(i);
CBooModel::SShader& shader = x18_matSets.back(); CBooModel::SShader& shader = x18_matSets.back();
athena::io::MemoryReader r(sec, matSetSz); athena::io::MemoryReader r(sec, matSetSz);
shader.m_matSet.read(r); shader.m_matSet.read(r);
@ -703,44 +705,42 @@ void CBooModel::SShader::UnlockTextures()
tex.Unlock(); tex.Unlock();
} }
void CModel::VerifyCurrentShader(int shaderIdx) const void CBooModel::VerifyCurrentShader(int shaderIdx)
{ {
int idx = 0; if (shaderIdx != m_matSetIdx)
for (const CBooModel::SShader& shader : x18_matSets) RemapMaterialData(m_model->x18_matSets[shaderIdx]);
if (idx++ != shaderIdx) }
((CBooModel::SShader&)shader).UnlockTextures();
void CBooModel::Touch(int shaderIdx) const
{
const_cast<CBooModel*>(this)->VerifyCurrentShader(shaderIdx);
TryLockTextures();
} }
void CModel::DrawSortedParts(const CModelFlags& flags) const void CModel::DrawSortedParts(const CModelFlags& flags) const
{ {
VerifyCurrentShader(flags.m_matSetIdx); const_cast<CBooModel&>(*x28_modelInst).VerifyCurrentShader(flags.m_matSetIdx);
x28_modelInst->DrawAlpha(flags, nullptr, nullptr); x28_modelInst->DrawAlpha(flags, nullptr, nullptr);
} }
void CModel::DrawUnsortedParts(const CModelFlags& flags) const void CModel::DrawUnsortedParts(const CModelFlags& flags) const
{ {
VerifyCurrentShader(flags.m_matSetIdx); const_cast<CBooModel&>(*x28_modelInst).VerifyCurrentShader(flags.m_matSetIdx);
x28_modelInst->DrawNormal(flags, nullptr, nullptr); x28_modelInst->DrawNormal(flags, nullptr, nullptr);
} }
void CModel::Draw(const CModelFlags& flags) const void CModel::Draw(const CModelFlags& flags) const
{ {
VerifyCurrentShader(flags.m_matSetIdx); const_cast<CBooModel&>(*x28_modelInst).VerifyCurrentShader(flags.m_matSetIdx);
x28_modelInst->Draw(flags, nullptr, nullptr); x28_modelInst->Draw(flags, nullptr, nullptr);
} }
void CModel::Touch(int shaderIdx) const
{
VerifyCurrentShader(shaderIdx);
x28_modelInst->TryLockTextures();
}
bool CModel::IsLoaded(int shaderIdx) const bool CModel::IsLoaded(int shaderIdx) const
{ {
VerifyCurrentShader(shaderIdx); const_cast<CBooModel&>(*x28_modelInst).VerifyCurrentShader(shaderIdx);
std::vector<TCachedToken<CTexture>>* texs = x28_modelInst->x1c_textures; std::vector<TCachedToken<CTexture>>& texs = x28_modelInst->x1c_textures;
bool loaded = true; bool loaded = true;
for (TCachedToken<CTexture>& tex : *texs) for (TCachedToken<CTexture>& tex : texs)
{ {
if (!tex.IsLoaded()) if (!tex.IsLoaded())
{ {
@ -753,10 +753,11 @@ bool CModel::IsLoaded(int shaderIdx) const
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag, CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len, std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms) const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)
{ {
IObjectStore* store = static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam(); IObjectStore* store = static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam();
CFactoryFnReturn ret = TToken<CModel>::GetIObjObjectFor(std::make_unique<CModel>(std::move(in), len, store)); CFactoryFnReturn ret = TToken<CModel>::GetIObjObjectFor(std::make_unique<CModel>(std::move(in), len, store, selfRef));
return ret; return ret;
} }

View File

@ -35,6 +35,7 @@ public:
ResId layoutInfo, int shaderIdx); ResId layoutInfo, int shaderIdx);
TLockedToken<CModel>& GetModel() {return x4_model;} TLockedToken<CModel>& GetModel() {return x4_model;}
std::unique_ptr<CBooModel>& GetModelInst() {return m_modelInst;}
TLockedToken<CSkinRules>& GetSkinRules() {return x10_skinRules;} TLockedToken<CSkinRules>& GetSkinRules() {return x10_skinRules;}
TLockedToken<CCharLayoutInfo>& GetLayoutInfo() {return x1c_layoutInfo;} TLockedToken<CCharLayoutInfo>& GetLayoutInfo() {return x1c_layoutInfo;}

View File

@ -59,7 +59,8 @@ public:
CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag, CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len, std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms); const urde::CVParamTransfer& vparms,
CObjectReference* selfRef);
} }

View File

@ -739,7 +739,8 @@ void CTexture::Load(int slot, EClampMode clamp) const
CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag, CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len, std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms) const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)
{ {
return TToken<CTexture>::GetIObjObjectFor(std::make_unique<CTexture>(std::move(in), len)); return TToken<CTexture>::GetIObjObjectFor(std::make_unique<CTexture>(std::move(in), len));
} }

View File

@ -634,7 +634,8 @@ CGuiFrame* CGuiFrame::CreateFrame(ResId frmeId, CGuiSys& sys, CInputStream& in)
} }
std::unique_ptr<IObj> RGuiFrameFactoryInGame(const SObjectTag& tag, CInputStream& in, std::unique_ptr<IObj> RGuiFrameFactoryInGame(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer&) const CVParamTransfer&,
CObjectReference* selfRef)
{ {
std::unique_ptr<CGuiFrame> frame(CGuiFrame::CreateFrame(tag.id, *g_GuiSys, in)); std::unique_ptr<CGuiFrame> frame(CGuiFrame::CreateFrame(tag.id, *g_GuiSys, in));
return TToken<CGuiFrame>::GetIObjObjectFor(std::move(frame)); return TToken<CGuiFrame>::GetIObjObjectFor(std::move(frame));

View File

@ -18,6 +18,7 @@ class CGuiHeadWidget;
class CFinalInput; class CFinalInput;
class CGuiLight; class CGuiLight;
class CVParamTransfer; class CVParamTransfer;
class CObjectReference;
enum class EFrameTransitionOptions enum class EFrameTransitionOptions
{ {
@ -134,7 +135,8 @@ public:
}; };
std::unique_ptr<IObj> RGuiFrameFactoryInGame(const SObjectTag& tag, CInputStream& in, std::unique_ptr<IObj> RGuiFrameFactoryInGame(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& vparms); const CVParamTransfer& vparms,
CObjectReference* selfRef);
} }

View File

@ -31,7 +31,7 @@ bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() const
const CModel* model = xf8_model.GetObj(); const CModel* model = xf8_model.GetObj();
if (!model) if (!model)
return false; return false;
model->Touch(0); model->GetInstance().Touch(0);
return model->IsLoaded(0); return model->IsLoaded(0);
} }
@ -39,7 +39,7 @@ void CGuiModel::Touch() const
{ {
const CModel* model = xf8_model.GetObj(); const CModel* model = xf8_model.GetObj();
if (model) if (model)
model->Touch(0); model->GetInstance().Touch(0);
} }
void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) const void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) const

View File

@ -192,7 +192,8 @@ void CRasterFont::GetSize(const CDrawStringOptions& opts, int& width, int& heigh
} }
} }
std::unique_ptr<IObj> FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms) std::unique_ptr<IObj> FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms,
CObjectReference* selfRef)
{ {
return TToken<CRasterFont>::GetIObjObjectFor( return TToken<CRasterFont>::GetIObjObjectFor(
std::make_unique<CRasterFont>(in, *static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam())); std::make_unique<CRasterFont>(in, *static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam()));

View File

@ -149,7 +149,8 @@ public:
TToken<CTexture>& GetTexture() { return x80_texture; } TToken<CTexture>& GetTexture() { return x80_texture; }
}; };
std::unique_ptr<IObj> FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms); std::unique_ptr<IObj> FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms,
CObjectReference* selfRef);
} }
#endif // __URDE_CRASTERFONT_HPP__ #endif // __URDE_CRASTERFONT_HPP__

View File

@ -85,7 +85,8 @@ void CStringTable::SetLanguage(s32 lang)
mCurrentLanguage = skLanguages[lang]; mCurrentLanguage = skLanguages[lang];
} }
CFactoryFnReturn FStringTableFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&) CFactoryFnReturn FStringTableFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&,
CObjectReference* selfRef)
{ {
return TToken<CStringTable>::GetIObjObjectFor(std::make_unique<CStringTable>(in)); return TToken<CStringTable>::GetIObjObjectFor(std::make_unique<CStringTable>(in));
} }

View File

@ -21,6 +21,7 @@ public:
static void SetLanguage(s32); static void SetLanguage(s32);
}; };
CFactoryFnReturn FStringTableFactory(const SObjectTag&, CInputStream&, const CVParamTransfer&); CFactoryFnReturn FStringTableFactory(const SObjectTag&, CInputStream&, const CVParamTransfer&,
CObjectReference* selfRef);
} }
#endif // __URDE_CSTRINGTABLE_HPP__ #endif // __URDE_CSTRINGTABLE_HPP__

View File

@ -8,21 +8,24 @@ namespace urde
{ {
class CVParamTransfer; class CVParamTransfer;
class IObj; class IObj;
class CObjectReference;
using CFactoryFnReturn = std::unique_ptr<IObj>; using CFactoryFnReturn = std::unique_ptr<IObj>;
using FFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag, using FFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag,
urde::CInputStream& in, urde::CInputStream& in,
const urde::CVParamTransfer& vparms)>; const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)>;
using FMemFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag, using FMemFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len, std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms)>; const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)>;
class IFactory class IFactory
{ {
public: public:
virtual ~IFactory() = default; virtual ~IFactory() = default;
virtual CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&)=0; virtual CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference*)=0;
virtual void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**)=0; virtual void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**, CObjectReference*)=0;
virtual void CancelBuild(const SObjectTag&)=0; virtual void CancelBuild(const SObjectTag&)=0;
virtual bool CanBuild(const SObjectTag&)=0; virtual bool CanBuild(const SObjectTag&)=0;
virtual const SObjectTag* GetResourceIdByName(const char*) const=0; virtual const SObjectTag* GetResourceIdByName(const char*) const=0;

View File

@ -1157,7 +1157,8 @@ void CParticleDataFactory::LoadGPSMTokens(CGenDescription* desc)
} }
CFactoryFnReturn FParticleFactory(const SObjectTag& tag, CInputStream& in, CFactoryFnReturn FParticleFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& vparms) const CVParamTransfer& vparms,
CObjectReference* selfRef)
{ {
CSimplePool* sp = static_cast<CSimplePool*>(static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam()); CSimplePool* sp = static_cast<CSimplePool*>(static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam());
return TToken<CGenDescription>::GetIObjObjectFor(std::unique_ptr<CGenDescription>(CParticleDataFactory::GetGeneratorDesc(in, sp))); return TToken<CGenDescription>::GetIObjObjectFor(std::unique_ptr<CGenDescription>(CParticleDataFactory::GetGeneratorDesc(in, sp)));

View File

@ -97,7 +97,8 @@ public:
static CGenDescription* GetGeneratorDesc(CInputStream& in, CSimplePool* resPool); static CGenDescription* GetGeneratorDesc(CInputStream& in, CSimplePool* resPool);
}; };
CFactoryFnReturn FParticleFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms); CFactoryFnReturn FParticleFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms,
CObjectReference* selfRef);
} }

View File

@ -413,7 +413,7 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId)
if (!skybox) if (!skybox)
return false; return false;
skybox->Touch(0); skybox->GetInstance().Touch(0);
if (!skybox->IsLoaded(0)) if (!skybox->IsLoaded(0))
return false; return false;