Added project overview dialog with placeholder UI to allow loading worlds through a game project

This commit is contained in:
parax0
2016-07-08 01:10:07 -06:00
parent 12bd4eff90
commit 08dcfe5e5a
13 changed files with 404 additions and 74 deletions

View File

@@ -460,7 +460,7 @@ void CGameExporter::ExportWorlds()
SResourceInstance *pInst = FindResourceInstance(AreaID);
ASSERT(pInst != nullptr);
SetResourcePath(AreaID, AreaDir, HasInternalName ? InternalAreaName : GameAreaName);
SetResourcePath(AreaID, AreaDir, GameAreaName);
ExportResource(*pInst);
}
@@ -488,7 +488,7 @@ void CGameExporter::ExportCookedResources()
{
SCOPED_TIMER(SaveResourceDatabase);
#if EXPORT_COOKED
mStore.SaveResourceDatabase(this->mExportDir.ToUTF8() + "ResourceDatabase.rdb");
mStore.SaveResourceDatabase(mpProject->ResourceDBPath(false).ToUTF8());
#endif
mpProject->Save();
}

View File

@@ -3,17 +3,27 @@
#include <tinyxml2.h>
using namespace tinyxml2;
CGameProject *CGameProject::mspActiveProject = nullptr;
void CGameProject::Load()
CGameProject::~CGameProject()
{
TString ProjPath = ProjectPath().ToUTF8();
if (IsActive())
{
mspActiveProject = nullptr;
gpResourceStore->SetActiveProject(nullptr);
}
}
bool CGameProject::Load(const TWideString& rkPath)
{
TString ProjPath = rkPath.ToUTF8();
XMLDocument Doc;
Doc.LoadFile(*ProjPath);
if (Doc.Error())
{
Log::Error("Unable to open game project at " + ProjPath);
return;
return false;
}
XMLElement *pRoot = Doc.FirstChildElement("GameProject");
@@ -29,7 +39,7 @@ void CGameProject::Load()
{
TString MissingElem = pProjName ? (pGame ? (pResDB ? "Packages" : "ResourceDB") : "Game") : "Name";
Log::Error("Unable to load game project at " + ProjPath + "; " + MissingElem + " element is missing");
return;
return false;
}
mProjectName = pProjName->GetText();
@@ -41,7 +51,6 @@ void CGameProject::Load()
while (pPkgElem)
{
pPkgElem = pPkgElem->NextSiblingElement("Package");
TString Path = pPkgElem->Attribute("Path");
if (Path.IsEmpty())
@@ -53,7 +62,13 @@ void CGameProject::Load()
pPackage->Load();
mPackages.push_back(pPackage);
}
pPkgElem = pPkgElem->NextSiblingElement("Package");
}
// All loaded!
mProjectRoot = rkPath.GetFileDirectory();
return true;
}
void CGameProject::Save()
@@ -101,3 +116,33 @@ void CGameProject::Save()
if (Result != XML_SUCCESS)
Log::Error("Failed to save game project at: " + ProjPath);
}
void CGameProject::SetActive()
{
if (mspActiveProject != this)
{
mspActiveProject = this;
gpResourceStore->SetActiveProject(this);
}
}
void CGameProject::GetWorldList(std::list<CUniqueID>& rOut) const
{
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
{
CPackage *pPkg = mPackages[iPkg];
for (u32 iCol = 0; iCol < pPkg->NumCollections(); iCol++)
{
CResourceCollection *pCol = pPkg->CollectionByIndex(iCol);
for (u32 iRes = 0; iRes < pCol->NumResources(); iRes++)
{
const SNamedResource& rkRes = pCol->ResourceByIndex(iRes);
if (rkRes.Type == "MLVL" && !rkRes.Name.EndsWith("NODEPEND"))
rOut.push_back(rkRes.ID);
}
}
}
}

View File

@@ -24,7 +24,15 @@ class CGameProject
eVer_Max,
eVer_Current = eVer_Max - 1
};
static CGameProject *mspActiveProject;
public:
CGameProject()
: mGame(eUnknownVersion)
, mProjectName("Unnamed Project")
{}
CGameProject(const TWideString& rkProjRootDir)
: mGame(eUnknownVersion)
, mProjectName("Unnamed Project")
@@ -32,8 +40,12 @@ public:
, mResourceDBPath(L"ResourceDB.rdb")
{}
void Load();
~CGameProject();
bool Load(const TWideString& rkPath);
void Save();
void SetActive();
void GetWorldList(std::list<CUniqueID>& rOut) const;
// Directory Handling
inline TWideString ProjectRoot() const { return mProjectRoot; }
@@ -53,6 +65,9 @@ public:
inline void AddPackage(CPackage *pPackage) { mPackages.push_back(pPackage); }
inline EGame Game() const { return mGame; }
inline bool IsActive() const { return mspActiveProject == this; }
static inline CGameProject* ActiveProject() { return mspActiveProject; }
};
extern CGameProject *gpProject;

View File

@@ -137,6 +137,7 @@ CResource* CResourceEntry::Load(IInputStream& rInput)
default: mpResource = new CResource(this); break;
}
mpStore->TrackLoadedResource(this);
return mpResource;
}

View File

@@ -49,50 +49,21 @@ void CResourceStore::LoadResourceDatabase(const TString& rkPath)
while (pRes)
{
XMLElement *pChild = pRes->FirstChildElement();
XMLElement *pID = pRes->FirstChildElement("ID");
XMLElement *pType = pRes->FirstChildElement("Type");
XMLElement *pDir = pRes->FirstChildElement("FileDir");
XMLElement *pName = pRes->FirstChildElement("FileName");
bool HasID = false, HasType = false, HasDir = false, HasName = false;
CUniqueID ID;
EResType Type;
TWideString FileDir;
TWideString FileName;
while (pChild)
if (pID && pType && pDir && pName)
{
TString NodeName = pChild->Name();
if (NodeName == "ID")
{
ID = CUniqueID::FromString(pChild->GetText());
HasID = true;
}
else if (NodeName == "Type")
{
Type = CResource::ResTypeForExtension(pChild->GetText());
HasType = true;
ASSERT(Type != eInvalidResType);
}
else if (NodeName == "FileDir")
{
FileDir = pChild->GetText();
HasDir = true;
}
else if (NodeName == "FileName")
{
FileName = pChild->GetText();
HasName = true;
}
pChild = pChild->NextSiblingElement();
}
if (HasID && HasType && HasDir && HasName)
CUniqueID ID = CUniqueID::FromString(pID->GetText());
EResType Type = CResource::ResTypeForExtension(pType->GetText());
TWideString FileDir = pDir->GetText();
TWideString FileName = pName->GetText();
RegisterResource(ID, Type, FileDir, FileName);
}
else
Log::Error("Error reading " + rkPath + ": Resource entry " + TString::FromInt32(ResIndex, 0, 10) + " is missing one or more components");
Log::Error("Error reading " + rkPath + ": Resource entry " + TString::FromInt32(ResIndex, 0, 10) + " is missing one or more required components");
ResIndex++;
pRes = pRes->NextSiblingElement("Resource");
@@ -292,12 +263,6 @@ CResource* CResourceStore::LoadResource(const CUniqueID& rkID, const CFourCC& rk
EResType Type = CResource::ResTypeForExtension(rkType);
CResourceEntry *pEntry = RegisterTransientResource(Type, rkID);
CResource *pRes = pEntry->Load(MemStream);
if (pRes)
{
mLoadedResources[rkID] = pEntry;
}
return pRes;
}
@@ -322,8 +287,7 @@ CResource* CResourceStore::LoadResource(const CUniqueID& rkID, const CFourCC& rk
CFileInStream File(Path.ToStdString(), IOUtil::eBigEndian);
CResource *pRes = pEntry->Load(File);
if (pRes) mLoadedResources[rkID] = pEntry;
else DeleteResourceEntry(pEntry);
if (!pRes) DeleteResourceEntry(pEntry);
return pRes;
}
@@ -371,15 +335,20 @@ CResource* CResourceStore::LoadResource(const TString& rkPath)
CResourceEntry *pEntry = RegisterTransientResource(Type, ID, Dir, Name);
CResource *pRes = pEntry->Load(File);
if (pRes) mLoadedResources[ID] = pEntry;
else DeleteResourceEntry(pEntry);
if (!pRes) DeleteResourceEntry(pEntry);
mTransientLoadDir = OldTransientDir;
return pRes;
}
void CResourceStore::TrackLoadedResource(CResourceEntry *pEntry)
{
ASSERT(pEntry->IsLoaded());
ASSERT(mLoadedResources.find(pEntry->ID()) == mLoadedResources.end());
mLoadedResources[pEntry->ID()] = pEntry;
}
CFourCC CResourceStore::ResourceTypeByID(const CUniqueID& rkID, const TStringList& rkPossibleTypes) const
{
if (!rkID.IsValid()) return eInvalidResType;

View File

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

View File

@@ -94,14 +94,7 @@ void CVirtualDirectory::AddChild(const TWideString &rkPath, CResourceEntry *pEnt
if (rkPath.IsEmpty())
{
if (pEntry)
{
#if !PUBLIC_RELEASE
for (u32 iRes = 0; iRes < mResources.size(); iRes++)
ASSERT(mResources[iRes] != pEntry);
#endif
mResources.push_back(pEntry);
}
}
else