Wed, 15 Jun 2022 12:32:50 +0300
Fix crash involving polygon being too empty
24 | 1 | /* |
2 | * LDForge: LDraw parts authoring CAD | |
3 | * Copyright (C) 2013 - 2020 Teemu Piippo | |
4 | * | |
5 | * This program is free software: you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation, either version 3 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
19 | #include <QFile> |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
20 | #include <QDir> |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
21 | #include <QFileInfo> |
148 | 22 | #include <QSaveFile> |
213
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
23 | #include <deque> |
3 | 24 | #include "documentmanager.h" |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
25 | #include "parser.h" |
3 | 26 | |
214
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
27 | DocumentManager::DocumentManager(QObject *parent) : |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
28 | QObject{parent} |
5 | 29 | { |
30 | } | |
31 | ||
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
32 | /** |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
33 | * @brief Creates a new model. |
148 | 34 | * @returns the ID of the new model |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
35 | */ |
148 | 36 | ModelId DocumentManager::newModel() |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
37 | { |
148 | 38 | const ModelId modelId{++this->modelIdCounter}; |
214
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
39 | this->openModels.emplace(std::make_pair(modelId, ModelInfo{ |
217
6d95c1a41e6e
reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
214
diff
changeset
|
40 | .model = std::make_unique<Model>(this), |
214
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
41 | .id = modelId, |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
42 | .opentype = OpenType::ManuallyOpened, |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
43 | })); |
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
44 | this->makePolygonCacheForModel(modelId); |
148 | 45 | return modelId; |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
46 | } |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
47 | |
148 | 48 | Model* DocumentManager::findDependencyByName(const ModelId modelId, const QString& name) |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
49 | { |
148 | 50 | const auto modelsIterator = this->openModels.find(modelId); |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
51 | if (modelsIterator != std::end(this->openModels)) { |
148 | 52 | const auto& dependencies = modelsIterator->second.dependencies; |
53 | const auto dependenciesIterator = dependencies.find(name); | |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
54 | if (dependenciesIterator != dependencies.end()) { |
148 | 55 | ModelInfo& modelInfo = this->openModels[dependenciesIterator->second]; |
56 | return modelInfo.model.get(); | |
57 | } | |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
58 | else { |
148 | 59 | return nullptr; |
60 | } | |
61 | } | |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
62 | else { |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
63 | return nullptr; |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
64 | } |
148 | 65 | } |
66 | ||
67 | /** | |
68 | * @brief Gets a model pointer by id or nullptr if not found | |
69 | * @param modelId id of model to find | |
70 | * @returns model pointer or null | |
71 | */ | |
72 | Model *DocumentManager::getModelById(ModelId modelId) | |
73 | { | |
74 | const auto iterator = this->openModels.find(modelId); | |
75 | if (iterator != this->openModels.end()) | |
76 | { | |
77 | return iterator->second.model.get(); | |
78 | } | |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
79 | else |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
80 | { |
148 | 81 | return nullptr; |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
82 | } |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
83 | } |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
84 | |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
85 | QString pathToName(const QFileInfo& path) |
3 | 86 | { |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
87 | static const char* paths[] = { |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
88 | "s", |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
89 | "48" |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
90 | "8" |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
91 | }; |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
92 | const QString baseName = path.fileName(); |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
93 | const QString dirName = QFileInfo{path.dir().path()}.fileName(); |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
94 | QString result; |
17 | 95 | if (std::find(std::begin(paths), std::end(paths), dirName) != std::end(paths)) |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
96 | { |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
97 | result = dirName + "\\" + baseName; |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
98 | } |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
99 | else |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
100 | { |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
101 | result = baseName; |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
102 | } |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
103 | return result; |
3 | 104 | } |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
105 | |
147 | 106 | /** |
107 | * @brief Tries to open the model at the specified path | |
108 | * @param path Path to the model to open | |
109 | * @param errorStream Where to write any errors | |
110 | * @param openType rationale behind opening this file | |
148 | 111 | * @returns model id, or no value on error |
147 | 112 | */ |
148 | 113 | std::optional<ModelId> DocumentManager::openModel( |
114 | const QString& path, | |
115 | QTextStream& errorStream, | |
116 | const OpenType openType | |
117 | ) { | |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
118 | QFile file{path}; |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
119 | const QString name = pathToName(path); |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
120 | file.open(QFile::ReadOnly | QFile::Text); |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
121 | std::unique_ptr<Model> newModel = std::make_unique<Model>(nullptr); |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
122 | QTextStream textStream{&file}; |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
123 | Parser parser{file}; |
152 | 124 | parser.parseBody(*newModel); |
148 | 125 | std::optional<ModelId> result; |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
126 | if (file.error() == QFile::NoError) |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
127 | { |
148 | 128 | const ModelId modelId{++this->modelIdCounter}; |
214
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
129 | this->openModels.emplace(std::make_pair(modelId, ModelInfo{ |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
130 | .model = std::move(newModel), |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
131 | .id = modelId, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
132 | .path = path, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
133 | .opentype = openType, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
134 | .polygonCache = {}, |
214
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
135 | })); |
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
136 | this->makePolygonCacheForModel(modelId); |
148 | 137 | result = modelId; |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
138 | } |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
139 | else |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
140 | { |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
141 | errorStream << file.errorString(); |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
142 | } |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
143 | return result; |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
144 | } |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
145 | |
148 | 146 | void DocumentManager::closeDocument(const ModelId modelId) |
147 | { | |
148 | ModelInfo* modelInfo = findInMap(this->openModels, modelId); | |
149 | if (modelInfo != nullptr) | |
150 | { | |
151 | modelInfo->opentype = OpenType::AutomaticallyOpened; | |
152 | this->prune(); | |
153 | } | |
154 | } | |
155 | ||
156 | const QString *DocumentManager::modelPath(ModelId modelId) const | |
157 | { | |
158 | const auto iterator = this->openModels.find(modelId); | |
159 | if (iterator != this->openModels.end()) | |
160 | { | |
161 | return &iterator->second.path; | |
162 | } | |
163 | else | |
164 | { | |
165 | return nullptr; | |
166 | } | |
167 | } | |
168 | ||
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
169 | //! \brief Changes the path of the specified model. This can cause dependencies |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
170 | //! to be resolved differently. As such, dependencies need to be resolved for |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
171 | //! all files after this operation. |
148 | 172 | void DocumentManager::setModelPath( |
173 | const ModelId modelId, | |
174 | const QString &newPath, | |
175 | const LibraryManager &libraries, | |
176 | QTextStream &errorStream) | |
177 | { | |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
178 | ModelInfo* info = findInMap(this->openModels, modelId); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
179 | if (info != nullptr and info->opentype == OpenType::ManuallyOpened) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
180 | info->path = newPath; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
181 | const MissingDependencies missing = this->loadDependenciesForAllModels(libraries); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
182 | if (not missing.empty()) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
183 | errorStream << errorStringFromMissingDependencies(missing); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
184 | } |
12 | 185 | } |
186 | } | |
187 | ||
148 | 188 | bool DocumentManager::saveModel(const ModelId modelId, QTextStream &errors) |
147 | 189 | { |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
190 | ModelInfo* info = findInMap(this->openModels, modelId); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
191 | if (info != nullptr) |
147 | 192 | { |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
193 | QSaveFile file{info->path}; |
148 | 194 | file.setDirectWriteFallback(true); |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
195 | if (file.open(QSaveFile::WriteOnly)) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
196 | ::save(info->model.get(), &file); |
148 | 197 | const bool commitSucceeded = file.commit(); |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
198 | if (not commitSucceeded) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
199 | errors << QObject::tr("Could not save: %1").arg(file.errorString()); |
148 | 200 | return false; |
201 | } | |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
202 | else { |
148 | 203 | return true; |
204 | } | |
205 | } | |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
206 | else { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
207 | errors << QObject::tr("Could not open %1 for writing: %2") |
206
654661eab7f3
More refactor, merged main.h, basics.h and utility.h into one header file basics.h and removed plenty of unused code
Teemu Piippo <teemu@hecknology.net>
parents:
201
diff
changeset
|
208 | .arg(file.fileName(), file.errorString()); |
148 | 209 | return false; |
147 | 210 | } |
211 | } | |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
212 | else { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
213 | errors << QObject::tr("Bad model ID %1").arg(modelId.value); |
148 | 214 | return false; |
215 | } | |
147 | 216 | } |
217 | ||
148 | 218 | /** |
219 | * @brief Searches the open models for the specified model and returns its id if found | |
220 | * @param model model to look for | |
221 | * @return id or no value if not found | |
222 | */ | |
223 | std::optional<ModelId> DocumentManager::findIdForModel(const Model *model) const | |
147 | 224 | { |
148 | 225 | std::optional<ModelId> result; |
226 | for (auto it = this->openModels.begin(); it != this->openModels.end(); ++it) | |
147 | 227 | { |
148 | 228 | if (it->second.model.get() == model) |
147 | 229 | { |
148 | 230 | result = it->first; |
231 | break; | |
232 | } | |
233 | } | |
234 | return result; | |
235 | } | |
236 | ||
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
237 | PolygonCache *DocumentManager::getPolygonCacheForModel(ModelId modelId) |
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
238 | { |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
239 | ModelInfo* info = findInMap(this->openModels, modelId); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
240 | if (info != nullptr) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
241 | return &info->polygonCache; |
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
242 | } |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
243 | else { |
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
244 | return nullptr; |
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
245 | } |
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
246 | } |
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
247 | |
214
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
248 | const DocumentManager::ModelInfo *DocumentManager::find(ModelId modelId) const |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
249 | { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
250 | return findInMap(this->openModels, modelId); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
251 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
252 | |
214
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
253 | void DocumentManager::setModelPayload(ModelId modelId, QObject *object) |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
254 | { |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
255 | ModelInfo* info = findInMap(this->openModels, modelId); |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
256 | if (info != nullptr) { |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
257 | info->payload = object; |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
258 | object->setParent(this); |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
259 | } |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
260 | } |
8e1fe64ce4e3
begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
213
diff
changeset
|
261 | |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
262 | QString errorStringFromMissingDependencies(const DocumentManager::MissingDependencies& missing) |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
263 | { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
264 | QString missingString; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
265 | forValueInMap(missing, [&missingString](const QString& path){ |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
266 | missingString = joined(missingString, QStringLiteral(", "), path); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
267 | }); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
268 | return QObject::tr("The following files could not be opened: %1") |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
269 | .arg(missingString); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
270 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
271 | |
213
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
272 | template<typename T, typename K> |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
273 | void removeFromSet(std::set<T>& set, K&& valueToRemove) |
148 | 274 | { |
213
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
275 | const auto it = std::lower_bound(set.begin(), set.end(), valueToRemove); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
276 | if (it != set.end() and *it == valueToRemove) { |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
277 | set.erase(it); |
148 | 278 | } |
279 | } | |
280 | ||
213
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
281 | //! @brief Cleans up and erases models that are no longer required. |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
282 | void DocumentManager::prune() |
148 | 283 | { |
213
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
284 | Graph<ModelId> dependencyGraph; |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
285 | forValueInMap(this->openModels, [&dependencyGraph](const ModelInfo& info) { |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
286 | forValueInMap(info.dependencies, [&dependencyGraph, &info](ModelId dep){ |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
287 | dependencyGraph.push_back({.from = info.id, .to = dep}); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
288 | }); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
289 | }); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
290 | std::set<ModelId> autoOpened; |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
291 | forValueInMap(this->openModels, [&autoOpened](const ModelInfo& info) { |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
292 | if (info.opentype == OpenType::AutomaticallyOpened) { |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
293 | autoOpened.insert(info.id); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
294 | } |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
295 | }); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
296 | bool repeat = true; |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
297 | while (repeat) { |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
298 | repeat = false; |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
299 | std::set<ModelId> prunable = autoOpened; |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
300 | for (const auto& pair : dependencyGraph) { |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
301 | removeFromSet(prunable, pair.to); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
302 | } |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
303 | for (ModelId idToPrune : prunable) { |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
304 | auto it = this->openModels.find(idToPrune); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
305 | if (it != this->openModels.end()) { |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
306 | this->openModels.erase(it); |
147 | 307 | } |
213
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
308 | removeFromSet(autoOpened, idToPrune); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
309 | std::erase_if(dependencyGraph, [&idToPrune](const GraphEdge<ModelId>& edge) { |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
310 | return edge.from == idToPrune; |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
311 | }); |
ee5758ddb6d2
Rewrite prune to use graphs rather than O(n²) searches
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
212
diff
changeset
|
312 | repeat = true; |
148 | 313 | } |
147 | 314 | } |
315 | } | |
316 | ||
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
317 | void DocumentManager::makePolygonCacheForModel(const ModelId modelId) |
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
318 | { |
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
319 | Model* model = this->getModelById(modelId); |
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
320 | if (model != nullptr) |
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
321 | { |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
322 | const auto modelModified = [this, model]{ |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
323 | const std::optional<ModelId> modelId = this->findIdForModel(model); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
324 | if (modelId.has_value()) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
325 | ModelInfo* info = findInMap(this->openModels, *modelId); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
326 | if (info != nullptr) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
327 | info->polygonCache.needRecache = true; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
328 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
329 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
330 | }; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
331 | QObject::connect(model, &Model::dataChanged, modelModified); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
332 | QObject::connect(model, &Model::rowsInserted, modelModified); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
333 | QObject::connect(model, &Model::rowsRemoved, modelModified); |
193 | 334 | } |
335 | } | |
336 | ||
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
337 | static QString findFile( |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
338 | QString referenceName, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
339 | const QString& modelPath, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
340 | const LibraryManager& libraries) |
23
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
341 | { |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
342 | // Try to find the file in the same place as the model itself |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
343 | referenceName.replace("\\", "/"); |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
344 | const QDir dir = QFileInfo{modelPath}.dir(); |
23
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
345 | QString referencedFilePath = dir.filePath(referenceName); |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
346 | if (not QFileInfo{referencedFilePath}.exists()) |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
347 | { |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
348 | // Look for it in the libraries |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
349 | referencedFilePath = libraries.findFile(referenceName); |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
350 | } |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
351 | return referencedFilePath; |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
352 | } |
3387a84ddaba
fixed a pile of nonsense that caused subfiles to go haywire
Teemu Piippo <teemu@hecknology.net>
parents:
17
diff
changeset
|
353 | |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
354 | static std::set<QString> referenceNames(const Model* model) |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
355 | { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
356 | std::set<QString> result; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
357 | iterate<Colored<SubfileReference>>(*model, [&result](const SubfileReference& ref){ |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
358 | result.insert(ref.name); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
359 | }); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
360 | return result; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
361 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
362 | |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
363 | struct Dependency |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
364 | { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
365 | QString name; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
366 | QString path; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
367 | bool operator<(const Dependency& other) const |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
368 | { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
369 | if (this->name != other.name) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
370 | return this->name < other.name; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
371 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
372 | else { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
373 | return this->path < other.path; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
374 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
375 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
376 | }; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
377 | |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
378 | static std::set<Dependency> resolveReferencePaths( |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
379 | const DocumentManager::ModelInfo* modelInfo, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
380 | const LibraryManager* libraries) |
200 | 381 | { |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
382 | std::set<Dependency> result; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
383 | const std::set<QString> refNames = referenceNames(modelInfo->model.get()); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
384 | if (modelInfo != nullptr) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
385 | for (const QString& name : refNames) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
386 | const QString path = findFile(name, modelInfo->path, *libraries); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
387 | if (not path.isEmpty()) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
388 | result.insert(Dependency{.name = name, .path = path}); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
389 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
390 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
391 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
392 | return result; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
393 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
394 | |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
395 | static void loadDependenciesForModel( |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
396 | DocumentManager::ModelInfo* info, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
397 | DocumentManager* documents, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
398 | const LibraryManager* libraries, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
399 | std::map<QString, QString>& missing) |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
400 | { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
401 | bool repeat = true; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
402 | info->dependencies.clear(); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
403 | while (repeat) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
404 | repeat = false; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
405 | const std::set<Dependency> dependencies = resolveReferencePaths(info, libraries); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
406 | for (const Dependency& dep : dependencies) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
407 | if (not info->dependencies.contains(dep.name) and not missing.contains(dep.path)) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
408 | QString loadErrorString; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
409 | QTextStream localErrorStream{&loadErrorString}; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
410 | const std::optional<ModelId> modelIdOpt = documents->openModel( |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
411 | dep.path, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
412 | localErrorStream, |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
413 | OpenType::AutomaticallyOpened); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
414 | if (not modelIdOpt.has_value()) { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
415 | const QString& errorMessage = QObject::tr("could not load '%1': %2") |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
416 | .arg(dep.path, loadErrorString); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
417 | missing[dep.path] = errorMessage; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
418 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
419 | else { |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
420 | info->dependencies[dep.name] = modelIdOpt.value(); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
421 | repeat = true; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
422 | } |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
423 | } |
200 | 424 | } |
425 | } | |
426 | } | |
427 | ||
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
428 | std::map<QString, QString> DocumentManager::loadDependenciesForAllModels(const LibraryManager& libraries) |
12 | 429 | { |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
430 | std::map<QString, QString> missing; |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
431 | for (auto& modelInfoPair : this->openModels) |
12 | 432 | { |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
433 | loadDependenciesForModel(&modelInfoPair.second, this, &libraries, missing); |
148 | 434 | } |
212
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
435 | this->prune(); |
27259810da6d
Rewrite dependency loading
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
206
diff
changeset
|
436 | return missing; |
12 | 437 | } |