From cb6a8361784a2eeaaf2632ea891688d83868f5f7 Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Mon, 27 May 2024 11:43:36 -0700 Subject: [PATCH] Use unique_ptr to control group ownership. --- common/group.cpp | 6 +- common/group.h | 4 +- common/lc_colors.h | 1 - common/lc_context.h | 1 - common/lc_global.h | 1 + common/lc_mainwindow.h | 1 - common/lc_model.cpp | 115 +++++++++++++++++++++---------------- common/lc_model.h | 4 +- common/lc_objectproperty.h | 2 - common/lc_scene.h | 1 - common/lc_synth.h | 1 + common/light.h | 1 + common/object.h | 1 - common/pieceinf.h | 1 - qt/lc_qselectdialog.cpp | 6 +- 15 files changed, 76 insertions(+), 70 deletions(-) diff --git a/common/group.cpp b/common/group.cpp index b64d9fc7..336d9582 100644 --- a/common/group.cpp +++ b/common/group.cpp @@ -21,12 +21,12 @@ void lcGroup::FileLoad(lcFile* File) mGroup = (lcGroup*)(quintptr)GroupIndex; } -void lcGroup::CreateName(const lcArray& Groups) +void lcGroup::CreateName(const std::vector>& Groups) { if (!mName.isEmpty()) { bool Found = false; - for (const lcGroup* const Group : Groups) + for (const std::unique_ptr& Group : Groups) { if (Group->mName == mName) { @@ -43,7 +43,7 @@ void lcGroup::CreateName(const lcArray& Groups) QString Prefix = QApplication::tr("Group #"); const int Length = Prefix.length(); - for (const lcGroup* const Group : Groups) + for (const std::unique_ptr& Group : Groups) { const QString& Name = Group->mName; diff --git a/common/group.h b/common/group.h index 5c7e66f4..a39534f9 100644 --- a/common/group.h +++ b/common/group.h @@ -1,7 +1,5 @@ #pragma once -#include "lc_array.h" - #define LC_MAX_GROUP_NAME 64 class lcGroup @@ -15,7 +13,7 @@ public: } void FileLoad(lcFile* File); - void CreateName(const lcArray& Groups); + void CreateName(const std::vector>& Groups); lcGroup* mGroup; QString mName; diff --git a/common/lc_colors.h b/common/lc_colors.h index 90fa9cf5..aa4a16f1 100644 --- a/common/lc_colors.h +++ b/common/lc_colors.h @@ -1,6 +1,5 @@ #pragma once -#include "lc_array.h" #include "lc_math.h" #define LC_MAX_COLOR_NAME 64 diff --git a/common/lc_context.h b/common/lc_context.h index ef8e1153..3709a33a 100644 --- a/common/lc_context.h +++ b/common/lc_context.h @@ -1,6 +1,5 @@ #pragma once -#include "lc_array.h" #include "lc_math.h" #include "lc_colors.h" #include "lc_mesh.h" diff --git a/common/lc_global.h b/common/lc_global.h index 6cd3cc0b..655df052 100644 --- a/common/lc_global.h +++ b/common/lc_global.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/common/lc_mainwindow.h b/common/lc_mainwindow.h index 30aab0bf..c3f78e89 100644 --- a/common/lc_mainwindow.h +++ b/common/lc_mainwindow.h @@ -2,7 +2,6 @@ #include "lc_application.h" #include "lc_shortcuts.h" -#include "lc_array.h" #include "lc_commands.h" #include "lc_model.h" diff --git a/common/lc_model.cpp b/common/lc_model.cpp index e59246df..ea951f2b 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -285,7 +285,7 @@ void lcModel::DeleteModel() mPieces.DeleteAll(); mCameras.DeleteAll(); mLights.DeleteAll(); - mGroups.DeleteAll(); + mGroups.clear(); mFileLines.clear(); } @@ -349,7 +349,7 @@ void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly, lcStep LastStep) mProperties.SaveLDraw(Stream); - lcArray CurrentGroups; + std::vector CurrentGroups; lcStep Step = 1; int CurrentLine = 0; int AddedSteps = 0; @@ -407,33 +407,33 @@ void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly, lcStep LastStep) { if (CurrentGroups.empty() || (!CurrentGroups.empty() && PieceGroup != CurrentGroups[CurrentGroups.size() - 1])) { - lcArray PieceParents; + std::deque PieceParents; for (lcGroup* Group = PieceGroup; Group; Group = Group->mGroup) - PieceParents.InsertAt(0, Group); + PieceParents.push_front(Group); - int FoundParent = -1; + std::deque::iterator ParentsToAdd = PieceParents.begin(); while (!CurrentGroups.empty()) { - lcGroup* Group = CurrentGroups[CurrentGroups.size() - 1]; - const int Index = PieceParents.FindIndex(Group); + lcGroup* Group = CurrentGroups.back(); + const std::deque::iterator ParentFound = std::find(PieceParents.begin(), PieceParents.end(), Group); - if (Index == -1) + if (ParentFound == PieceParents.end()) { - CurrentGroups.RemoveIndex(CurrentGroups.size() - 1); + CurrentGroups.pop_back(); Stream << QLatin1String("0 !LEOCAD GROUP END\r\n"); } else { - FoundParent = Index; + ParentsToAdd = ParentFound + 1; break; } } - for (int ParentIdx = FoundParent + 1; ParentIdx < PieceParents.size(); ParentIdx++) + for (std::deque::iterator ParentIt = ParentsToAdd; ParentIt != PieceParents.end(); ParentIt++) { - lcGroup* Group = PieceParents[ParentIdx]; + lcGroup* Group = *ParentIt; CurrentGroups.emplace_back(Group); Stream << QLatin1String("0 !LEOCAD GROUP BEGIN ") << Group->mName << LineEnding; } @@ -443,7 +443,7 @@ void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly, lcStep LastStep) { while (CurrentGroups.size()) { - CurrentGroups.RemoveIndex(CurrentGroups.size() - 1); + CurrentGroups.pop_back(); Stream << QLatin1String("0 !LEOCAD GROUP END\r\n"); } } @@ -497,7 +497,7 @@ void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly, lcStep LastStep) while (CurrentGroups.size()) { - CurrentGroups.RemoveIndex(CurrentGroups.size() - 1); + CurrentGroups.pop_back(); Stream << QLatin1String("0 !LEOCAD GROUP END\r\n"); } @@ -556,7 +556,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project) lcPiece* Piece = nullptr; lcCamera* Camera = nullptr; lcLight* Light = nullptr; - lcArray CurrentGroups; + std::vector CurrentGroups; std::vector ControlPoints; int CurrentStep = 1; lcPiecesLibrary* Library = lcGetPiecesLibrary(); @@ -680,7 +680,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project) else if (Token == QLatin1String("END")) { if (!CurrentGroups.empty()) - CurrentGroups.RemoveIndex(CurrentGroups.size() - 1); + CurrentGroups.pop_back(); } } else if (Token == QLatin1String("SYNTH")) @@ -919,15 +919,15 @@ bool lcModel::LoadBinary(lcFile* file) if (fv >= 0.5f) { - const int NumGroups = mGroups.size(); + const size_t NumGroups = mGroups.size(); file->ReadS32(&count, 1); for (i = 0; i < count; i++) mGroups.emplace_back(new lcGroup()); - for (int GroupIdx = NumGroups; GroupIdx < mGroups.size(); GroupIdx++) + for (size_t GroupIdx = NumGroups; GroupIdx < mGroups.size(); GroupIdx++) { - lcGroup* Group = mGroups[GroupIdx]; + lcGroup* Group = mGroups[GroupIdx].get(); if (fv < 1.0f) { @@ -941,9 +941,9 @@ bool lcModel::LoadBinary(lcFile* file) Group->FileLoad(file); } - for (int GroupIdx = NumGroups; GroupIdx < mGroups.size(); GroupIdx++) + for (size_t GroupIdx = NumGroups; GroupIdx < mGroups.size(); GroupIdx++) { - lcGroup* Group = mGroups[GroupIdx]; + lcGroup* Group = mGroups[GroupIdx].get(); i = (qint32)(quintptr)(Group->mGroup); Group->mGroup = nullptr; @@ -951,7 +951,7 @@ bool lcModel::LoadBinary(lcFile* file) if (i > 0xFFFF || i == -1) continue; - Group->mGroup = mGroups[NumGroups + i]; + Group->mGroup = mGroups[NumGroups + i].get(); } for (int PieceIdx = FirstNewPiece; PieceIdx < mPieces.size(); PieceIdx++) @@ -964,7 +964,7 @@ bool lcModel::LoadBinary(lcFile* file) if (i > 0xFFFF || i == -1) continue; - Piece->SetGroup(mGroups[NumGroups + i]); + Piece->SetGroup(mGroups[NumGroups + i].get()); } RemoveEmptyGroups(); @@ -1166,14 +1166,14 @@ void lcModel::Merge(lcModel* Other) Other->mLights.RemoveAll(); - for (int GroupIdx = 0; GroupIdx < Other->mGroups.size(); GroupIdx++) + for (std::vector>::iterator GroupIt = Other->mGroups.begin(); GroupIt != Other->mGroups.end(); GroupIt++) { - lcGroup* Group = Other->mGroups[GroupIdx]; + std::unique_ptr& Group = *GroupIt; Group->CreateName(mGroups); - mGroups.emplace_back(Group); + mGroups.emplace_back(std::move(Group)); } - Other->mGroups.RemoveAll(); + Other->mGroups.clear(); delete Other; @@ -1919,9 +1919,9 @@ lcGroup* lcModel::AddGroup(const QString& Prefix, lcGroup* Parent) lcGroup* lcModel::GetGroup(const QString& Name, bool CreateIfMissing) { - for (lcGroup* Group : mGroups) + for (const std::unique_ptr& Group : mGroups) if (Group->mName == Name) - return Group; + return Group.get(); if (CreateIfMissing) { @@ -1937,8 +1937,14 @@ lcGroup* lcModel::GetGroup(const QString& Name, bool CreateIfMissing) void lcModel::RemoveGroup(lcGroup* Group) { - mGroups.Remove(Group); - delete Group; + for (std::vector>::iterator GroupIt = mGroups.begin(); GroupIt != mGroups.end(); GroupIt++) + { + if (GroupIt->get() == Group) + { + mGroups.erase(GroupIt); + break; + } + } } void lcModel::GroupSelection() @@ -1973,7 +1979,7 @@ void lcModel::GroupSelection() void lcModel::UngroupSelection() { - lcArray SelectedGroups; + std::set SelectedGroups; for (lcPiece* Piece : mPieces) { @@ -1981,10 +1987,17 @@ void lcModel::UngroupSelection() { lcGroup* Group = Piece->GetTopGroup(); - if (SelectedGroups.FindIndex(Group) == -1) + if (SelectedGroups.insert(Group).second) { - mGroups.Remove(Group); - SelectedGroups.emplace_back(Group); + for (std::vector>::iterator GroupIt = mGroups.begin(); GroupIt != mGroups.end(); GroupIt++) + { + if (GroupIt->get() == Group) + { + GroupIt->release(); + mGroups.erase(GroupIt); + break; + } + } } } } @@ -1993,15 +2006,16 @@ void lcModel::UngroupSelection() { lcGroup* Group = Piece->GetGroup(); - if (SelectedGroups.FindIndex(Group) != -1) + if (SelectedGroups.find(Group) != SelectedGroups.end()) Piece->SetGroup(nullptr); } - for (lcGroup* Group : mGroups) - if (SelectedGroups.FindIndex(Group->mGroup) != -1) + for (const std::unique_ptr& Group : mGroups) + if (SelectedGroups.find(Group->mGroup) != SelectedGroups.end()) Group->mGroup = nullptr; - SelectedGroups.DeleteAll(); + for (lcGroup* Group : SelectedGroups) + delete Group; RemoveEmptyGroups(); SaveCheckpoint(tr("Ungrouping")); @@ -2060,8 +2074,8 @@ void lcModel::ShowEditGroupsDialog() for (lcPiece* Piece : mPieces) PieceParents[Piece] = Piece->GetGroup(); - for (lcGroup* Group : mGroups) - GroupParents[Group] = Group->mGroup; + for (const std::unique_ptr& Group : mGroups) + GroupParents[Group.get()] = Group->mGroup; lcQEditGroupsDialog Dialog(gMainWindow, PieceParents, GroupParents, this); @@ -2081,9 +2095,9 @@ void lcModel::ShowEditGroupsDialog() } } - for (lcGroup* Group : mGroups) + for (const std::unique_ptr& Group : mGroups) { - lcGroup* ParentGroup = Dialog.mGroupParents.value(Group); + lcGroup* ParentGroup = Dialog.mGroupParents.value(Group.get()); if (ParentGroup != Group->mGroup) { @@ -2104,7 +2118,7 @@ QString lcModel::GetGroupName(const QString& Prefix) const int Length = Prefix.length(); int Max = 0; - for (const lcGroup* Group : mGroups) + for (const std::unique_ptr& Group : mGroups) { const QString& Name = Group->mName; @@ -2128,22 +2142,22 @@ void lcModel::RemoveEmptyGroups() { Removed = false; - for (int GroupIdx = 0; GroupIdx < mGroups.size();) + for (std::vector>::iterator GroupIt = mGroups.begin(); GroupIt != mGroups.end();) { - lcGroup* Group = mGroups[GroupIdx]; + lcGroup* Group = GroupIt->get(); int Ref = 0; for (lcPiece* Piece : mPieces) if (Piece->GetGroup() == Group) Ref++; - for (int ParentIdx = 0; ParentIdx < mGroups.size(); ParentIdx++) + for (size_t ParentIdx = 0; ParentIdx < mGroups.size(); ParentIdx++) if (mGroups[ParentIdx]->mGroup == Group) Ref++; if (Ref > 1) { - GroupIdx++; + GroupIt++; continue; } @@ -2158,7 +2172,7 @@ void lcModel::RemoveEmptyGroups() } } - for (int ParentIdx = 0; ParentIdx < mGroups.size(); ParentIdx++) + for (size_t ParentIdx = 0; ParentIdx < mGroups.size(); ParentIdx++) { if (mGroups[ParentIdx]->mGroup == Group) { @@ -2168,8 +2182,7 @@ void lcModel::RemoveEmptyGroups() } } - mGroups.RemoveIndex(GroupIdx); - delete Group; + GroupIt = mGroups.erase(GroupIt); Removed = true; } } diff --git a/common/lc_model.h b/common/lc_model.h index 8f98dee1..f4a4745c 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -150,7 +150,7 @@ public: return mLights; } - const lcArray& GetGroups() const + const std::vector>& GetGroups() const { return mGroups; } @@ -406,7 +406,7 @@ protected: lcArray mPieces; lcArray mCameras; lcArray mLights; - lcArray mGroups; + std::vector> mGroups; QStringList mFileLines; lcModelHistoryEntry* mSavedHistory; diff --git a/common/lc_objectproperty.h b/common/lc_objectproperty.h index 72c5015b..a89e9c8f 100644 --- a/common/lc_objectproperty.h +++ b/common/lc_objectproperty.h @@ -1,7 +1,5 @@ #pragma once -#include "lc_array.h" - enum class lcObjectPropertyId { PieceId, diff --git a/common/lc_scene.h b/common/lc_scene.h index 951fe55a..046cd30d 100644 --- a/common/lc_scene.h +++ b/common/lc_scene.h @@ -1,7 +1,6 @@ #pragma once #include "lc_mesh.h" -#include "lc_array.h" enum class lcRenderMeshState : int { diff --git a/common/lc_synth.h b/common/lc_synth.h index 1644c308..41eb35e8 100644 --- a/common/lc_synth.h +++ b/common/lc_synth.h @@ -1,6 +1,7 @@ #pragma once #include "lc_math.h" +#include "lc_array.h" #include "piece.h" class lcLibraryMeshData; diff --git a/common/light.h b/common/light.h index 71a05309..629cb92b 100644 --- a/common/light.h +++ b/common/light.h @@ -2,6 +2,7 @@ #include "object.h" #include "lc_math.h" +#include "lc_array.h" #define LC_LIGHT_HIDDEN 0x0001 #define LC_LIGHT_DISABLED 0x0002 diff --git a/common/object.h b/common/object.h index 8452bd23..e6e0ad77 100644 --- a/common/object.h +++ b/common/object.h @@ -1,7 +1,6 @@ #pragma once #include "lc_math.h" -#include "lc_array.h" #include "lc_objectproperty.h" enum class lcObjectType diff --git a/common/pieceinf.h b/common/pieceinf.h index 93cf43bf..908a275f 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -2,7 +2,6 @@ #include #include "lc_math.h" -#include "lc_array.h" enum class lcPieceInfoType { diff --git a/qt/lc_qselectdialog.cpp b/qt/lc_qselectdialog.cpp index 668498c8..6239222a 100644 --- a/qt/lc_qselectdialog.cpp +++ b/qt/lc_qselectdialog.cpp @@ -171,16 +171,16 @@ void lcQSelectDialog::itemChanged(QTreeWidgetItem *item, int column) void lcQSelectDialog::AddChildren(QTreeWidgetItem* ParentItem, lcGroup* ParentGroup, lcModel* Model) { - const lcArray& Groups = Model->GetGroups(); + const std::vector>& Groups = Model->GetGroups(); - for (lcGroup* Group : Groups) + for (const std::unique_ptr& Group : Groups) { if (Group->mGroup != ParentGroup) continue; QTreeWidgetItem* GroupItem = new QTreeWidgetItem(ParentItem, QStringList(Group->mName)); - AddChildren(GroupItem, Group, Model); + AddChildren(GroupItem, Group.get(), Model); } const lcArray& Pieces = Model->GetPieces();