Added CResTypeInfo class

This commit is contained in:
Aruki
2017-01-31 21:56:53 -07:00
parent 4f03c2431e
commit 8a66e393e7
16 changed files with 503 additions and 326 deletions

View File

@@ -518,7 +518,7 @@ void CGameExporter::ExportResource(SResourceInstance& rRes)
// Register resource and write to file
TString Directory, Name;
mNameMap.GetNameInfo(rRes.ResourceID, Directory, Name);
CResourceEntry *pEntry = mpStore->RegisterResource(rRes.ResourceID, CResource::ResTypeForExtension(rRes.ResourceType), Directory, Name);
CResourceEntry *pEntry = mpStore->RegisterResource(rRes.ResourceID, CResTypeInfo::TypeForCookedExtension(mGame, rRes.ResourceType)->Type(), Directory, Name);
#if EXPORT_COOKED
// Save cooked asset

View File

@@ -255,7 +255,7 @@ void CPackage::CompareOriginalAssetList(const std::list<CAssetID>& rkNewList)
if (NewListSet.find(ID) == NewListSet.end())
{
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
TString Extension = (pEntry ? "." + GetResourceCookedExtension(pEntry->ResourceType(), pEntry->Game()) : "");
TString Extension = (pEntry ? "." + pEntry->CookedExtension() : "");
Log::Error("Missing resource: " + ID.ToString() + Extension);
}
}
@@ -268,7 +268,7 @@ void CPackage::CompareOriginalAssetList(const std::list<CAssetID>& rkNewList)
if (OldListSet.find(ID) == OldListSet.end())
{
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
TString Extension = (pEntry ? "." + GetResourceCookedExtension(pEntry->ResourceType(), pEntry->Game()) : "");
TString Extension = (pEntry ? "." + pEntry->CookedExtension() : "");
Log::Error("Extra resource: " + ID.ToString() + Extension);
}
}

View File

@@ -16,12 +16,14 @@ CResourceEntry::CResourceEntry(CResourceStore *pStore, const CAssetID& rkID,
, mpStore(pStore)
, mpDependencies(nullptr)
, mID(rkID)
, mType(Type)
, mpDirectory(nullptr)
, mName(rkFilename)
, mCachedSize(-1)
, mCachedUppercaseName(rkFilename.ToUpper())
{
mpTypeInfo = CResTypeInfo::FindTypeInfo(Type);
ASSERT(mpTypeInfo);
if (Transient) mFlags |= eREF_Transient;
mpDirectory = mpStore->GetVirtualDirectory(rkDir, Transient, true);
@@ -93,7 +95,7 @@ bool CResourceEntry::HasCookedVersion() const
TString CResourceEntry::RawAssetPath(bool Relative) const
{
TWideString Ext = GetResourceRawExtension(mType, mGame).ToUTF16();
TWideString Ext = RawExtension().ToUTF16();
TWideString Path = mpDirectory ? mpDirectory->FullPath() : L"";
TWideString Name = mName + L"." + Ext;
return ((IsTransient() || Relative) ? Path + Name : mpStore->RawDir(false) + Path + Name);
@@ -101,12 +103,12 @@ TString CResourceEntry::RawAssetPath(bool Relative) const
TString CResourceEntry::RawExtension() const
{
return GetResourceRawExtension(mType, mGame);
return mpTypeInfo->RawExtension();
}
TString CResourceEntry::CookedAssetPath(bool Relative) const
{
TWideString Ext = GetResourceCookedExtension(mType, mGame).ToUTF16();
TWideString Ext = CookedExtension().ToString().ToUTF16();
TWideString Path = mpDirectory ? mpDirectory->FullPath() : L"";
TWideString Name = mName + L"." + Ext;
return ((IsTransient() || Relative) ? Path + Name : mpStore->CookedDir(false) + Path + Name);
@@ -114,7 +116,7 @@ TString CResourceEntry::CookedAssetPath(bool Relative) const
CFourCC CResourceEntry::CookedExtension() const
{
return CFourCC( GetResourceCookedExtension(mType, mGame) );
return mpTypeInfo->CookedExtension(mGame);
}
bool CResourceEntry::IsInDirectory(CVirtualDirectory *pDir) const
@@ -178,7 +180,7 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/)
bool ShouldCollectGarbage = false;
// Save raw resource
if (ResourceSupportsSerialization(ResourceType()))
if (mpTypeInfo->CanBeSerialized())
{
ShouldCollectGarbage = !IsLoaded();
@@ -190,7 +192,9 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/)
TString Dir = Path.GetFileDirectory();
FileUtil::CreateDirectory(Dir.ToUTF16());
CXMLWriter Writer(Path, GetResourceSerialName(ResourceType()), 0, mGame);
TString SerialName = mpTypeInfo->TypeName();
SerialName.RemoveWhitespace();
CXMLWriter Writer(Path, SerialName, 0, mGame);
mpResource->Serialize(Writer);
}
@@ -288,7 +292,7 @@ bool CResourceEntry::CanMoveTo(const TWideString& rkDir, const TWideString& rkNa
// We need to validate the path isn't taken already - either the directory doesn't exist, or doesn't have a resource by this name
CVirtualDirectory *pDir = mpStore->GetVirtualDirectory(rkDir, false, false);
if (pDir && pDir->FindChildResource(rkName, mType)) return false;
if (pDir && pDir->FindChildResource(rkName, ResourceType())) return false;
// All checks are true
return true;
@@ -309,7 +313,7 @@ bool CResourceEntry::Move(const TWideString& rkDir, const TWideString& rkName)
if (pNewDir == mpDirectory && rkName == mName) return false;
// Check if we can legally move to this spot
ASSERT(pNewDir->FindChildResource(rkName, mType) == nullptr); // this check should be guaranteed to pass due to CanMoveTo() having already checked it
ASSERT(pNewDir->FindChildResource(rkName, ResourceType()) == nullptr); // this check should be guaranteed to pass due to CanMoveTo() having already checked it
mpDirectory = pNewDir;
mName = rkName;

View File

@@ -2,6 +2,7 @@
#define CRESOURCEENTRY_H
#include "CVirtualDirectory.h"
#include "Core/Resource/CResTypeInfo.h"
#include "Core/Resource/EResType.h"
#include <Common/CAssetID.h>
#include <Common/CFourCC.h>
@@ -26,10 +27,10 @@ DECLARE_FLAGS(EResEntryFlag, FResEntryFlags)
class CResourceEntry
{
CResource *mpResource;
CResTypeInfo *mpTypeInfo;
CResourceStore *mpStore;
CDependencyTree *mpDependencies;
CAssetID mID;
EResType mType;
EGame mGame;
CVirtualDirectory *mpDirectory;
TWideString mName;
@@ -74,6 +75,7 @@ public:
inline bool IsCategorized() const { return mpDirectory && mpDirectory->FullPath() != L"Uncategorized\\"; }
inline bool IsNamed() const { return mName != mID.ToString().ToUTF16(); }
inline CResource* Resource() const { return mpResource; }
inline CResTypeInfo* TypeInfo() const { return mpTypeInfo; }
inline CResourceStore* ResourceStore() const { return mpStore; }
inline CDependencyTree* Dependencies() const { return mpDependencies; }
inline CAssetID ID() const { return mID; }
@@ -82,7 +84,7 @@ public:
inline TWideString DirectoryPath() const { return mpDirectory->FullPath(); }
inline TWideString Name() const { return mName; }
inline const TWideString& UppercaseName() const { return mCachedUppercaseName; }
inline EResType ResourceType() const { return mType; }
inline EResType ResourceType() const { return mpTypeInfo->Type(); }
inline bool IsTransient() const { return mFlags.HasFlag(eREF_Transient); }
inline bool IsHidden() const { return mFlags.HasFlag(eREF_Hidden); }

View File

@@ -21,7 +21,7 @@ CResourceStore::CResourceStore(const TWideString& rkDatabasePath)
, mDatabaseDirty(false)
, mCacheFileDirty(false)
{
mpDatabaseRoot = new CVirtualDirectory();
mpDatabaseRoot = new CVirtualDirectory(this);
mDatabasePath = FileUtil::MakeAbsolute(rkDatabasePath.GetFileDirectory());
mDatabaseName = rkDatabasePath.GetFileName();
}
@@ -100,7 +100,7 @@ void CResourceStore::SerializeResourceDatabase(IArchive& rArc)
for (auto Iter = Resources.begin(); Iter != Resources.end(); Iter++)
{
SDatabaseResource& rRes = *Iter;
RegisterResource(rRes.ID, CResource::ResTypeForExtension(rRes.Type), rRes.Directory, rRes.Name);
RegisterResource(rRes.ID, CResTypeInfo::TypeForCookedExtension(rArc.Game(), rRes.Type)->Type(), rRes.Directory, rRes.Name);
}
}
}
@@ -111,7 +111,7 @@ void CResourceStore::LoadResourceDatabase()
TString Path = DatabasePath().ToUTF8();
if (!mpDatabaseRoot)
mpDatabaseRoot = new CVirtualDirectory();
mpDatabaseRoot = new CVirtualDirectory(this);
CXMLReader Reader(Path);
@@ -238,7 +238,7 @@ void CResourceStore::SetProject(CGameProject *pProj)
TWideString DatabasePath = mpProj->ResourceDBPath(false);
mDatabasePath = DatabasePath.GetFileDirectory();
mDatabaseName = DatabasePath.GetFileName();
mpDatabaseRoot = new CVirtualDirectory();
mpDatabaseRoot = new CVirtualDirectory(this);
mGame = mpProj->Game();
}
}
@@ -296,7 +296,7 @@ CVirtualDirectory* CResourceStore::GetVirtualDirectory(const TWideString& rkPath
if (AllowCreate)
{
CVirtualDirectory *pDir = new CVirtualDirectory(rkPath);
CVirtualDirectory *pDir = new CVirtualDirectory(rkPath, this);
mTransientRoots.push_back(pDir);
return pDir;
}
@@ -409,7 +409,7 @@ CResource* CResourceStore::LoadResource(const CAssetID& rkID, const CFourCC& rkT
if (DataBuffer.empty()) return nullptr;
CMemoryInStream MemStream(DataBuffer.data(), DataBuffer.size(), IOUtil::eBigEndian);
EResType Type = CResource::ResTypeForExtension(rkType);
EResType Type = CResTypeInfo::TypeForCookedExtension(mGame, rkType)->Type();
CResourceEntry *pEntry = RegisterTransientResource(Type, rkID);
CResource *pRes = pEntry->LoadCooked(MemStream);
return pRes;
@@ -423,7 +423,7 @@ CResource* CResourceStore::LoadResource(const CAssetID& rkID, const CFourCC& rkT
if (pEntry) return pEntry->Load();
// Check in transient load directory - this only works for cooked
EResType Type = CResource::ResTypeForExtension(rkType);
EResType Type = CResTypeInfo::TypeForCookedExtension(mGame, rkType)->Type();
if (Type != eInvalidResType)
{
@@ -490,7 +490,7 @@ CResource* CResourceStore::LoadResource(const TWideString& rkPath)
// Determine type
TString PathUTF8 = rkPath.ToUTF8();
TString Extension = TString(PathUTF8).GetFileExtension().ToUpper();
EResType Type = CResource::ResTypeForExtension(Extension);
EResType Type = CResTypeInfo::TypeForCookedExtension(mGame, Extension)->Type();
if (Type == eInvalidResType)
{
@@ -527,32 +527,6 @@ void CResourceStore::TrackLoadedResource(CResourceEntry *pEntry)
mLoadedResources[pEntry->ID()] = pEntry;
}
CFourCC CResourceStore::ResourceTypeByID(const CAssetID& rkID, const TStringList& rkPossibleTypes) const
{
if (!rkID.IsValid()) return eInvalidResType;
if (rkPossibleTypes.size() == 1) return CFourCC(rkPossibleTypes.front());
// Check for existing entry
auto Find = mResourceEntries.find(rkID);
if (Find != mResourceEntries.end())
return GetResourceCookedExtension(Find->second->ResourceType(), Find->second->Game());
// Determine extension from filesystem - try every extension until we find the file
TString PathBase = mTransientLoadDir.ToUTF8() + rkID.ToString() + '.';
for (auto It = rkPossibleTypes.begin(); It != rkPossibleTypes.end(); It++)
{
TString NewPath = PathBase + *It;
if (FileUtil::Exists(NewPath))
return CFourCC(*It);
}
// Couldn't find one, so return unknown. Note that it'd be possible to look up the extension from the
// filesystem even if it's not one of the provided possible types, but this would be too slow.
return "UNKN";
}
void CResourceStore::DestroyUnreferencedResources()
{
// This can be updated to avoid the do-while loop when reference lookup is implemented.

View File

@@ -72,7 +72,6 @@ public:
CResource* LoadResource(const CAssetID& rkID, const CFourCC& rkType);
CResource* LoadResource(const TWideString& rkPath);
void TrackLoadedResource(CResourceEntry *pEntry);
CFourCC ResourceTypeByID(const CAssetID& rkID, const TStringList& rkPossibleTypes) const;
void DestroyUnreferencedResources();
bool DeleteResourceEntry(CResourceEntry *pEntry);
void SetTransientLoadDir(const TString& rkDir);

View File

@@ -4,16 +4,16 @@
#include "Core/Resource/CResource.h"
#include <algorithm>
CVirtualDirectory::CVirtualDirectory()
: mpParent(nullptr)
CVirtualDirectory::CVirtualDirectory(CResourceStore *pStore)
: mpParent(nullptr), mpStore(pStore)
{}
CVirtualDirectory::CVirtualDirectory(const TWideString& rkName)
: mpParent(nullptr), mName(rkName)
CVirtualDirectory::CVirtualDirectory(const TWideString& rkName, CResourceStore *pStore)
: mpParent(nullptr), mName(rkName), mpStore(pStore)
{}
CVirtualDirectory::CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName)
: mpParent(pParent), mName(rkName)
CVirtualDirectory::CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName, CResourceStore *pStore)
: mpParent(pParent), mName(rkName), mpStore(pStore)
{}
CVirtualDirectory::~CVirtualDirectory()
@@ -93,7 +93,7 @@ CResourceEntry* CVirtualDirectory::FindChildResource(const TWideString& rkPath)
else if (!Name.IsEmpty())
{
TWideString Ext = Name.GetFileExtension();
EResType Type = CResource::ResTypeForExtension(Ext);
EResType Type = CResTypeInfo::TypeForCookedExtension(mpStore->Game(), Ext)->Type();
return FindChildResource(Name.GetFileName(false), Type);
}
@@ -137,7 +137,7 @@ void CVirtualDirectory::AddChild(const TWideString &rkPath, CResourceEntry *pEnt
if (!pSubdir)
{
pSubdir = new CVirtualDirectory(this, DirName);
pSubdir = new CVirtualDirectory(this, DirName, mpStore);
mSubdirectories.push_back(pSubdir);
std::sort(mSubdirectories.begin(), mSubdirectories.end(), [](CVirtualDirectory *pLeft, CVirtualDirectory *pRight) -> bool {

View File

@@ -8,18 +8,20 @@
#include <vector>
class CResourceEntry;
class CResourceStore;
class CVirtualDirectory
{
CVirtualDirectory *mpParent;
CResourceStore *mpStore;
TWideString mName;
std::vector<CVirtualDirectory*> mSubdirectories;
std::vector<CResourceEntry*> mResources;
public:
CVirtualDirectory();
CVirtualDirectory(const TWideString& rkName);
CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName);
CVirtualDirectory(CResourceStore *pStore);
CVirtualDirectory(const TWideString& rkName, CResourceStore *pStore);
CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName, CResourceStore *pStore);
~CVirtualDirectory();
bool IsEmpty() const;