Files
FC1/Editor/BaseLibraryManager.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

438 lines
11 KiB
C++

////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: baselibrarymanager.cpp
// Version: v1.00
// Created: 10/6/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "BaseLibraryManager.h"
#include "BaseLibrary.h"
#include "BaseLibraryItem.h"
#include "ErrorReport.h"
//////////////////////////////////////////////////////////////////////////
// CBaseLibraryManager implementation.
//////////////////////////////////////////////////////////////////////////
CBaseLibraryManager::CBaseLibraryManager()
{
}
//////////////////////////////////////////////////////////////////////////
CBaseLibraryManager::~CBaseLibraryManager()
{
ClearAll();
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::ClearAll()
{
// Delete all items from all libraries.
for (int i = 0; i < m_libs.size(); i++)
{
m_libs[i]->RemoveAllItems();
}
m_itemsMap.clear();
m_libs.clear();
}
//////////////////////////////////////////////////////////////////////////
IDataBaseLibrary* CBaseLibraryManager::FindLibrary( const CString &library )
{
for (int i = 0; i < m_libs.size(); i++)
{
if (stricmp(library,m_libs[i]->GetName()) == 0)
{
return m_libs[i];
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CBaseLibraryManager::FindItem( REFGUID guid ) const
{
CBaseLibraryItem* pMtl = stl::find_in_map( m_itemsMap,guid,(CBaseLibraryItem*)0 );
return pMtl;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::SplitFullItemName( const CString &fullItemName,CString &libraryName,CString &itemName )
{
int p;
p = fullItemName.Find( '.' );
if (p < 0)
{
libraryName = "";
itemName = fullItemName;
return;
}
libraryName = fullItemName.Mid(0,p);
itemName = fullItemName.Mid(p+1);
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CBaseLibraryManager::FindItemByName( const CString &fullItemName )
{
CString libraryName,itemName;
SplitFullItemName( fullItemName,libraryName,itemName );
if (libraryName.IsEmpty())
{
Error( _T("Cannot Find Item, Library name must be specified before \".\" : %s"),(const char*)fullItemName );
return 0;
}
IDataBaseLibrary *lib = FindLibrary( libraryName );
if (!lib)
{
Error( _T("Cannot Find Library: %s"),(const char*)libraryName );
return 0;
}
return lib->FindItem( itemName );
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CBaseLibraryManager::CreateItem( IDataBaseLibrary *pLibrary )
{
assert( pLibrary );
// Add item to this library.
TSmartPtr<CBaseLibraryItem> pItem = MakeNewItem();
pLibrary->AddItem( pItem );
pItem->GenerateId();
return pItem;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::DeleteItem( IDataBaseItem* pItem )
{
assert( pItem );
m_itemsMap.erase( pItem->GetGUID() );
if (pItem->GetLibrary())
{
pItem->GetLibrary()->RemoveItem( pItem );
}
// Delete all objects from object manager that have
//GetIEditor()->GetObjectManager()->GetObjects( objects );
}
//////////////////////////////////////////////////////////////////////////
IDataBaseLibrary* CBaseLibraryManager::LoadLibrary( const CString &filename )
{
// If library is already loaded ignore it.
for (int i = 0; i < m_libs.size(); i++)
{
if (stricmp(filename,m_libs[i]->GetFilename()) == 0)
{
Error( _T("Loading Duplicate Library: %s"),(const char*)filename );
return 0;
}
}
TSmartPtr<CBaseLibrary> pLib = MakeNewLibrary();
if (!pLib->Load( filename ))
{
Error( _T("Failed to Load Item Library: %s"),(const char*)filename );
return 0;
}
if (FindLibrary(pLib->GetName()) != 0)
{
Error( _T("Loading Duplicate Library: %s"),(const char*)pLib->GetName() );
return 0;
}
m_libs.push_back( pLib );
return pLib;
}
//////////////////////////////////////////////////////////////////////////
IDataBaseLibrary* CBaseLibraryManager::AddLibrary( const CString &library )
{
// Check if library with same name already exist.
IDataBaseLibrary* pBaseLib = FindLibrary(library);
if (pBaseLib)
return pBaseLib;
CBaseLibrary *lib = MakeNewLibrary();
lib->SetName( library );
// Set filename of this library.
// Make a filename from name of library.
CString filename = library;
filename.Replace( ' ','_' );
filename = GetLibsPath() + filename + ".xml";
lib->SetFilename( filename );
m_libs.push_back( lib );
return lib;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::DeleteLibrary( const CString &library )
{
for (int i = 0; i < m_libs.size(); i++)
{
if (stricmp(library,m_libs[i]->GetName()) == 0)
{
CBaseLibrary *pLibrary = m_libs[i];
// Check if not level library, they cannot be deleted.
if (!pLibrary->IsLevelLibrary())
{
for (int j = 0; j < pLibrary->GetItemCount(); j++)
{
UnregisterItem( (CBaseLibraryItem*)pLibrary->GetItem(j) );
}
m_libs.erase( m_libs.begin() + i );
}
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
IDataBaseLibrary* CBaseLibraryManager::GetLibrary( int index ) const
{
assert( index >= 0 && index < m_libs.size() );
return m_libs[index];
};
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::SaveAllLibs()
{
for (int i = 0; i < GetLibraryCount(); i++)
{
// Check if library is modified.
IDataBaseLibrary *pLibrary = GetLibrary(i);
if (pLibrary->IsLevelLibrary())
continue;
if (pLibrary->IsModified())
{
if (pLibrary->Save())
{
pLibrary->SetModified(false);
}
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::Serialize( XmlNodeRef &node,bool bLoading )
{
CString rootNodeName = GetRootNodeName();
if (bLoading)
{
CString libsPath = GetLibsPath();
if (!libsPath.IsEmpty())
CFileUtil::CreateDirectory( libsPath );
XmlNodeRef libs = node->findChild( rootNodeName );
if (libs)
{
for (int i = 0; i < libs->getChildCount(); i++)
{
// Load only library name.
XmlNodeRef libNode = libs->getChild(i);
if (strcmp(libNode->getTag(),"LevelLibrary") == 0)
{
m_pLevelLibrary->Serialize( libNode,bLoading );
}
else
{
CString libName;
if (libNode->getAttr( "Name",libName ))
{
// Load this library.
CString filename = libName;
filename.Replace( ' ','_' );
filename = GetLibsPath() + filename + ".xml";
if (!FindLibrary(libName))
{
LoadLibrary( filename );
}
}
}
}
}
}
else
{
// Save all libraries.
XmlNodeRef libs = node->newChild( rootNodeName );
for (int i = 0; i < GetLibraryCount(); i++)
{
IDataBaseLibrary* pLib = GetLibrary(i);
if (pLib->IsLevelLibrary())
{
// Level libraries are saved in in level.
XmlNodeRef libNode = libs->newChild( "LevelLibrary" );
pLib->Serialize( libNode,bLoading );
}
else
{
// Save only library name.
XmlNodeRef libNode = libs->newChild( "Library" );
libNode->setAttr( "Name",pLib->GetName() );
}
}
SaveAllLibs();
}
}
//////////////////////////////////////////////////////////////////////////
CString CBaseLibraryManager::MakeUniqItemName( const CString &srcName )
{
// Remove all numbers from the end of name.
CString typeName = srcName;
int len = typeName.GetLength();
while (len > 0 && isdigit(typeName[len-1]))
len--;
typeName = typeName.Left(len);
CString tpName = typeName;
int num = 0;
for (ItemsMap::iterator it = m_itemsMap.begin(); it != m_itemsMap.end(); ++it)
{
CBaseLibraryItem *pItem = it->second;
const char *name = pItem->GetName();
if (strncmp(name,tpName,len) == 0)
{
int n = atoi(name+len) + 1;
num = MAX( num,n );
}
}
CString str;
str.Format( "%s%d",(const char*)typeName,num );
return str;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::Validate()
{
for (ItemsMap::iterator it = m_itemsMap.begin(); it != m_itemsMap.end(); ++it)
{
it->second->Validate();
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::RegisterItem( CBaseLibraryItem *pItem,REFGUID newGuid )
{
assert(pItem);
bool bNewItem = true;
REFGUID oldGuid = pItem->GetGUID();
if (!GuidUtil::IsEmpty(oldGuid))
{
bNewItem = false;
m_itemsMap.erase( oldGuid );
}
if (GuidUtil::IsEmpty(newGuid))
return;
CBaseLibraryItem *pOldItem = stl::find_in_map( m_itemsMap,newGuid,(CBaseLibraryItem*)0 );
if (!pOldItem)
{
pItem->m_guid = newGuid;
m_itemsMap[newGuid] = pItem;
}
else
{
if (pOldItem != pItem)
{
ReportDuplicateItem( pItem,pOldItem );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::RegisterItem( CBaseLibraryItem *pItem )
{
assert(pItem);
if (GuidUtil::IsEmpty(pItem->GetGUID()))
return;
CBaseLibraryItem *pOldItem = stl::find_in_map( m_itemsMap,pItem->GetGUID(),(CBaseLibraryItem*)0 );
if (!pOldItem)
{
m_itemsMap[pItem->GetGUID()] = pItem;
}
else
{
if (pOldItem != pItem)
{
ReportDuplicateItem( pItem,pOldItem );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::ReportDuplicateItem( CBaseLibraryItem *pItem,CBaseLibraryItem *pOldItem )
{
CString sLibName;
if (pOldItem->GetLibrary())
sLibName = pOldItem->GetLibrary()->GetName();
CErrorRecord err;
err.error.Format( "Item %s with duplicate GUID to loaded item %s ignored",(const char*)pItem->GetFullName(),(const char*)pOldItem->GetFullName() );
GetIEditor()->GetErrorReport()->ReportError( err );
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::UnregisterItem( CBaseLibraryItem *pItem )
{
m_itemsMap.erase( pItem->GetGUID() );
}
//////////////////////////////////////////////////////////////////////////
CString CBaseLibraryManager::MakeFullItemName( IDataBaseLibrary *pLibrary,const CString &group,const CString &itemName )
{
assert(pLibrary);
CString name = pLibrary->GetName() + ".";
if (!group.IsEmpty())
name += group + ".";
name += itemName;
return name;
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::GatherUsedResources( CUsedResources &resources )
{
for (int lib = 0; lib < GetLibraryCount(); lib++)
{
IDataBaseLibrary *pLib = GetLibrary(lib);
for (int i = 0; i < pLib->GetItemCount(); i++)
{
pLib->GetItem(i)->GatherUsedResources( resources );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::OnNewDocument()
{
ClearAll();
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::OnLoadDocument()
{
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::OnCloseDocument()
{
}
//////////////////////////////////////////////////////////////////////////
void CBaseLibraryManager::OnMissionChange()
{
}