Store library pieces in a map.

This commit is contained in:
Leonardo Zide 2017-07-23 19:35:18 -07:00
parent 692604ee50
commit 94eb5b8ae2
10 changed files with 109 additions and 93 deletions

View file

@ -59,9 +59,9 @@ lcPiecesLibrary::~lcPiecesLibrary()
void lcPiecesLibrary::Unload()
{
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
delete mPieces[PieceIdx];
mPieces.RemoveAll();
for (const auto PieceIt : mPieces)
delete PieceIt.second;
mPieces.clear();
for (const auto PrimitiveIt : mPrimitives)
delete PrimitiveIt.second;
@ -82,27 +82,40 @@ void lcPiecesLibrary::RemoveTemporaryPieces()
{
QMutexLocker LoadLock(&mLoadMutex);
for (int PieceIdx = mPieces.GetSize() - 1; PieceIdx >= 0; PieceIdx--)
for (auto PieceIt = mPieces.begin(); PieceIt != mPieces.end();)
{
PieceInfo* Info = mPieces[PieceIdx];
PieceInfo* Info = PieceIt->second;
if (!Info->IsTemporary())
break;
if (Info->GetRefCount() == 0)
if (Info->IsTemporary() && Info->GetRefCount() == 0)
{
mPieces.RemoveIndex(PieceIdx);
PieceIt = mPieces.erase(PieceIt);
delete Info;
}
else
PieceIt++;
}
}
void lcPiecesLibrary::RemovePiece(PieceInfo* Info)
{
mPieces.Remove(Info);
for (auto PieceIt = mPieces.begin(); PieceIt != mPieces.end(); PieceIt++)
{
if (PieceIt->second == Info)
{
mPieces.erase(PieceIt);
break;
}
}
delete Info;
}
void lcPiecesLibrary::RenamePiece(PieceInfo* Info, const char* NewName)
{
mPieces.erase(Info->m_strName);
strcpy(Info->m_strName, NewName);
mPieces[Info->m_strName] = Info;
}
PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* CurrentProject, bool CreatePlaceholder, bool SearchProjectFolder)
{
QString ProjectPath;
@ -114,20 +127,14 @@ PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* CurrentPro
ProjectPath = QFileInfo(FileName).absolutePath();
}
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
const auto PieceIt = mPieces.find(PieceName);
if (PieceIt != mPieces.end())
{
PieceInfo* Info = mPieces[PieceIdx];
PieceInfo* Info = PieceIt->second;
if (strcmp(PieceName, Info->m_strName))
continue;
if (CurrentProject && Info->IsModel() && CurrentProject->GetModels().FindIndex(Info->GetModel()) == -1)
continue;
if (ProjectPath.isEmpty() && Info->IsProject())
continue;
return Info;
if ((!CurrentProject || !Info->IsModel() || CurrentProject->GetModels().FindIndex(Info->GetModel()) != -1) && (!ProjectPath.isEmpty() || !Info->IsProject()))
return Info;
}
if (!ProjectPath.isEmpty())
@ -143,7 +150,7 @@ PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* CurrentPro
PieceInfo* Info = new PieceInfo();
Info->SetProject(NewProject, PieceName);
mPieces.Add(Info);
mPieces[Info->m_strName] = Info;
return Info;
}
@ -157,7 +164,7 @@ PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* CurrentPro
PieceInfo* Info = new PieceInfo();
Info->CreatePlaceholder(PieceName);
mPieces.Add(Info);
mPieces[Info->m_strName] = Info;
return Info;
}
@ -330,10 +337,11 @@ bool lcPiecesLibrary::OpenArchive(lcFile* File, const QString& FileName, lcZipFi
if (!Info)
{
Info = new PieceInfo();
mPieces.Add(Info);
strncpy(Info->m_strName, Name, sizeof(Info->m_strName));
Info->m_strName[sizeof(Info->m_strName) - 1] = 0;
mPieces[Info->m_strName] = Info;
}
Info->SetZipFile(ZipFileType, FileIdx);
@ -390,16 +398,15 @@ void lcPiecesLibrary::ReadArchiveDescriptions(const QString& OfficialFileName, c
mArchiveCheckSum[3] = 0;
}
QString IndexFileName = QFileInfo(QDir(mCachePath), QLatin1String("index")).absoluteFilePath();
if (!LoadCacheIndex(IndexFileName))
{
lcMemFile PieceFile;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
PieceInfo* Info = PieceIt.second;
mZipFiles[Info->mZipFileType]->ExtractFile(Info->mZipFileIndex, PieceFile, 256);
PieceFile.Seek(0, SEEK_END);
@ -476,25 +483,25 @@ bool lcPiecesLibrary::OpenDirectory(const QDir& LibraryDir)
continue;
PieceInfo* Info = new PieceInfo();
mPieces.Add(Info);
strncpy(Info->m_strName, Line, sizeof(Info->m_strName));
Info->m_strName[sizeof(Info->m_strName) - 1] = 0;
strncpy(Info->m_strDescription, Description, sizeof(Info->m_strDescription));
Info->m_strDescription[sizeof(Info->m_strDescription) - 1] = 0;
mPieces[Info->m_strName] = Info;
}
}
const QLatin1String BaseFolders[] = { QLatin1String("unofficial/"), QLatin1String("") };
if (!mPieces.GetSize())
if (mPieces.empty())
{
for (unsigned int BaseFolderIdx = 0; BaseFolderIdx < sizeof(BaseFolders) / sizeof(BaseFolders[0]); BaseFolderIdx++)
{
QDir Dir(QDir(LibraryDir.absoluteFilePath(BaseFolders[BaseFolderIdx])).absoluteFilePath(QLatin1String("parts/")), QLatin1String("*.dat"), QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable);
QStringList FileList = Dir.entryList();
mPieces.AllocGrow(FileList.size());
for (int FileIdx = 0; FileIdx < FileList.size(); FileIdx++)
{
@ -524,22 +531,8 @@ bool lcPiecesLibrary::OpenDirectory(const QDir& LibraryDir)
continue;
*Dst = 0;
if (mHasUnofficial)
{
bool Skip = false;
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
{
if (!strcmp(Name, mPieces[PieceIdx]->m_strName))
{
Skip = true;
break;
}
}
if (Skip)
continue;
}
if (mHasUnofficial && mPieces.find(Name) != mPieces.end())
continue;
lcDiskFile PieceFile(Dir.absoluteFilePath(FileList[FileIdx]));
if (!PieceFile.Open(QIODevice::ReadOnly))
@ -550,7 +543,6 @@ bool lcPiecesLibrary::OpenDirectory(const QDir& LibraryDir)
continue;
PieceInfo* Info = new PieceInfo();
mPieces.Add(Info);
if (BaseFolderIdx == 0)
mHasUnofficial = true;
@ -572,11 +564,13 @@ bool lcPiecesLibrary::OpenDirectory(const QDir& LibraryDir)
strncpy(Info->m_strName, Name, sizeof(Info->m_strName));
Info->m_strName[sizeof(Info->m_strName) - 1] = 0;
mPieces[Info->m_strName] = Info;
}
}
}
if (!mPieces.GetSize())
if (mPieces.empty())
return false;
for (unsigned int BaseFolderIdx = 0; BaseFolderIdx < sizeof(BaseFolders) / sizeof(BaseFolders[0]); BaseFolderIdx++)
@ -838,12 +832,12 @@ bool lcPiecesLibrary::LoadCacheIndex(const QString& FileName)
qint32 NumFiles;
if (IndexFile.ReadBuffer((char*)&NumFiles, sizeof(NumFiles)) == 0 || NumFiles != mPieces.GetSize())
if (IndexFile.ReadBuffer((char*)&NumFiles, sizeof(NumFiles)) == 0 || NumFiles != mPieces.size())
return false;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
PieceInfo* Info = PieceIt.second;
quint8 Length;
if (IndexFile.ReadBuffer((char*)&Length, sizeof(Length)) == 0 || Length >= sizeof(Info->m_strDescription))
@ -862,14 +856,14 @@ bool lcPiecesLibrary::SaveCacheIndex(const QString& FileName)
{
lcMemFile IndexFile;
qint32 NumFiles = mPieces.GetSize();
qint32 NumFiles = mPieces.size();
if (IndexFile.WriteBuffer((char*)&NumFiles, sizeof(NumFiles)) == 0)
return false;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
PieceInfo* Info = PieceIt.second;
quint8 Length = (quint8)strlen(Info->m_strDescription);
if (IndexFile.WriteBuffer((char*)&Length, sizeof(Length)) == 0)
@ -1417,9 +1411,9 @@ void lcPiecesLibrary::UpdateBuffers(lcContext* Context)
int VertexDataSize = 0;
int IndexDataSize = 0;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
PieceInfo* Info = PieceIt.second;
lcMesh* Mesh = Info->IsPlaceholder() ? gPlaceholderMesh : Info->GetMesh();
if (!Mesh)
@ -1444,9 +1438,9 @@ void lcPiecesLibrary::UpdateBuffers(lcContext* Context)
VertexDataSize = 0;
IndexDataSize = 0;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
PieceInfo* Info = PieceIt.second;
lcMesh* Mesh = Info->IsPlaceholder() ? gPlaceholderMesh : Info->GetMesh();
if (!Mesh)
@ -1477,9 +1471,9 @@ void lcPiecesLibrary::UnloadUnusedParts()
{
QMutexLocker LoadLock(&mLoadMutex);
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
PieceInfo* Info = PieceIt.second;
if (Info->GetRefCount() == 0 && Info->mState != LC_PIECEINFO_UNLOADED)
ReleasePieceInfo(Info);
}
@ -1896,12 +1890,11 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
}
else
{
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
const auto PieceIt = mPieces.find(FileName);
if (strcmp(Info->m_strName, FileName))
continue;
if (PieceIt != mPieces.end())
{
PieceInfo* Info = PieceIt->second;
if (mZipFiles[LC_ZIPFILE_OFFICIAL] && Info->mZipFileType != LC_NUM_ZIPFILES)
{
@ -2731,9 +2724,9 @@ void lcPiecesLibrary::GetCategoryEntries(const char* CategoryKeywords, bool Grou
SinglePieces.RemoveAll();
GroupedPieces.RemoveAll();
for (int i = 0; i < mPieces.GetSize(); i++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[i];
PieceInfo* Info = PieceIt.second;
if (!PieceInCategory(Info, CategoryKeywords))
continue;
@ -2794,9 +2787,9 @@ void lcPiecesLibrary::GetPatternedPieces(PieceInfo* Parent, lcArray<PieceInfo*>&
Pieces.RemoveAll();
for (int i = 0; i < mPieces.GetSize(); i++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[i];
PieceInfo* Info = PieceIt.second;
if (strncmp(Name, Info->m_strName, strlen(Name)) == 0)
Pieces.Add(Info);
@ -2810,9 +2803,9 @@ void lcPiecesLibrary::GetPatternedPieces(PieceInfo* Parent, lcArray<PieceInfo*>&
if (Name[Len-1] < '0' || Name[Len-1] > '9')
Name[Len-1] = 'P';
for (int i = 0; i < mPieces.GetSize(); i++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[i];
PieceInfo* Info = PieceIt.second;
if (strncmp(Name, Info->m_strName, strlen(Name)) == 0)
Pieces.Add(Info);
@ -2822,7 +2815,11 @@ void lcPiecesLibrary::GetPatternedPieces(PieceInfo* Parent, lcArray<PieceInfo*>&
void lcPiecesLibrary::GetParts(lcArray<PieceInfo*>& Parts)
{
Parts = mPieces;
Parts.SetSize(0);
Parts.AllocGrow(mPieces.size());
for (const auto PartIt : mPieces)
Parts.Add(PartIt.second);
}
bool lcPiecesLibrary::LoadBuiltinPieces()
@ -2843,9 +2840,9 @@ bool lcPiecesLibrary::LoadBuiltinPieces()
lcMemFile PieceFile;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
for (const auto PieceIt : mPieces)
{
PieceInfo* Info = mPieces[PieceInfoIndex];
PieceInfo* Info = PieceIt.second;
mZipFiles[Info->mZipFileType]->ExtractFile(Info->mZipFileIndex, PieceFile, 256);
PieceFile.Seek(0, SEEK_END);

View file

@ -153,6 +153,7 @@ public:
void RemoveTemporaryPieces();
void RemovePiece(PieceInfo* Info);
void RenamePiece(PieceInfo* Info, const char* NewName);
PieceInfo* FindPiece(const char* PieceName, Project* Project, bool CreatePlaceholder, bool SearchProjectFolder);
void LoadPieceInfo(PieceInfo* Info, bool Wait, bool Priority);
void ReleasePieceInfo(PieceInfo* Info);
@ -179,7 +180,7 @@ public:
void SetOfficialPieces()
{
if (mZipFiles[LC_ZIPFILE_OFFICIAL])
mNumOfficialPieces = mPieces.GetSize();
mNumOfficialPieces = mPieces.size();
}
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize, Project* CurrentProject, bool SearchProjectFolder);
@ -188,7 +189,7 @@ public:
void UpdateBuffers(lcContext* Context);
void UnloadUnusedParts();
lcArray<PieceInfo*> mPieces;
std::map<std::string, PieceInfo*> mPieces;
std::map<std::string, lcLibraryPrimitive*> mPrimitives;
int mNumOfficialPieces;

View file

@ -2227,6 +2227,13 @@ void lcModel::SetPieceSteps(const QList<QPair<lcPiece*, lcStep>>& PieceSteps)
}
}
void lcModel::RenamePiece(PieceInfo* Info)
{
for (lcPiece* Piece : mPieces)
if (Piece->mPieceInfo == Info)
Piece->UpdateID();
}
void lcModel::MoveSelectionToModel(lcModel* Model)
{
if (!Model)

View file

@ -181,6 +181,7 @@ public:
void ShowSelectedPiecesEarlier();
void ShowSelectedPiecesLater();
void SetPieceSteps(const QList<QPair<lcPiece*, lcStep>>& PieceSteps);
void RenamePiece(PieceInfo* Info);
void MoveSelectionToModel(lcModel* Model);
void InlineSelectedModels();

View file

@ -95,6 +95,11 @@ void lcPiece::SetPieceInfo(PieceInfo* Info, const QString& ID, bool Wait)
}
}
void lcPiece::UpdateID()
{
mID = mPieceInfo->GetSaveID();
}
void lcPiece::SaveLDraw(QTextStream& Stream) const
{
QLatin1String LineEnding("\r\n");

View file

@ -389,6 +389,8 @@ public:
return mID;
}
void UpdateID();
const char* GetName() const override;
bool IsVisible(lcStep Step);
void Initialize(const lcMatrix44& WorldMatrix, lcStep Step);

View file

@ -219,6 +219,11 @@ void Project::ShowModelListDialog()
else if (Model->GetProperties().mName != it->first)
{
Model->SetName(it->first);
lcGetPiecesLibrary()->RenamePiece(Model->GetPieceInfo(), it->first.toUpper().toLatin1().constData());
for (lcModel* CheckModel : mModels)
CheckModel->RenamePiece(Model->GetPieceInfo());
mModified = true;
}

View file

@ -16,10 +16,9 @@ lcQFindDialog::lcQFindDialog(QWidget *parent, void *data) :
parts->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
parts->setMinimumContentsLength(1);
lcPiecesLibrary* library = lcGetPiecesLibrary();
for (int partIdx = 0; partIdx < library->mPieces.GetSize(); partIdx++)
parts->addItem(library->mPieces[partIdx]->m_strDescription, qVariantFromValue((void*)library->mPieces[partIdx]));
parts->model()->sort(0);
lcPiecesLibrary* Library = lcGetPiecesLibrary();
for (const auto PartIt : Library->mPieces)
parts->addItem(PartIt.second->m_strDescription, qVariantFromValue((void*)PartIt.second));
options = (lcSearchOptions*)data;

View file

@ -232,7 +232,7 @@ void lcQPreferencesDialog::updateCategories()
void lcQPreferencesDialog::updateParts()
{
lcPiecesLibrary *library = lcGetPiecesLibrary();
lcPiecesLibrary *Library = lcGetPiecesLibrary();
QTreeWidget *tree = ui->partsTree;
tree->clear();
@ -249,7 +249,7 @@ void lcQPreferencesDialog::updateParts()
{
lcArray<PieceInfo*> singleParts, groupedParts;
library->GetCategoryEntries(options->Categories[categoryIndex].Keywords.constData(), false, singleParts, groupedParts);
Library->GetCategoryEntries(options->Categories[categoryIndex].Keywords.constData(), false, singleParts, groupedParts);
for (int partIndex = 0; partIndex < singleParts.GetSize(); partIndex++)
{
@ -263,20 +263,20 @@ void lcQPreferencesDialog::updateParts()
}
else
{
for (int partIndex = 0; partIndex < library->mPieces.GetSize(); partIndex++)
for (const auto PartIt : Library->mPieces)
{
PieceInfo *info = library->mPieces[partIndex];
PieceInfo* Info = PartIt.second;
for (categoryIndex = 0; categoryIndex < options->Categories.GetSize(); categoryIndex++)
{
if (library->PieceInCategory(info, options->Categories[categoryIndex].Keywords.constData()))
if (Library->PieceInCategory(Info, options->Categories[categoryIndex].Keywords.constData()))
break;
}
if (categoryIndex == options->Categories.GetSize())
{
QStringList rowList(info->m_strDescription);
rowList.append(info->m_strName);
QStringList rowList(Info->m_strDescription);
rowList.append(Info->m_strName);
new QTreeWidgetItem(tree, rowList);
}

View file

@ -476,10 +476,9 @@ QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item)
editor->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
editor->setMinimumContentsLength(1);
lcPiecesLibrary* library = lcGetPiecesLibrary();
for (int partIdx = 0; partIdx < library->mPieces.GetSize(); partIdx++)
editor->addItem(library->mPieces[partIdx]->m_strDescription, qVariantFromValue((void*)library->mPieces[partIdx]));
editor->model()->sort(0);
lcPiecesLibrary* Library = lcGetPiecesLibrary();
for (const auto PartIt : Library->mPieces)
editor->addItem(PartIt.second->m_strDescription, qVariantFromValue((void*)PartIt.second));
PieceInfo *info = (PieceInfo*)item->data(0, PropertyValueRole).value<void*>();
editor->setCurrentIndex(editor->findData(qVariantFromValue((void*)info)));