From 94eb5b8ae277c8c4777f0f50e1eb3e00120216d7 Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Sun, 23 Jul 2017 19:35:18 -0700 Subject: [PATCH] Store library pieces in a map. --- common/lc_library.cpp | 149 +++++++++++++++++------------------ common/lc_library.h | 5 +- common/lc_model.cpp | 7 ++ common/lc_model.h | 1 + common/piece.cpp | 5 ++ common/piece.h | 2 + common/project.cpp | 5 ++ qt/lc_qfinddialog.cpp | 7 +- qt/lc_qpreferencesdialog.cpp | 14 ++-- qt/lc_qpropertiestree.cpp | 7 +- 10 files changed, 109 insertions(+), 93 deletions(-) diff --git a/common/lc_library.cpp b/common/lc_library.cpp index f66c7a11..865dc0a9 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -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& 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& 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& void lcPiecesLibrary::GetParts(lcArray& 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); diff --git a/common/lc_library.h b/common/lc_library.h index 41e9309c..d2457e7b 100644 --- a/common/lc_library.h +++ b/common/lc_library.h @@ -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& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize, Project* CurrentProject, bool SearchProjectFolder); @@ -188,7 +189,7 @@ public: void UpdateBuffers(lcContext* Context); void UnloadUnusedParts(); - lcArray mPieces; + std::map mPieces; std::map mPrimitives; int mNumOfficialPieces; diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 6d6f9155..8a5d1f37 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -2227,6 +2227,13 @@ void lcModel::SetPieceSteps(const QList>& PieceSteps) } } +void lcModel::RenamePiece(PieceInfo* Info) +{ + for (lcPiece* Piece : mPieces) + if (Piece->mPieceInfo == Info) + Piece->UpdateID(); +} + void lcModel::MoveSelectionToModel(lcModel* Model) { if (!Model) diff --git a/common/lc_model.h b/common/lc_model.h index 47faf939..3fc93368 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -181,6 +181,7 @@ public: void ShowSelectedPiecesEarlier(); void ShowSelectedPiecesLater(); void SetPieceSteps(const QList>& PieceSteps); + void RenamePiece(PieceInfo* Info); void MoveSelectionToModel(lcModel* Model); void InlineSelectedModels(); diff --git a/common/piece.cpp b/common/piece.cpp index db0c079e..48b97fdc 100644 --- a/common/piece.cpp +++ b/common/piece.cpp @@ -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"); diff --git a/common/piece.h b/common/piece.h index 77c136bf..8c15dd25 100644 --- a/common/piece.h +++ b/common/piece.h @@ -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); diff --git a/common/project.cpp b/common/project.cpp index e2333179..edb178a6 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -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; } diff --git a/qt/lc_qfinddialog.cpp b/qt/lc_qfinddialog.cpp index a1250ba4..ee781cdd 100644 --- a/qt/lc_qfinddialog.cpp +++ b/qt/lc_qfinddialog.cpp @@ -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; diff --git a/qt/lc_qpreferencesdialog.cpp b/qt/lc_qpreferencesdialog.cpp index d62cda13..a85fbc1a 100644 --- a/qt/lc_qpreferencesdialog.cpp +++ b/qt/lc_qpreferencesdialog.cpp @@ -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 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); } diff --git a/qt/lc_qpropertiestree.cpp b/qt/lc_qpropertiestree.cpp index 62db9ede..8f6cae37 100644 --- a/qt/lc_qpropertiestree.cpp +++ b/qt/lc_qpropertiestree.cpp @@ -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(); editor->setCurrentIndex(editor->findData(qVariantFromValue((void*)info)));