mirror of
https://github.com/leozide/leocad.git
synced 2026-07-28 04:07:11 +00:00
Multithreaded piece loading.
This commit is contained in:
+146
-19
@@ -14,6 +14,7 @@
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#include <zlib.h>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
@@ -26,6 +27,7 @@
|
||||
#define LC_LIBRARY_CACHE_DIRECTORY 0x0002
|
||||
|
||||
lcPiecesLibrary::lcPiecesLibrary()
|
||||
: mLoadMutex(QMutex::Recursive)
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
||||
QStringList cachePathList = QStandardPaths::standardLocations(QStandardPaths::CacheLocation);
|
||||
@@ -48,6 +50,10 @@ lcPiecesLibrary::lcPiecesLibrary()
|
||||
|
||||
lcPiecesLibrary::~lcPiecesLibrary()
|
||||
{
|
||||
mLoadMutex.lock();
|
||||
mLoadQueue.clear();
|
||||
mLoadMutex.unlock();
|
||||
WaitForLoadQueue();
|
||||
Unload();
|
||||
}
|
||||
|
||||
@@ -74,6 +80,8 @@ void lcPiecesLibrary::Unload()
|
||||
|
||||
void lcPiecesLibrary::RemoveTemporaryPieces()
|
||||
{
|
||||
QMutexLocker LoadLock(&mLoadMutex);
|
||||
|
||||
for (int PieceIdx = mPieces.GetSize() - 1; PieceIdx >= 0; PieceIdx--)
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceIdx];
|
||||
@@ -81,7 +89,7 @@ void lcPiecesLibrary::RemoveTemporaryPieces()
|
||||
if (!Info->IsTemporary())
|
||||
break;
|
||||
|
||||
if (!Info->IsLoaded())
|
||||
if (Info->GetRefCount() == 0)
|
||||
{
|
||||
mPieces.RemoveIndex(PieceIdx);
|
||||
delete Info;
|
||||
@@ -233,6 +241,11 @@ bool lcPiecesLibrary::OpenArchive(const char* FileName, lcZipFileType ZipFileTyp
|
||||
return true;
|
||||
}
|
||||
|
||||
static int lcPrimitiveCompare(lcLibraryPrimitive* const& a, lcLibraryPrimitive* const& b)
|
||||
{
|
||||
return strcmp(a->mName, b->mName);
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType)
|
||||
{
|
||||
lcZipFile* ZipFile = new lcZipFile();
|
||||
@@ -324,7 +337,7 @@ bool lcPiecesLibrary::OpenArchive(lcFile* File, const char* FileName, lcZipFileT
|
||||
int PrimitiveIndex = FindPrimitiveIndex(Name);
|
||||
|
||||
if (PrimitiveIndex == -1)
|
||||
mPrimitives.Add(new lcLibraryPrimitive(Name, ZipFileType, FileIdx, false, true));
|
||||
mPrimitives.AddSorted(new lcLibraryPrimitive(Name, ZipFileType, FileIdx, false, true), lcPrimitiveCompare);
|
||||
else
|
||||
mPrimitives[PrimitiveIndex]->SetZipFile(ZipFileType, FileIdx);
|
||||
}
|
||||
@@ -336,7 +349,7 @@ bool lcPiecesLibrary::OpenArchive(lcFile* File, const char* FileName, lcZipFileT
|
||||
int PrimitiveIndex = FindPrimitiveIndex(Name);
|
||||
|
||||
if (PrimitiveIndex == -1)
|
||||
mPrimitives.Add(new lcLibraryPrimitive(Name, ZipFileType, FileIdx, (memcmp(Name, "STU", 3) == 0), false));
|
||||
mPrimitives.AddSorted(new lcLibraryPrimitive(Name, ZipFileType, FileIdx, (memcmp(Name, "STU", 3) == 0), false), lcPrimitiveCompare);
|
||||
else
|
||||
mPrimitives[PrimitiveIndex]->SetZipFile(ZipFileType, FileIdx);
|
||||
}
|
||||
@@ -586,7 +599,7 @@ bool lcPiecesLibrary::OpenDirectory(const char* Path)
|
||||
|
||||
bool SubFile = SubFileDirectories[DirectoryIdx];
|
||||
lcLibraryPrimitive* Prim = new lcLibraryPrimitive(Name, LC_NUM_ZIPFILES, 0, !SubFile && (memcmp(Name, "STU", 3) == 0), SubFile);
|
||||
mPrimitives.Add(Prim);
|
||||
mPrimitives.AddSorted(Prim, lcPrimitiveCompare);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -849,16 +862,23 @@ bool lcPiecesLibrary::LoadCachePiece(PieceInfo* Info)
|
||||
if (!ReadCacheFile(FileName, MeshData))
|
||||
return false;
|
||||
|
||||
lcMesh* Mesh = new lcMesh;
|
||||
Info->SetMesh(Mesh);
|
||||
|
||||
quint32 Flags;
|
||||
if (MeshData.ReadBuffer((char*)&Flags, sizeof(Flags)) == 0)
|
||||
return false;
|
||||
|
||||
Info->mFlags = Flags;
|
||||
|
||||
return Mesh->FileLoad(MeshData);
|
||||
lcMesh* Mesh = new lcMesh;
|
||||
if (Mesh->FileLoad(MeshData))
|
||||
{
|
||||
Info->SetMesh(Mesh);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete Mesh;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::SaveCachePiece(PieceInfo* Info)
|
||||
@@ -877,6 +897,89 @@ bool lcPiecesLibrary::SaveCachePiece(PieceInfo* Info)
|
||||
return WriteCacheFile(FileName, MeshData);
|
||||
}
|
||||
|
||||
static void lcLoadPieceFuture(lcPiecesLibrary* Library)
|
||||
{
|
||||
Library->LoadQueuedPiece();
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::LoadPieceInfo(PieceInfo* Info, bool Wait, bool Priority)
|
||||
{
|
||||
QMutexLocker LoadLock(&mLoadMutex);
|
||||
|
||||
if (Wait)
|
||||
{
|
||||
if (Info->AddRef() == 1)
|
||||
Info->Load();
|
||||
else
|
||||
{
|
||||
if (Info->mState == LC_PIECEINFO_UNLOADED)
|
||||
{
|
||||
Info->Load();
|
||||
emit PartLoaded(Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadLock.unlock();
|
||||
|
||||
while (Info->mState != LC_PIECEINFO_LOADED)
|
||||
QThread::msleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Info->AddRef() == 1)
|
||||
{
|
||||
if (Priority)
|
||||
mLoadQueue.prepend(Info);
|
||||
else
|
||||
mLoadQueue.append(Info);
|
||||
|
||||
mLoadFutures.append(QtConcurrent::run(lcLoadPieceFuture, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::ReleasePieceInfo(PieceInfo* Info)
|
||||
{
|
||||
QMutexLocker LoadLock(&mLoadMutex);
|
||||
|
||||
if (Info->GetRefCount() == 0 || Info->Release() == 0)
|
||||
Info->Unload();
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::LoadQueuedPiece()
|
||||
{
|
||||
mLoadMutex.lock();
|
||||
|
||||
PieceInfo* Info = NULL;
|
||||
|
||||
while (!mLoadQueue.isEmpty())
|
||||
{
|
||||
Info = mLoadQueue.takeFirst();
|
||||
|
||||
if (Info->mState == LC_PIECEINFO_UNLOADED && Info->GetRefCount() > 0)
|
||||
{
|
||||
Info->mState = LC_PIECEINFO_LOADING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mLoadMutex.unlock();
|
||||
|
||||
if (Info)
|
||||
Info->Load();
|
||||
|
||||
emit PartLoaded(Info);
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::WaitForLoadQueue()
|
||||
{
|
||||
for (QFuture<void>& Future : mLoadFutures)
|
||||
Future.waitForFinished();
|
||||
mLoadFutures.clear();
|
||||
}
|
||||
|
||||
struct lcMergeSection
|
||||
{
|
||||
lcLibraryMeshSection* Shared;
|
||||
@@ -920,14 +1023,13 @@ static int LibraryMeshSectionCompare(lcMergeSection const& First, lcMergeSection
|
||||
return a->mColor > b->mColor ? -1 : 1;
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::LoadPiece(PieceInfo* Info)
|
||||
bool lcPiecesLibrary::LoadPieceData(PieceInfo* Info)
|
||||
{
|
||||
lcLibraryMeshData MeshData;
|
||||
lcArray<lcLibraryTextureMap> TextureStack;
|
||||
|
||||
bool Loaded = false;
|
||||
bool SaveCache = false;
|
||||
bool UpdateBoundingBox = false;
|
||||
|
||||
if (Info->mZipFileType != LC_NUM_ZIPFILES && mZipFiles[Info->mZipFileType])
|
||||
{
|
||||
@@ -967,10 +1069,7 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info)
|
||||
if (!Loaded)
|
||||
return false;
|
||||
|
||||
lcMesh* Mesh = CreateMesh(Info, MeshData);
|
||||
|
||||
if (UpdateBoundingBox)
|
||||
Info->SetBoundingBox(Mesh->mBoundingBox.Min, Mesh->mBoundingBox.Max);
|
||||
CreateMesh(Info, MeshData);
|
||||
|
||||
if (SaveCache)
|
||||
SaveCachePiece(Info);
|
||||
@@ -1332,8 +1431,14 @@ void lcPiecesLibrary::UpdateBuffers(lcContext* Context)
|
||||
|
||||
void lcPiecesLibrary::UnloadUnusedParts()
|
||||
{
|
||||
QMutexLocker LoadLock(&mLoadMutex);
|
||||
|
||||
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||
mPieces[PieceInfoIndex]->UnloadIfUnused();
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||
if (Info->GetRefCount() == 0 && Info->mState != LC_PIECEINFO_UNLOADED)
|
||||
ReleasePieceInfo(Info);
|
||||
}
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::LoadTexture(lcTexture* Texture)
|
||||
@@ -1369,15 +1474,37 @@ bool lcPiecesLibrary::LoadTexture(lcTexture* Texture)
|
||||
|
||||
int lcPiecesLibrary::FindPrimitiveIndex(const char* Name) const
|
||||
{
|
||||
for (int PrimitiveIndex = 0; PrimitiveIndex < mPrimitives.GetSize(); PrimitiveIndex++)
|
||||
if (!strcmp(mPrimitives[PrimitiveIndex]->mName, Name))
|
||||
return PrimitiveIndex;
|
||||
int Count = mPrimitives.GetSize();
|
||||
int Begin = 0;
|
||||
int Middle;
|
||||
|
||||
return -1;
|
||||
if (Count == 0)
|
||||
return -1;
|
||||
|
||||
while (Count > 0)
|
||||
{
|
||||
int Half = Count >> 1;
|
||||
Middle = Begin + Half;
|
||||
if (strcmp(mPrimitives[Middle]->mName, Name) < 0)
|
||||
{
|
||||
Begin = Middle + 1;
|
||||
Count -= Half + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Count = Half;
|
||||
}
|
||||
}
|
||||
if (Begin != mPrimitives.GetSize() && !strcmp(mPrimitives[Begin]->mName, Name))
|
||||
return Begin;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
||||
{
|
||||
QMutexLocker LoadLock(&mLoadMutex);
|
||||
|
||||
lcLibraryPrimitive* Primitive = mPrimitives[PrimitiveIndex];
|
||||
lcArray<lcLibraryTextureMap> TextureStack;
|
||||
|
||||
|
||||
+15
-2
@@ -123,8 +123,10 @@ public:
|
||||
lcLibraryMeshData mMeshData;
|
||||
};
|
||||
|
||||
class lcPiecesLibrary
|
||||
class lcPiecesLibrary : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
lcPiecesLibrary();
|
||||
~lcPiecesLibrary();
|
||||
@@ -135,8 +137,12 @@ public:
|
||||
void RemovePiece(PieceInfo* Info);
|
||||
|
||||
PieceInfo* FindPiece(const char* PieceName, Project* Project, bool CreatePlaceholder, bool SearchProjectFolder);
|
||||
bool LoadPiece(PieceInfo* Info);
|
||||
void LoadPieceInfo(PieceInfo* Info, bool Wait, bool Priority);
|
||||
void ReleasePieceInfo(PieceInfo* Info);
|
||||
bool LoadBuiltinPieces();
|
||||
bool LoadPieceData(PieceInfo* Info);
|
||||
void LoadQueuedPiece();
|
||||
void WaitForLoadQueue();
|
||||
|
||||
lcTexture* FindTexture(const char* TextureName);
|
||||
bool LoadTexture(lcTexture* Texture);
|
||||
@@ -176,6 +182,9 @@ public:
|
||||
lcVertexBuffer mVertexBuffer;
|
||||
lcIndexBuffer mIndexBuffer;
|
||||
|
||||
signals:
|
||||
void PartLoaded(PieceInfo* Info);
|
||||
|
||||
protected:
|
||||
bool OpenArchive(const char* FileName, lcZipFileType ZipFileType);
|
||||
bool OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType);
|
||||
@@ -192,6 +201,10 @@ protected:
|
||||
int FindPrimitiveIndex(const char* Name) const;
|
||||
bool LoadPrimitive(int PrimitiveIndex);
|
||||
|
||||
QMutex mLoadMutex;
|
||||
QList<QFuture<void>> mLoadFutures;
|
||||
QList<PieceInfo*> mLoadQueue;
|
||||
|
||||
QString mCachePath;
|
||||
qint64 mArchiveCheckSum[4];
|
||||
char mLibraryFileName[LC_MAXPATH];
|
||||
|
||||
@@ -54,7 +54,8 @@ lcMainWindow::~lcMainWindow()
|
||||
{
|
||||
if (mCurrentPieceInfo)
|
||||
{
|
||||
mCurrentPieceInfo->Release();
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
Library->ReleasePieceInfo(mCurrentPieceInfo);
|
||||
mCurrentPieceInfo = NULL;
|
||||
}
|
||||
|
||||
@@ -1265,15 +1266,16 @@ void lcMainWindow::SetTransformType(lcTransformType TransformType)
|
||||
|
||||
void lcMainWindow::SetCurrentPieceInfo(PieceInfo* Info)
|
||||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
GetActiveView()->MakeCurrent();
|
||||
|
||||
if (mCurrentPieceInfo)
|
||||
mCurrentPieceInfo->Release();
|
||||
Library->ReleasePieceInfo(mCurrentPieceInfo);
|
||||
|
||||
mCurrentPieceInfo = Info;
|
||||
|
||||
if (mCurrentPieceInfo)
|
||||
mCurrentPieceInfo->AddRef();
|
||||
Library->LoadPieceInfo(mCurrentPieceInfo, true, true);
|
||||
}
|
||||
|
||||
lcVector3 lcMainWindow::GetTransformAmount()
|
||||
|
||||
+18
-12
@@ -168,7 +168,9 @@ lcModel::~lcModel()
|
||||
|
||||
if (mPieceInfo->GetModel() == this)
|
||||
mPieceInfo->SetPlaceholder();
|
||||
mPieceInfo->Release();
|
||||
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
Library->ReleasePieceInfo(mPieceInfo);
|
||||
}
|
||||
|
||||
DeleteModel();
|
||||
@@ -225,9 +227,10 @@ void lcModel::DeleteModel()
|
||||
|
||||
void lcModel::CreatePieceInfo(Project* Project)
|
||||
{
|
||||
mPieceInfo = lcGetPiecesLibrary()->FindPiece(mProperties.mName.toUpper().toLatin1().constData(), Project, true, false);
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
mPieceInfo = Library->FindPiece(mProperties.mName.toUpper().toLatin1().constData(), Project, true, false);
|
||||
mPieceInfo->SetModel(this, true);
|
||||
mPieceInfo->AddRef();
|
||||
Library->LoadPieceInfo(mPieceInfo, true, true);
|
||||
}
|
||||
|
||||
void lcModel::UpdatePieceInfo(lcArray<lcModel*>& UpdatedModels)
|
||||
@@ -468,6 +471,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
||||
lcArray<lcGroup*> CurrentGroups;
|
||||
lcArray<lcPieceControlPoint> ControlPoints;
|
||||
int CurrentStep = 1;
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
|
||||
mProperties.mAuthor.clear();
|
||||
|
||||
@@ -609,8 +613,6 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
||||
if (PartID.endsWith(QLatin1String(".DAT")))
|
||||
PartID = PartID.left(PartID.size() - 4);
|
||||
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
|
||||
if (Library->IsPrimitive(PartID.toLatin1().constData()))
|
||||
{
|
||||
mFileLines.append(OriginalLine);
|
||||
@@ -633,7 +635,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
||||
lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(Matrix[12], Matrix[14], -Matrix[13], 1.0f));
|
||||
|
||||
Piece->SetFileLine(mFileLines.size());
|
||||
Piece->SetPieceInfo(Info);
|
||||
Piece->SetPieceInfo(Info, false);
|
||||
Piece->Initialize(Transform, CurrentStep);
|
||||
Piece->SetColorCode(ColorCode);
|
||||
Piece->SetControlPoints(ControlPoints);
|
||||
@@ -648,7 +650,9 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
||||
mCurrentStep = CurrentStep;
|
||||
CalculateStep(mCurrentStep);
|
||||
UpdateBackgroundTexture();
|
||||
lcGetPiecesLibrary()->UnloadUnusedParts();
|
||||
Library->WaitForLoadQueue();
|
||||
Library->mBuffersDirty = true;
|
||||
Library->UnloadUnusedParts();
|
||||
|
||||
delete Piece;
|
||||
delete Camera;
|
||||
@@ -1348,12 +1352,13 @@ void lcModel::SaveCheckpoint(const QString& Description)
|
||||
|
||||
void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint)
|
||||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
lcArray<PieceInfo*> Infos;
|
||||
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceIdx]->mPieceInfo;
|
||||
Info->AddRef();
|
||||
Library->LoadPieceInfo(Info, true, true);
|
||||
Infos.Add(Info);
|
||||
}
|
||||
|
||||
@@ -1370,7 +1375,7 @@ void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint)
|
||||
gMainWindow->UpdateAllViews();
|
||||
|
||||
for (int InfoIdx = 0; InfoIdx < Infos.GetSize(); InfoIdx++)
|
||||
Infos[InfoIdx]->Release();
|
||||
Library->ReleasePieceInfo(Infos[InfoIdx]);
|
||||
}
|
||||
|
||||
void lcModel::SetActive(bool Active)
|
||||
@@ -1989,7 +1994,7 @@ void lcModel::InsertPiece(lcPiece* Piece, int Index)
|
||||
{
|
||||
lcMesh* Mesh = Info->IsTemporary() ? gPlaceholderMesh : Info->GetMesh();
|
||||
|
||||
if (Mesh->mVertexCacheOffset == -1)
|
||||
if (Mesh && Mesh->mVertexCacheOffset == -1)
|
||||
lcGetPiecesLibrary()->mBuffersDirty = true;
|
||||
}
|
||||
|
||||
@@ -2582,8 +2587,9 @@ void lcModel::SetSelectedPiecesPieceInfo(PieceInfo* Info)
|
||||
|
||||
if (Piece->IsSelected() && Piece->mPieceInfo != Info)
|
||||
{
|
||||
Piece->mPieceInfo->Release();
|
||||
Piece->SetPieceInfo(Info);
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
Library->ReleasePieceInfo(Piece->mPieceInfo);
|
||||
Piece->SetPieceInfo(Info, true);
|
||||
Modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,23 +69,44 @@ lcPartSelectionListModel::lcPartSelectionListModel(QObject* Parent)
|
||||
{
|
||||
mListView = (lcPartSelectionListView*)Parent;
|
||||
mIconSize = 0;
|
||||
mLastDrawTime = QDateTime::currentDateTime();
|
||||
|
||||
connect(lcGetPiecesLibrary(), SIGNAL(PartLoaded(PieceInfo*)), this, SLOT(PartLoaded(PieceInfo*)));
|
||||
}
|
||||
|
||||
lcPartSelectionListModel::~lcPartSelectionListModel()
|
||||
{
|
||||
ClearRequests();
|
||||
}
|
||||
|
||||
void lcPartSelectionListModel::ClearRequests()
|
||||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
|
||||
foreach(int RequestIdx, mRequestedPreviews)
|
||||
{
|
||||
PieceInfo* Info = mParts[RequestIdx].first;
|
||||
Library->ReleasePieceInfo(Info);
|
||||
}
|
||||
|
||||
mRequestedPreviews.clear();
|
||||
}
|
||||
|
||||
void lcPartSelectionListModel::Redraw()
|
||||
{
|
||||
ClearRequests();
|
||||
|
||||
beginResetModel();
|
||||
|
||||
for (int PartIdx = 0; PartIdx < mParts.size(); PartIdx++)
|
||||
mParts[PartIdx].second = QPixmap();
|
||||
|
||||
mRequestedPreviews.clear();
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void lcPartSelectionListModel::SetCategory(int CategoryIndex)
|
||||
{
|
||||
ClearRequests();
|
||||
|
||||
beginResetModel();
|
||||
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
@@ -99,17 +120,16 @@ void lcPartSelectionListModel::SetCategory(int CategoryIndex)
|
||||
for (int PartIdx = 0; PartIdx < SingleParts.GetSize(); PartIdx++)
|
||||
mParts[PartIdx] = QPair<PieceInfo*, QPixmap>(SingleParts[PartIdx], QPixmap());
|
||||
|
||||
mRequestedPreviews.clear();
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void lcPartSelectionListModel::SetModelsCategory()
|
||||
{
|
||||
ClearRequests();
|
||||
|
||||
beginResetModel();
|
||||
|
||||
mParts.clear();
|
||||
mRequestedPreviews.clear();
|
||||
|
||||
const lcArray<lcModel*>& Models = lcGetActiveProject()->GetModels();
|
||||
lcModel* CurrentModel = lcGetActiveModel();
|
||||
@@ -193,21 +213,34 @@ void lcPartSelectionListModel::RequestPreview(int InfoIndex)
|
||||
if (!mIconSize || !mParts[InfoIndex].second.isNull())
|
||||
return;
|
||||
|
||||
mRequestedPreviews.removeOne(InfoIndex);
|
||||
mRequestedPreviews.append(InfoIndex);
|
||||
DrawPreview();
|
||||
if (mRequestedPreviews.indexOf(InfoIndex) != -1)
|
||||
return;
|
||||
|
||||
PieceInfo* Info = mParts[InfoIndex].first;
|
||||
lcGetPiecesLibrary()->LoadPieceInfo(Info, false, false);
|
||||
|
||||
if (Info->mState == LC_PIECEINFO_LOADED)
|
||||
DrawPreview(InfoIndex);
|
||||
else
|
||||
mRequestedPreviews.append(InfoIndex);
|
||||
}
|
||||
|
||||
void lcPartSelectionListModel::DrawPreview()
|
||||
void lcPartSelectionListModel::PartLoaded(PieceInfo* Info)
|
||||
{
|
||||
qint64 Elapsed = mLastDrawTime.msecsTo(QDateTime::currentDateTime());
|
||||
|
||||
if (Elapsed < 100)
|
||||
for (int PartIdx = 0; PartIdx < mParts.size(); PartIdx++)
|
||||
{
|
||||
QTimer::singleShot(100 - Elapsed, this, SLOT(DrawPreview()));
|
||||
return;
|
||||
if (mParts[PartIdx].first == Info)
|
||||
{
|
||||
DrawPreview(PartIdx);
|
||||
mRequestedPreviews.removeOne(PartIdx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lcPartSelectionListModel::DrawPreview(int InfoIndex)
|
||||
{
|
||||
/*
|
||||
QRegion VisibleRegion = mListView->viewport()->visibleRegion();
|
||||
int InfoIndex;
|
||||
|
||||
@@ -216,18 +249,18 @@ void lcPartSelectionListModel::DrawPreview()
|
||||
if (mRequestedPreviews.isEmpty())
|
||||
return;
|
||||
|
||||
InfoIndex = mRequestedPreviews.takeLast();
|
||||
InfoIndex = mRequestedPreviews.takeFirst();
|
||||
QRect ItemRect = mListView->visualRect(mListView->GetFilterModel()->mapFromSource(index(InfoIndex, 0)));
|
||||
|
||||
if (VisibleRegion.contains(ItemRect) || VisibleRegion.intersects(ItemRect))
|
||||
break;
|
||||
}
|
||||
|
||||
*/
|
||||
View* View = gMainWindow->GetActiveView();
|
||||
View->MakeCurrent();
|
||||
lcContext* Context = View->mContext;
|
||||
int Width = mIconSize;
|
||||
int Height = mIconSize;
|
||||
int Width = 128;
|
||||
int Height = 128;
|
||||
|
||||
if (!Context->BeginRenderToTexture(Width, Height))
|
||||
return;
|
||||
@@ -235,15 +268,15 @@ void lcPartSelectionListModel::DrawPreview()
|
||||
float Aspect = (float)Width / (float)Height;
|
||||
Context->SetViewport(0, 0, Width, Height);
|
||||
|
||||
lcMatrix44 ProjectionMatrix = lcMatrix44Perspective(30.0f, Aspect, 1.0f, 2500.0f);
|
||||
lcMatrix44 ProjectionMatrix = lcMatrix44Perspective(20.0f, Aspect, 1.0f, 12500.0f);
|
||||
lcMatrix44 ViewMatrix;
|
||||
|
||||
Context->SetDefaultState();
|
||||
Context->SetProjectionMatrix(ProjectionMatrix);
|
||||
Context->SetProgram(LC_PROGRAM_SIMPLE);
|
||||
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
PieceInfo* Info = mParts[InfoIndex].first;
|
||||
Info->AddRef();
|
||||
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
@@ -264,15 +297,12 @@ void lcPartSelectionListModel::DrawPreview()
|
||||
|
||||
Context->UnbindMesh(); // context remove
|
||||
|
||||
Info->Release();
|
||||
Library->ReleasePieceInfo(Info);
|
||||
|
||||
mParts[InfoIndex].second = QPixmap::fromImage(Context->GetRenderToTextureImage(Width, Height));
|
||||
mParts[InfoIndex].second = QPixmap::fromImage(Context->GetRenderToTextureImage(Width, Height)).scaled(mIconSize, mIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
Context->EndRenderToTexture();
|
||||
|
||||
mLastDrawTime = QDateTime::currentDateTime();
|
||||
QTimer::singleShot(100, this, SLOT(DrawPreview()));
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
|
||||
emit dataChanged(index(InfoIndex, 0), index(InfoIndex, 0), QVector<int>() << Qt::DecorationRole);
|
||||
#else
|
||||
|
||||
@@ -43,6 +43,7 @@ class lcPartSelectionListModel : public QAbstractListModel
|
||||
|
||||
public:
|
||||
lcPartSelectionListModel(QObject* Parent);
|
||||
virtual ~lcPartSelectionListModel();
|
||||
|
||||
virtual int rowCount(const QModelIndex& Parent = QModelIndex()) const;
|
||||
virtual QVariant data(const QModelIndex& Index, int Role = Qt::DisplayRole) const;
|
||||
@@ -66,13 +67,15 @@ public:
|
||||
void SetIconSize(int Size);
|
||||
|
||||
protected slots:
|
||||
void DrawPreview();
|
||||
void PartLoaded(PieceInfo* Info);
|
||||
|
||||
protected:
|
||||
void ClearRequests();
|
||||
void DrawPreview(int InfoIndex);
|
||||
|
||||
lcPartSelectionListView* mListView;
|
||||
QVector<QPair<PieceInfo*, QPixmap>> mParts;
|
||||
QList<int> mRequestedPreviews;
|
||||
QDateTime mLastDrawTime;
|
||||
int mIconSize;
|
||||
};
|
||||
|
||||
|
||||
+2
-382
@@ -19,7 +19,6 @@ lcZipFile::lcZipFile()
|
||||
|
||||
lcZipFile::~lcZipFile()
|
||||
{
|
||||
Flush();
|
||||
delete mFile;
|
||||
}
|
||||
|
||||
@@ -605,6 +604,8 @@ bool lcZipFile::ExtractFile(const char* FileName, lcMemFile& File, lcuint32 MaxL
|
||||
|
||||
bool lcZipFile::ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength)
|
||||
{
|
||||
QMutexLocker Lock(&mMutex);
|
||||
|
||||
lcuint32 SizeVar;
|
||||
lcuint64 OffsetLocalExtraField;
|
||||
lcuint32 SizeLocalExtraField;
|
||||
@@ -746,384 +747,3 @@ bool lcZipFile::ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lcZipFile::AddFile(const char* FileName, lcMemFile& File)
|
||||
{
|
||||
const size_t BufferSize = 16384;
|
||||
char WriteBuffer[BufferSize];
|
||||
z_stream Stream;
|
||||
lcuint32 Crc32 = 0;
|
||||
|
||||
File.Seek(0, SEEK_SET);
|
||||
|
||||
Stream.zalloc = (alloc_func)0;
|
||||
Stream.zfree = (free_func)0;
|
||||
Stream.opaque = (voidpf)0;
|
||||
|
||||
if (deflateInit2(&Stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
return false;
|
||||
|
||||
lcMemFile* OutFile = new lcMemFile();
|
||||
lcMemFile& CompressedFile = *OutFile;
|
||||
|
||||
Bytef* BufferIn = File.mBuffer;
|
||||
int FlushMode;
|
||||
|
||||
do
|
||||
{
|
||||
uInt Read = lcMin(File.GetLength() - (BufferIn - File.mBuffer), BufferSize);
|
||||
Stream.avail_in = Read;
|
||||
Stream.next_in = BufferIn;
|
||||
Crc32 = crc32(Crc32, BufferIn, Read);
|
||||
BufferIn += Read;
|
||||
|
||||
FlushMode = (BufferIn >= File.mBuffer + File.GetLength()) ? Z_FINISH : Z_NO_FLUSH;
|
||||
|
||||
do
|
||||
{
|
||||
Stream.avail_out = BufferSize;
|
||||
Stream.next_out = (Bytef*)WriteBuffer;
|
||||
deflate(&Stream, FlushMode);
|
||||
CompressedFile.WriteBuffer(WriteBuffer, BufferSize - Stream.avail_out);
|
||||
} while (Stream.avail_out == 0);
|
||||
} while (FlushMode != Z_FINISH);
|
||||
|
||||
deflateEnd(&Stream);
|
||||
|
||||
lcZipFileInfo& Info = mFiles.Add();
|
||||
|
||||
Info.version = 0;
|
||||
if (CompressedFile.GetLength() >= 0xffffffffU || File.GetLength() >= 0xffffffffU)
|
||||
Info.version_needed = 45;
|
||||
else
|
||||
Info.version_needed = 20;
|
||||
Info.flag = 0;
|
||||
Info.compression_method = Z_DEFLATED;
|
||||
Info.crc = Crc32;
|
||||
Info.compressed_size = CompressedFile.GetLength();
|
||||
Info.uncompressed_size = File.GetLength();
|
||||
Info.size_filename = (lcuint16)strlen(FileName);
|
||||
Info.size_file_extra = 0;
|
||||
Info.size_file_comment = 0;
|
||||
Info.disk_num_start = 0;
|
||||
Info.internal_fa = 0;
|
||||
Info.external_fa = 0;
|
||||
Info.offset_curfile = 0;
|
||||
strncpy(Info.file_name, FileName, sizeof(Info.file_name));
|
||||
|
||||
time_t rawtime;
|
||||
struct tm* timeinfo;
|
||||
|
||||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
|
||||
Info.tmu_date.tm_sec = timeinfo->tm_sec;
|
||||
Info.tmu_date.tm_min = timeinfo->tm_min;
|
||||
Info.tmu_date.tm_hour = timeinfo->tm_hour;
|
||||
Info.tmu_date.tm_mday = timeinfo->tm_mday;
|
||||
Info.tmu_date.tm_mon = timeinfo->tm_mon ;
|
||||
Info.tmu_date.tm_year = timeinfo->tm_year - 80;
|
||||
Info.dosDate = (((timeinfo->tm_mday) + (32 * (timeinfo->tm_mon + 1)) + (512 * timeinfo->tm_year)) << 16) | ((timeinfo->tm_sec / 2) + (32 * timeinfo->tm_min) + (2048 * (uLong)timeinfo->tm_hour));
|
||||
|
||||
Info.write_buffer = OutFile;
|
||||
Info.deleted = false;
|
||||
|
||||
mModified = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lcZipFile::DeleteFile(const char* FileName)
|
||||
{
|
||||
for (int FileIdx = 0; FileIdx < mFiles.GetSize(); FileIdx++)
|
||||
{
|
||||
lcZipFileInfo& FileInfo = mFiles[FileIdx];
|
||||
|
||||
if (!stricmp(FileInfo.file_name, FileName))
|
||||
{
|
||||
FileInfo.deleted = true;
|
||||
mModified = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void lcZipFile::Flush()
|
||||
{
|
||||
if (!mFile || !mModified)
|
||||
return;
|
||||
|
||||
lcMemFile MemFile;
|
||||
lcuint64 NumFiles = 0;
|
||||
|
||||
mFile->Seek(0, SEEK_SET);
|
||||
|
||||
if (mBytesBeforeZipFile)
|
||||
{
|
||||
MemFile.GrowFile((size_t)mBytesBeforeZipFile);
|
||||
mFile->ReadBuffer(MemFile.mBuffer, (long)mBytesBeforeZipFile);
|
||||
MemFile.Seek((long)mBytesBeforeZipFile, SEEK_CUR);
|
||||
}
|
||||
|
||||
for (int FileIdx = 0; FileIdx < mFiles.GetSize(); FileIdx++)
|
||||
{
|
||||
lcZipFileInfo& FileInfo = mFiles[FileIdx];
|
||||
|
||||
if (FileInfo.deleted)
|
||||
continue;
|
||||
|
||||
lcuint32 SizeVar;
|
||||
lcuint64 OffsetLocalExtraField;
|
||||
lcuint32 SizeLocalExtraField;
|
||||
CheckFileCoherencyHeader(FileIdx, &SizeVar, &OffsetLocalExtraField, &SizeLocalExtraField);
|
||||
NumFiles++;
|
||||
|
||||
lcuint64 PosInZipfile = FileInfo.offset_curfile + 0x1e + SizeVar;
|
||||
mFile->Seek((long)(PosInZipfile + mBytesBeforeZipFile), SEEK_SET);
|
||||
|
||||
FileInfo.offset_curfile = MemFile.GetPosition();
|
||||
|
||||
if (FileInfo.offset_curfile >= 0xffffffffU)
|
||||
FileInfo.version_needed = 45;
|
||||
|
||||
MemFile.WriteU32(0x04034b50);
|
||||
MemFile.WriteU16(FileInfo.version_needed);
|
||||
MemFile.WriteU16(FileInfo.flag);
|
||||
MemFile.WriteU16(FileInfo.compression_method);
|
||||
MemFile.WriteU32(FileInfo.dosDate);
|
||||
MemFile.WriteU32(FileInfo.crc);
|
||||
if (FileInfo.compressed_size >= 0xffffffffU)
|
||||
MemFile.WriteU32(0xffffffffU);
|
||||
else
|
||||
MemFile.WriteU32((lcuint32)FileInfo.compressed_size);
|
||||
if (FileInfo.uncompressed_size >= 0xffffffffU)
|
||||
MemFile.WriteU32(0xffffffffU);
|
||||
else
|
||||
MemFile.WriteU32((lcuint32)FileInfo.uncompressed_size);
|
||||
MemFile.WriteU16(FileInfo.size_filename);
|
||||
MemFile.WriteU16(FileInfo.size_file_extra);
|
||||
MemFile.WriteBuffer(FileInfo.file_name, FileInfo.size_filename);
|
||||
|
||||
if (FileInfo.write_buffer)
|
||||
{
|
||||
MemFile.WriteBuffer(FileInfo.write_buffer->mBuffer, FileInfo.write_buffer->GetLength());
|
||||
delete FileInfo.write_buffer;
|
||||
FileInfo.write_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MemFile.GrowFile((size_t)(MemFile.GetPosition() + FileInfo.compressed_size));
|
||||
mFile->ReadBuffer(MemFile.mBuffer + MemFile.GetPosition(), (long)FileInfo.compressed_size);
|
||||
MemFile.Seek((long)FileInfo.compressed_size, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
lcuint64 CentralDirPos = MemFile.GetPosition();
|
||||
|
||||
for (int FileIdx = 0; FileIdx < mFiles.GetSize(); FileIdx++)
|
||||
{
|
||||
lcZipFileInfo& FileInfo = mFiles[FileIdx];
|
||||
|
||||
if (FileInfo.deleted)
|
||||
continue;
|
||||
|
||||
MemFile.WriteU32(0x02014b50);
|
||||
MemFile.WriteU16(FileInfo.version);
|
||||
MemFile.WriteU16(FileInfo.version_needed);
|
||||
MemFile.WriteU16(FileInfo.flag);
|
||||
MemFile.WriteU16(FileInfo.compression_method);
|
||||
MemFile.WriteU32(FileInfo.dosDate);
|
||||
MemFile.WriteU32(FileInfo.crc);
|
||||
if (FileInfo.compressed_size >= 0xffffffffU)
|
||||
MemFile.WriteU32(0xffffffffU);
|
||||
else
|
||||
MemFile.WriteU32((lcuint32)FileInfo.compressed_size);
|
||||
if (FileInfo.uncompressed_size >= 0xffffffffU)
|
||||
MemFile.WriteU32(0xffffffffU);
|
||||
else
|
||||
MemFile.WriteU32((lcuint32)FileInfo.uncompressed_size);
|
||||
MemFile.WriteU16(FileInfo.size_filename);
|
||||
MemFile.WriteU16(FileInfo.size_file_extra);
|
||||
MemFile.WriteU16(FileInfo.size_file_comment);
|
||||
MemFile.WriteU16(FileInfo.disk_num_start);
|
||||
MemFile.WriteU16(FileInfo.internal_fa);
|
||||
MemFile.WriteU32(FileInfo.external_fa);
|
||||
|
||||
if (FileInfo.offset_curfile >= 0xffffffffU)
|
||||
MemFile.WriteU32(0xffffffffU);
|
||||
else
|
||||
MemFile.WriteU32((lcuint32)(FileInfo.offset_curfile - mBytesBeforeZipFile));
|
||||
|
||||
MemFile.WriteBuffer(FileInfo.file_name, FileInfo.size_filename);
|
||||
}
|
||||
|
||||
lcuint64 CentralDirEnd = MemFile.GetPosition();
|
||||
|
||||
if (CentralDirPos - mBytesBeforeZipFile >= 0xffffffffU)
|
||||
{
|
||||
MemFile.WriteU32(0x6064b50);
|
||||
MemFile.WriteU64(44);
|
||||
MemFile.WriteU16(45);
|
||||
MemFile.WriteU16(45);
|
||||
MemFile.WriteU32(0);
|
||||
MemFile.WriteU32(0);
|
||||
MemFile.WriteU64(NumFiles);
|
||||
MemFile.WriteU64(NumFiles);
|
||||
MemFile.WriteU64(CentralDirEnd - CentralDirPos);
|
||||
MemFile.WriteU64(CentralDirPos - mBytesBeforeZipFile);
|
||||
|
||||
MemFile.WriteU32(0x7064b50);
|
||||
MemFile.WriteU32(0);
|
||||
MemFile.WriteU64(CentralDirEnd - mBytesBeforeZipFile);
|
||||
MemFile.WriteU32(1);
|
||||
}
|
||||
|
||||
MemFile.WriteU32(0x06054b50);
|
||||
MemFile.WriteU16(0);
|
||||
MemFile.WriteU16(0);
|
||||
|
||||
if (NumFiles >= 0xffff)
|
||||
MemFile.WriteU16(0xffff);
|
||||
else
|
||||
MemFile.WriteU16((lcuint16)NumFiles);
|
||||
|
||||
if (NumFiles >= 0xffff)
|
||||
MemFile.WriteU16(0xffff);
|
||||
else
|
||||
MemFile.WriteU16((lcuint16)NumFiles);
|
||||
|
||||
MemFile.WriteU32((lcuint32)(CentralDirEnd - CentralDirPos));
|
||||
if (CentralDirPos - mBytesBeforeZipFile >= 0xffffffffU)
|
||||
MemFile.WriteU32(0xffffffffU);
|
||||
else
|
||||
MemFile.WriteU32((lcuint32)(CentralDirPos - mBytesBeforeZipFile));
|
||||
|
||||
MemFile.WriteU16(0);
|
||||
|
||||
mFile->CopyFrom(MemFile);
|
||||
/*
|
||||
lcuint64 CurrentOffset = mCentralDirOffset + mBytesBeforeZipFile;
|
||||
mFile->Seek((long)CurrentOffset, SEEK_SET);
|
||||
|
||||
void* CentralDir = malloc((long)mCentralDirSize);
|
||||
mFile->ReadBuffer(CentralDir, (long)mCentralDirSize);
|
||||
mFile->Seek((long)CurrentOffset, SEEK_SET);
|
||||
|
||||
for (int FileIdx = FirstFileAdded; FileIdx < mFiles.GetSize(); FileIdx++)
|
||||
{
|
||||
lcZipFileInfo& FileInfo = mFiles[FileIdx];
|
||||
|
||||
FileInfo.offset_curfile = CurrentOffset;
|
||||
|
||||
if (FileInfo.offset_curfile >= 0xffffffffU)
|
||||
FileInfo.version_needed = 45;
|
||||
|
||||
mFile->WriteU32(0x04034b50);
|
||||
mFile->WriteU16(FileInfo.version_needed);
|
||||
mFile->WriteU16(FileInfo.flag);
|
||||
mFile->WriteU16(FileInfo.compression_method);
|
||||
mFile->WriteU32(FileInfo.dosDate);
|
||||
mFile->WriteU32(FileInfo.crc);
|
||||
if (FileInfo.compressed_size >= 0xffffffffU)
|
||||
mFile->WriteU32(0xffffffffU);
|
||||
else
|
||||
mFile->WriteU32((lcuint32)FileInfo.compressed_size);
|
||||
if (FileInfo.uncompressed_size >= 0xffffffffU)
|
||||
mFile->WriteU32(0xffffffffU);
|
||||
else
|
||||
mFile->WriteU32((lcuint32)FileInfo.uncompressed_size);
|
||||
mFile->WriteU16(FileInfo.size_filename);
|
||||
mFile->WriteU16(FileInfo.size_file_extra);
|
||||
mFile->WriteBuffer(FileInfo.file_name, FileInfo.size_filename);
|
||||
|
||||
mFile->WriteBuffer(FileInfo.write_buffer->mBuffer, FileInfo.write_buffer->GetLength());
|
||||
delete FileInfo.write_buffer;
|
||||
FileInfo.write_buffer = NULL;
|
||||
|
||||
CurrentOffset = mFile->GetPosition();
|
||||
}
|
||||
|
||||
lcuint64 CentralDirPos = mFile->GetPosition();
|
||||
mFile->WriteBuffer(CentralDir, (long)mCentralDirSize);
|
||||
free(CentralDir);
|
||||
|
||||
for (int FileIdx = FirstFileAdded; FileIdx < mFiles.GetSize(); FileIdx++)
|
||||
{
|
||||
lcZipFileInfo& FileInfo = mFiles[FileIdx];
|
||||
|
||||
mFile->WriteU32(0x02014b50);
|
||||
mFile->WriteU16(FileInfo.version);
|
||||
mFile->WriteU16(FileInfo.version_needed);
|
||||
mFile->WriteU16(FileInfo.flag);
|
||||
mFile->WriteU16(FileInfo.compression_method);
|
||||
mFile->WriteU32(FileInfo.dosDate);
|
||||
mFile->WriteU32(FileInfo.crc);
|
||||
if (FileInfo.compressed_size >= 0xffffffffU)
|
||||
mFile->WriteU32(0xffffffffU);
|
||||
else
|
||||
mFile->WriteU32((lcuint32)FileInfo.compressed_size);
|
||||
if (FileInfo.uncompressed_size >= 0xffffffffU)
|
||||
mFile->WriteU32(0xffffffffU);
|
||||
else
|
||||
mFile->WriteU32((lcuint32)FileInfo.uncompressed_size);
|
||||
mFile->WriteU16(FileInfo.size_filename);
|
||||
mFile->WriteU16(FileInfo.size_file_extra);
|
||||
mFile->WriteU16(FileInfo.size_file_comment);
|
||||
mFile->WriteU16(FileInfo.disk_num_start);
|
||||
mFile->WriteU16(FileInfo.internal_fa);
|
||||
mFile->WriteU32(FileInfo.external_fa);
|
||||
|
||||
if (FileInfo.offset_curfile >= 0xffffffffU)
|
||||
mFile->WriteU32(0xffffffffU);
|
||||
else
|
||||
mFile->WriteU32((lcuint32)(FileInfo.offset_curfile - mBytesBeforeZipFile));
|
||||
|
||||
mFile->WriteBuffer(FileInfo.file_name, FileInfo.size_filename);
|
||||
}
|
||||
|
||||
lcuint64 CentralDirEnd = mFile->GetPosition();
|
||||
|
||||
if (CentralDirPos - mBytesBeforeZipFile >= 0xffffffffU)
|
||||
{
|
||||
mFile->WriteU32(0x6064b50);
|
||||
mFile->WriteU64(44);
|
||||
mFile->WriteU16(45);
|
||||
mFile->WriteU16(45);
|
||||
mFile->WriteU32(0);
|
||||
mFile->WriteU32(0);
|
||||
mFile->WriteU64(mFiles.GetSize());
|
||||
mFile->WriteU64(mFiles.GetSize());
|
||||
mFile->WriteU64(CentralDirEnd - CentralDirPos);
|
||||
mFile->WriteU64(CentralDirPos - mBytesBeforeZipFile);
|
||||
|
||||
mFile->WriteU32(0x7064b50);
|
||||
mFile->WriteU32(0);
|
||||
mFile->WriteU64(CentralDirEnd - mBytesBeforeZipFile);
|
||||
mFile->WriteU32(1);
|
||||
}
|
||||
|
||||
mFile->WriteU32(0x06054b50);
|
||||
mFile->WriteU16(0);
|
||||
mFile->WriteU16(0);
|
||||
|
||||
if (mFiles.GetSize() >= 0xffff)
|
||||
mFile->WriteU16(0xffff);
|
||||
else
|
||||
mFile->WriteU16(mFiles.GetSize());
|
||||
|
||||
if (mFiles.GetSize() >= 0xffff)
|
||||
mFile->WriteU16(0xffff);
|
||||
else
|
||||
mFile->WriteU16(mFiles.GetSize());
|
||||
|
||||
mFile->WriteU32((lcuint32)(CentralDirEnd - CentralDirPos));
|
||||
if (CentralDirPos - mBytesBeforeZipFile >= 0xffffffffU)
|
||||
mFile->WriteU32(0xffffffffU);
|
||||
else
|
||||
mFile->WriteU32((lcuint32)(CentralDirPos - mBytesBeforeZipFile));
|
||||
|
||||
mFile->WriteU16(0);
|
||||
*/
|
||||
}
|
||||
|
||||
+1
-3
@@ -59,19 +59,17 @@ public:
|
||||
|
||||
bool ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
|
||||
bool ExtractFile(const char* FileName, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
|
||||
bool AddFile(const char* FileName, lcMemFile& File);
|
||||
bool DeleteFile(const char* FileName);
|
||||
|
||||
lcArray<lcZipFileInfo> mFiles;
|
||||
|
||||
protected:
|
||||
bool Open();
|
||||
void Flush();
|
||||
bool ReadCentralDir();
|
||||
lcuint64 SearchCentralDir();
|
||||
lcuint64 SearchCentralDir64();
|
||||
bool CheckFileCoherencyHeader(int FileIndex, lcuint32* SizeVar, lcuint64* OffsetLocalExtraField, lcuint32* SizeLocalExtraField);
|
||||
|
||||
QMutex mMutex;
|
||||
lcFile* mFile;
|
||||
|
||||
bool mModified;
|
||||
|
||||
+10
-5
@@ -58,27 +58,31 @@ void MinifigWizard::OnInitialUpdate()
|
||||
|
||||
const int ColorCodes[LC_MFW_NUMITEMS] = { 4, 7, 14, 7, 1, 0, 7, 4, 4, 14, 14, 7, 7, 0, 0, 7, 7 };
|
||||
const char* Pieces[LC_MFW_NUMITEMS] = { "3624", "None", "3626BP01", "None", "973", "3815", "None", "3819", "3818", "3820", "3820", "None", "None", "3817", "3816", "None", "None" };
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
|
||||
for (int i = 0; i < LC_MFW_NUMITEMS; i++)
|
||||
{
|
||||
mMinifig.Colors[i] = lcGetColorIndex(ColorCodes[i]);
|
||||
|
||||
PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(Pieces[i], NULL, false, false);
|
||||
PieceInfo* Info = Library->FindPiece(Pieces[i], NULL, false, false);
|
||||
if (Info)
|
||||
{
|
||||
mMinifig.Parts[i] = Info;
|
||||
Info->AddRef();
|
||||
Library->LoadPieceInfo(Info, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
Library->WaitForLoadQueue();
|
||||
Calculate();
|
||||
}
|
||||
|
||||
MinifigWizard::~MinifigWizard()
|
||||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
|
||||
for (int i = 0; i < LC_MFW_NUMITEMS; i++)
|
||||
if (mMinifig.Parts[i])
|
||||
mMinifig.Parts[i]->Release();
|
||||
Library->ReleasePieceInfo(mMinifig.Parts[i]);
|
||||
}
|
||||
|
||||
void MinifigWizard::ParseSettings(lcFile& Settings)
|
||||
@@ -547,15 +551,16 @@ int MinifigWizard::GetSelectionIndex(int Type) const
|
||||
|
||||
void MinifigWizard::SetSelectionIndex(int Type, int Index)
|
||||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
MakeCurrent();
|
||||
|
||||
if (mMinifig.Parts[Type])
|
||||
mMinifig.Parts[Type]->Release();
|
||||
Library->ReleasePieceInfo(mMinifig.Parts[Type]);
|
||||
|
||||
mMinifig.Parts[Type] = mSettings[Type][Index].Info;
|
||||
|
||||
if (mMinifig.Parts[Type])
|
||||
mMinifig.Parts[Type]->AddRef();
|
||||
Library->LoadPieceInfo(mMinifig.Parts[Type], true, true);
|
||||
|
||||
Calculate();
|
||||
}
|
||||
|
||||
+10
-5
@@ -20,7 +20,7 @@ lcPiece::lcPiece(PieceInfo* Info)
|
||||
: lcObject(LC_OBJECT_PIECE)
|
||||
{
|
||||
mMesh = NULL;
|
||||
SetPieceInfo(Info);
|
||||
SetPieceInfo(Info, true);
|
||||
mState = 0;
|
||||
mColorIndex = gDefaultColor;
|
||||
mColorCode = 16;
|
||||
@@ -37,16 +37,21 @@ lcPiece::lcPiece(PieceInfo* Info)
|
||||
lcPiece::~lcPiece()
|
||||
{
|
||||
if (mPieceInfo)
|
||||
mPieceInfo->Release();
|
||||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
Library->ReleasePieceInfo(mPieceInfo);
|
||||
}
|
||||
|
||||
delete mMesh;
|
||||
}
|
||||
|
||||
void lcPiece::SetPieceInfo(PieceInfo* Info)
|
||||
void lcPiece::SetPieceInfo(PieceInfo* Info, bool Wait)
|
||||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
|
||||
mPieceInfo = Info;
|
||||
if (mPieceInfo)
|
||||
mPieceInfo->AddRef();
|
||||
Library->LoadPieceInfo(mPieceInfo, Wait, true);
|
||||
|
||||
mControlPoints.RemoveAll();
|
||||
delete mMesh;
|
||||
@@ -266,7 +271,7 @@ bool lcPiece::FileLoad(lcFile& file)
|
||||
file.ReadBuffer(name, LC_PIECE_NAME_LEN);
|
||||
|
||||
PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, NULL, true, false);
|
||||
SetPieceInfo(pInfo);
|
||||
SetPieceInfo(pInfo, true);
|
||||
|
||||
// 11 (0.77)
|
||||
if (version < 11)
|
||||
|
||||
+1
-1
@@ -388,7 +388,7 @@ public:
|
||||
void Initialize(const lcMatrix44& WorldMatrix, lcStep Step);
|
||||
const lcBoundingBox& GetBoundingBox() const;
|
||||
void CompareBoundingBox(lcVector3& Min, lcVector3& Max) const;
|
||||
void SetPieceInfo(PieceInfo* Info);
|
||||
void SetPieceInfo(PieceInfo* Info, bool Wait);
|
||||
bool FileLoad(lcFile& file);
|
||||
|
||||
void UpdatePosition(lcStep Step);
|
||||
|
||||
+25
-19
@@ -18,7 +18,7 @@ PieceInfo::PieceInfo()
|
||||
mZipFileType = LC_NUM_ZIPFILES;
|
||||
mZipFileIndex = -1;
|
||||
mFlags = 0;
|
||||
mLoaded = false;
|
||||
mState = LC_PIECEINFO_UNLOADED;
|
||||
mRefCount = 0;
|
||||
mMesh = NULL;
|
||||
mModel = NULL;
|
||||
@@ -30,7 +30,7 @@ PieceInfo::~PieceInfo()
|
||||
{
|
||||
delete mSynthInfo;
|
||||
|
||||
if (mLoaded)
|
||||
if (mState == LC_PIECEINFO_LOADED)
|
||||
Unload();
|
||||
}
|
||||
|
||||
@@ -42,6 +42,12 @@ QString PieceInfo::GetSaveID() const
|
||||
return QString::fromLatin1(m_strName) + QLatin1String(".DAT");
|
||||
}
|
||||
|
||||
void PieceInfo::SetMesh(lcMesh* Mesh)
|
||||
{
|
||||
mBoundingBox = Mesh->mBoundingBox;
|
||||
mMesh = Mesh;
|
||||
}
|
||||
|
||||
void PieceInfo::SetPlaceholder()
|
||||
{
|
||||
mBoundingBox.Min = lcVector3(-10.0f, -10.0f, -24.0f);
|
||||
@@ -100,7 +106,7 @@ void PieceInfo::SetProject(Project* Project, const char* PieceName)
|
||||
{
|
||||
mFlags = LC_PIECE_PROJECT;
|
||||
mProject = Project;
|
||||
mLoaded = true;
|
||||
mState = LC_PIECEINFO_LOADED;
|
||||
}
|
||||
|
||||
strncpy(m_strName, PieceName, sizeof(m_strName));
|
||||
@@ -134,25 +140,25 @@ void PieceInfo::CreatePlaceholder(const char* Name)
|
||||
|
||||
void PieceInfo::Load()
|
||||
{
|
||||
mLoaded = true;
|
||||
if ((mFlags & (LC_PIECE_MODEL | LC_PIECE_PROJECT)) == 0)
|
||||
{
|
||||
mState = LC_PIECEINFO_LOADING; // todo: mutex lock when changing load state
|
||||
|
||||
if (mFlags & (LC_PIECE_MODEL | LC_PIECE_PROJECT))
|
||||
return;
|
||||
else if (mFlags & LC_PIECE_PLACEHOLDER)
|
||||
{
|
||||
if (lcGetPiecesLibrary()->LoadPiece(this))
|
||||
mFlags &= ~LC_PIECE_PLACEHOLDER;
|
||||
else
|
||||
if (mFlags & LC_PIECE_PLACEHOLDER)
|
||||
{
|
||||
mFlags |= LC_PIECE_HAS_DEFAULT | LC_PIECE_HAS_LINES;
|
||||
mBoundingBox = gPlaceholderMesh->mBoundingBox;
|
||||
if (lcGetPiecesLibrary()->LoadPieceData(this))
|
||||
mFlags &= ~LC_PIECE_PLACEHOLDER;
|
||||
else
|
||||
{
|
||||
mFlags |= LC_PIECE_HAS_DEFAULT | LC_PIECE_HAS_LINES;
|
||||
mBoundingBox = gPlaceholderMesh->mBoundingBox;
|
||||
}
|
||||
}
|
||||
else
|
||||
lcGetPiecesLibrary()->LoadPieceData(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
lcGetPiecesLibrary()->LoadPiece(this);
|
||||
mBoundingBox = mMesh->mBoundingBox;
|
||||
}
|
||||
|
||||
mState = LC_PIECEINFO_LOADED;
|
||||
}
|
||||
|
||||
void PieceInfo::Unload()
|
||||
@@ -174,7 +180,7 @@ void PieceInfo::Unload()
|
||||
mMesh = NULL;
|
||||
}
|
||||
|
||||
mLoaded = false;
|
||||
mState = LC_PIECEINFO_UNLOADED;
|
||||
mModel = NULL;
|
||||
|
||||
if (IsModel())
|
||||
|
||||
+18
-25
@@ -15,6 +15,13 @@
|
||||
|
||||
#define LC_PIECE_NAME_LEN 256
|
||||
|
||||
enum lcPieceInfoState
|
||||
{
|
||||
LC_PIECEINFO_UNLOADED,
|
||||
LC_PIECEINFO_LOADING,
|
||||
LC_PIECEINFO_LOADED
|
||||
};
|
||||
|
||||
class lcSynthInfo;
|
||||
|
||||
class PieceInfo
|
||||
@@ -56,36 +63,23 @@ public:
|
||||
return mModel;
|
||||
}
|
||||
|
||||
void SetMesh(lcMesh* Mesh)
|
||||
{
|
||||
mMesh = Mesh;
|
||||
}
|
||||
void SetMesh(lcMesh* Mesh);
|
||||
|
||||
void AddRef()
|
||||
int AddRef()
|
||||
{
|
||||
mRefCount++;
|
||||
|
||||
if (!mLoaded)
|
||||
Load();
|
||||
return mRefCount;
|
||||
}
|
||||
|
||||
void Release()
|
||||
int Release()
|
||||
{
|
||||
mRefCount--;
|
||||
|
||||
if (!mRefCount)
|
||||
Unload();
|
||||
return mRefCount;
|
||||
}
|
||||
|
||||
void UnloadIfUnused()
|
||||
int GetRefCount() const
|
||||
{
|
||||
if (!mRefCount && mLoaded)
|
||||
Unload();
|
||||
}
|
||||
|
||||
bool IsLoaded() const
|
||||
{
|
||||
return mLoaded;
|
||||
return mRefCount;
|
||||
}
|
||||
|
||||
bool IsPlaceholder() const
|
||||
@@ -153,25 +147,24 @@ public:
|
||||
void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcArray<lcModelPartsEntry>& ModelParts) const;
|
||||
void UpdateBoundingBox(lcArray<lcModel*>& UpdatedModels);
|
||||
|
||||
void Load();
|
||||
void Unload();
|
||||
|
||||
public:
|
||||
// Attributes
|
||||
char m_strName[LC_PIECE_NAME_LEN];
|
||||
char m_strDescription[128];
|
||||
int mZipFileType;
|
||||
int mZipFileIndex;
|
||||
lcuint32 mFlags;
|
||||
lcPieceInfoState mState;
|
||||
|
||||
protected:
|
||||
bool mLoaded;
|
||||
int mRefCount;
|
||||
lcModel* mModel;
|
||||
Project* mProject;
|
||||
lcMesh* mMesh;
|
||||
lcBoundingBox mBoundingBox;
|
||||
lcSynthInfo* mSynthInfo;
|
||||
|
||||
void Load();
|
||||
void Unload();
|
||||
};
|
||||
|
||||
#endif // _PIECEINF_H_
|
||||
|
||||
Reference in New Issue
Block a user