1 #pragma once
2
3 #include "lc_context.h"
4 #include "lc_mesh.h"
5 #include "lc_math.h"
6 #include "lc_array.h"
7 #include "lc_meshloader.h"
8
9 class PieceInfo;
10 class lcZipFile;
11 class lcLibraryMeshData;
12
13 enum class lcStudStyle
14 {
15 Plain,
16 ThinLinesLogo,
17 OutlineLogo,
18 SharpTopLogo,
19 RoundedTopLogo,
20 FlattenedLogo,
21 HighContrast,
22 HighContrastLogo,
23 Count
24 };
25
lcIsHighContrast(lcStudStyle StudStyle)26 inline bool lcIsHighContrast(lcStudStyle StudStyle)
27 {
28 return StudStyle == lcStudStyle::HighContrast || StudStyle == lcStudStyle::HighContrastLogo;
29 }
30
31 enum class lcZipFileType
32 {
33 Official,
34 Unofficial,
35 StudStyle,
36 Count
37 };
38
39 enum class lcLibraryFolderType
40 {
41 Official,
42 Unofficial,
43 Count
44 };
45
46 enum class lcPrimitiveState
47 {
48 NotLoaded,
49 Loading,
50 Loaded
51 };
52
53 class lcLibraryPrimitive
54 {
55 public:
lcLibraryPrimitive(QString && FileName,const char * Name,lcZipFileType ZipFileType,quint32 ZipFileIndex,bool Stud,bool StudStyle,bool SubFile)56 explicit lcLibraryPrimitive(QString&& FileName, const char* Name, lcZipFileType ZipFileType, quint32 ZipFileIndex, bool Stud, bool StudStyle, bool SubFile)
57 : mFileName(std::move(FileName))
58 {
59 strncpy(mName, Name, sizeof(mName)-1);
60 mName[sizeof(mName) - 1] = 0;
61
62 mZipFileType = ZipFileType;
63 mZipFileIndex = ZipFileIndex;
64 mState = lcPrimitiveState::NotLoaded;
65 mStud = Stud;
66 mStudStyle = StudStyle;
67 mSubFile = SubFile;
68 }
69
SetZipFile(lcZipFileType ZipFileType,quint32 ZipFileIndex)70 void SetZipFile(lcZipFileType ZipFileType, quint32 ZipFileIndex)
71 {
72 mZipFileType = ZipFileType;
73 mZipFileIndex = ZipFileIndex;
74 }
75
Unload()76 void Unload()
77 {
78 mState = lcPrimitiveState::NotLoaded;
79 mMeshData.Clear();
80 }
81
82 QString mFileName;
83 char mName[LC_MAXNAME];
84 lcZipFileType mZipFileType;
85 quint32 mZipFileIndex;
86 lcPrimitiveState mState;
87 bool mStud;
88 bool mStudStyle;
89 bool mSubFile;
90 lcLibraryMeshData mMeshData;
91 };
92
93 enum class lcLibrarySourceType
94 {
95 Library,
96 StudStyle
97 };
98
99 struct lcLibrarySource
100 {
~lcLibrarySourcelcLibrarySource101 ~lcLibrarySource()
102 {
103 for (const auto& PrimitiveIt : Primitives)
104 delete PrimitiveIt.second;
105 }
106
107 lcLibrarySourceType Type;
108 std::map<std::string, lcLibraryPrimitive*> Primitives;
109 };
110
111 class lcPiecesLibrary : public QObject
112 {
113 Q_OBJECT
114
115 public:
116 lcPiecesLibrary();
117 ~lcPiecesLibrary();
118
119 lcPiecesLibrary(const lcPiecesLibrary&) = delete;
120 lcPiecesLibrary& operator=(const lcPiecesLibrary&) = delete;
121
122 bool Load(const QString& LibraryPath, bool ShowProgress);
123 void LoadColors();
124 void Unload();
125 void RemoveTemporaryPieces();
126 void RemovePiece(PieceInfo* Info);
127
128 void RenamePiece(PieceInfo* Info, const char* NewName);
129 PieceInfo* FindPiece(const char* PieceName, Project* Project, bool CreatePlaceholder, bool SearchProjectFolder);
130 void LoadPieceInfo(PieceInfo* Info, bool Wait, bool Priority);
131 void ReleasePieceInfo(PieceInfo* Info);
132 bool LoadBuiltinPieces();
133 bool LoadPieceData(PieceInfo* Info);
134 void LoadQueuedPiece();
135 void WaitForLoadQueue();
136
137 lcTexture* FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder);
138 bool LoadTexture(lcTexture* Texture);
139 void ReleaseTexture(lcTexture* Texture);
140
141 bool PieceInCategory(PieceInfo* Info, const char* CategoryKeywords) const;
142 void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray<PieceInfo*>& SinglePieces, lcArray<PieceInfo*>& GroupedPieces);
143 void GetCategoryEntries(const char* CategoryKeywords, bool GroupPieces, lcArray<PieceInfo*>& SinglePieces, lcArray<PieceInfo*>& GroupedPieces);
144 void GetPatternedPieces(PieceInfo* Parent, lcArray<PieceInfo*>& Pieces) const;
145 void GetParts(lcArray<PieceInfo*>& Parts) const;
146
147 std::vector<PieceInfo*> GetPartsFromSet(const std::vector<std::string>& PartIds) const;
148 std::string GetPartId(const PieceInfo* Info) const;
149
150 void GetPrimitiveFile(lcLibraryPrimitive* Primitive, std::function<void(lcFile& File)> Callback);
151 void GetPieceFile(const char* FileName, std::function<void(lcFile& File)> Callback);
152
153 bool IsPrimitive(const char* Name) const;
154 lcLibraryPrimitive* FindPrimitive(const char* Name) const;
155 bool LoadPrimitive(lcLibraryPrimitive* Primitive);
156
157 bool SupportsStudStyle() const;
158 void SetStudStyle(lcStudStyle StudStyle, bool Reload);
159
GetStudStyle()160 lcStudStyle GetStudStyle() const
161 {
162 return mStudStyle;
163 }
164
SetOfficialPieces()165 void SetOfficialPieces()
166 {
167 if (mZipFiles[static_cast<int>(lcZipFileType::Official)])
168 mNumOfficialPieces = (int)mPieces.size();
169 }
170
ShouldCancelLoading()171 bool ShouldCancelLoading() const
172 {
173 return mCancelLoading;
174 }
175
176 void UpdateBuffers(lcContext* Context);
177 void UnloadUnusedParts();
178
179 std::map<std::string, PieceInfo*> mPieces;
180 int mNumOfficialPieces;
181
182 std::vector<lcTexture*> mTextures;
183
184 QDir mLibraryDir;
185
186 bool mBuffersDirty;
187 lcVertexBuffer mVertexBuffer;
188 lcIndexBuffer mIndexBuffer;
189
190 signals:
191 void PartLoaded(PieceInfo* Info);
192 void ColorsLoaded();
193
194 protected:
195 bool OpenArchive(const QString& FileName, lcZipFileType ZipFileType);
196 bool OpenArchive(std::unique_ptr<lcFile> File, lcZipFileType ZipFileType);
197 bool OpenDirectory(const QDir& LibraryDir, bool ShowProgress);
198 void ReadArchiveDescriptions(const QString& OfficialFileName, const QString& UnofficialFileName);
199 void ReadDirectoryDescriptions(const QFileInfoList (&FileLists)[static_cast<int>(lcLibraryFolderType::Count)], bool ShowProgress);
200
201 bool ReadArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile);
202 bool WriteArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile);
203 bool LoadCacheIndex(const QString& FileName);
204 bool SaveArchiveCacheIndex(const QString& FileName);
205 bool LoadCachePiece(PieceInfo* Info);
206 bool SaveCachePiece(PieceInfo* Info);
207 bool ReadDirectoryCacheFile(const QString& FileName, lcMemFile& CacheFile);
208 bool WriteDirectoryCacheFile(const QString& FileName, lcMemFile& CacheFile);
209
210 static bool IsStudPrimitive(const char* FileName);
211 static bool IsStudStylePrimitive(const char* FileName);
212 void UpdateStudStyleSource();
213
214 void ReleaseBuffers();
215
216 std::vector<std::unique_ptr<lcLibrarySource>> mSources;
217
218 QMutex mLoadMutex;
219 QList<QFuture<void>> mLoadFutures;
220 QList<PieceInfo*> mLoadQueue;
221
222 QMutex mTextureMutex;
223
224 lcStudStyle mStudStyle;
225
226 QString mCachePath;
227 qint64 mArchiveCheckSum[4];
228 std::unique_ptr<lcZipFile> mZipFiles[static_cast<int>(lcZipFileType::Count)];
229 bool mHasUnofficial;
230 bool mCancelLoading;
231 };
232