Changed the library cache to use loose files.

This commit is contained in:
leo 2015-07-22 04:00:47 +00:00
parent 4e0d23e3df
commit b53debf017
10 changed files with 250 additions and 254 deletions

View file

@ -107,25 +107,25 @@ void lcApplication::GetFileList(const char* Path, lcArray<String>& FileList)
} }
} }
bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LDrawPath, const char* LibraryCachePath) bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LDrawPath)
{ {
if (mLibrary == NULL) if (mLibrary == NULL)
mLibrary = new lcPiecesLibrary(); mLibrary = new lcPiecesLibrary();
if (LibPath && LibPath[0]) if (LibPath && LibPath[0])
return mLibrary->Load(LibPath, LibraryCachePath); return mLibrary->Load(LibPath);
char* EnvPath = getenv("LEOCAD_LIB"); char* EnvPath = getenv("LEOCAD_LIB");
if (EnvPath && EnvPath[0]) if (EnvPath && EnvPath[0])
{ {
return mLibrary->Load(EnvPath, LibraryCachePath); return mLibrary->Load(EnvPath);
} }
QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY); QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY);
if (!CustomPath.isEmpty()) if (!CustomPath.isEmpty())
return mLibrary->Load(CustomPath.toLatin1().constData(), LibraryCachePath); // todo: qstring return mLibrary->Load(CustomPath.toLatin1().constData()); // todo: qstring
if (LibraryInstallPath && LibraryInstallPath[0]) if (LibraryInstallPath && LibraryInstallPath[0])
{ {
@ -139,7 +139,7 @@ bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryIn
strcat(LibraryPath, "library.bin"); strcat(LibraryPath, "library.bin");
if (mLibrary->Load(LibraryPath, LibraryCachePath)) if (mLibrary->Load(LibraryPath))
{ {
mLibrary->SetOfficialPieces(); mLibrary->SetOfficialPieces();
return true; return true;
@ -156,7 +156,7 @@ bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryIn
if ((LibraryPath[i] != '\\') && (LibraryPath[i] != '/')) if ((LibraryPath[i] != '\\') && (LibraryPath[i] != '/'))
strcat(LibraryPath, "/"); strcat(LibraryPath, "/");
if (mLibrary->Load(LibraryPath, LibraryCachePath)) if (mLibrary->Load(LibraryPath))
return true; return true;
} }
@ -195,7 +195,7 @@ void lcApplication::ParseStringArgument(int* CurArg, int argc, char* argv[], cha
} }
} }
bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstallPath, const char* LDrawPath, const char* LibraryCachePath) bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstallPath, const char* LDrawPath)
{ {
char* LibPath = NULL; char* LibPath = NULL;
@ -312,7 +312,7 @@ bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstal
gMainWindow = new lcMainWindow(); gMainWindow = new lcMainWindow();
lcLoadDefaultKeyboardShortcuts(); lcLoadDefaultKeyboardShortcuts();
if (!LoadPiecesLibrary(LibPath, LibraryInstallPath, LDrawPath, LibraryCachePath)) if (!LoadPiecesLibrary(LibPath, LibraryInstallPath, LDrawPath))
{ {
if (SaveImage || SaveWavefront || Save3DS) if (SaveImage || SaveWavefront || Save3DS)
{ {

View file

@ -42,11 +42,11 @@ public:
~lcApplication(); ~lcApplication();
void SetProject(Project* Project); void SetProject(Project* Project);
bool Initialize(int argc, char *argv[], const char* LibraryInstallPath, const char* LDrawPath, const char* LibraryCachePath); bool Initialize(int argc, char *argv[], const char* LibraryInstallPath, const char* LDrawPath);
void Shutdown(); void Shutdown();
void ShowPreferencesDialog(); void ShowPreferencesDialog();
bool LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LDrawPath, const char* LibraryCachePath); bool LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LDrawPath);
void GetFileList(const char* Path, lcArray<String>& FileList); void GetFileList(const char* Path, lcArray<String>& FileList);
void SetClipboard(const QByteArray& Clipboard); void SetClipboard(const QByteArray& Clipboard);

View file

@ -8,10 +8,6 @@
#define LC_FOURCC(ch0, ch1, ch2, ch3) (lcuint32)((lcuint32)(lcuint8)(ch0) | ((lcuint32)(lcuint8)(ch1) << 8) | \ #define LC_FOURCC(ch0, ch1, ch2, ch3) (lcuint32)((lcuint32)(lcuint8)(ch0) | ((lcuint32)(lcuint8)(ch1) << 8) | \
((lcuint32)(lcuint8)(ch2) << 16) | ((lcuint32)(lcuint8)(ch3) << 24 )) ((lcuint32)(lcuint8)(ch2) << 16) | ((lcuint32)(lcuint8)(ch3) << 24 ))
#define LC_FILE_ID LC_FOURCC('L','C','D', 0)
class String;
class lcFile class lcFile
{ {
public: public:

View file

@ -15,6 +15,13 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
#include <locale.h> #include <locale.h>
#include <zlib.h>
#if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
#else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
#endif
#define LC_LIBRARY_CACHE_VERSION 0x0104 #define LC_LIBRARY_CACHE_VERSION 0x0104
#define LC_LIBRARY_CACHE_ARCHIVE 0x0001 #define LC_LIBRARY_CACHE_ARCHIVE 0x0001
@ -22,17 +29,22 @@
lcPiecesLibrary::lcPiecesLibrary() lcPiecesLibrary::lcPiecesLibrary()
{ {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
QStringList cachePathList = QStandardPaths::standardLocations(QStandardPaths::CacheLocation);
mCachePath = cachePathList.first();
#else
mCachePath = QDesktopServices::storageLocation(QDesktopServices::CacheLocation);
#endif
QDir Dir;
Dir.mkpath(mCachePath);
mNumOfficialPieces = 0; mNumOfficialPieces = 0;
mLibraryPath[0] = 0; mLibraryPath[0] = 0;
mCacheFileName[0] = 0;
mCacheFileModifiedTime = 0;
mLibraryFileName[0] = 0; mLibraryFileName[0] = 0;
mUnofficialFileName[0] = 0; mUnofficialFileName[0] = 0;
mZipFiles[LC_ZIPFILE_OFFICIAL] = NULL; mZipFiles[LC_ZIPFILE_OFFICIAL] = NULL;
mZipFiles[LC_ZIPFILE_UNOFFICIAL] = NULL; mZipFiles[LC_ZIPFILE_UNOFFICIAL] = NULL;
mCacheFile = NULL;
mCacheFileName[0] = 0;
mSaveCache = false;
mBuffersDirty = false; mBuffersDirty = false;
} }
@ -43,8 +55,6 @@ lcPiecesLibrary::~lcPiecesLibrary()
void lcPiecesLibrary::Unload() void lcPiecesLibrary::Unload()
{ {
SaveCacheFile();
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
delete mPieces[PieceIdx]; delete mPieces[PieceIdx];
mPieces.RemoveAll(); mPieces.RemoveAll();
@ -124,7 +134,7 @@ lcTexture* lcPiecesLibrary::FindTexture(const char* TextureName)
return NULL; return NULL;
} }
bool lcPiecesLibrary::Load(const char* LibraryPath, const char* CachePath) bool lcPiecesLibrary::Load(const char* LibraryPath)
{ {
Unload(); Unload();
@ -146,7 +156,7 @@ bool lcPiecesLibrary::Load(const char* LibraryPath, const char* CachePath)
OpenArchive(UnofficialFileName, LC_ZIPFILE_UNOFFICIAL); OpenArchive(UnofficialFileName, LC_ZIPFILE_UNOFFICIAL);
ReadArchiveDescriptions(LibraryPath, UnofficialFileName, CachePath); ReadArchiveDescriptions(LibraryPath, UnofficialFileName);
} }
else else
{ {
@ -300,75 +310,22 @@ bool lcPiecesLibrary::OpenArchive(lcFile* File, const char* FileName, lcZipFileT
return true; return true;
} }
void lcPiecesLibrary::ReadArchiveDescriptions(const char* OfficialFileName, const char* UnofficialFileName, const char* CachePath) void lcPiecesLibrary::ReadArchiveDescriptions(const QString& OfficialFileName, const QString& UnofficialFileName)
{ {
bool CacheValid = false; QFileInfo OfficialInfo(OfficialFileName);
struct stat OfficialStat, UnofficialStat; QFileInfo UnofficialInfo(OfficialFileName);
mArchiveCheckSum[0] = OfficialInfo.size();
mArchiveCheckSum[1] = OfficialInfo.lastModified().toMSecsSinceEpoch();
mArchiveCheckSum[2] = UnofficialInfo.size();
mArchiveCheckSum[3] = UnofficialInfo.lastModified().toMSecsSinceEpoch();
strcpy(mCacheFileName, CachePath); QString IndexFileName = QFileInfo(QDir(mCachePath), QLatin1String("index")).absoluteFilePath();
mCacheFileModifiedTime = 0;
if (mCacheFileName[0]) if (!LoadCacheIndex(IndexFileName))
{
int Length = strlen(mCacheFileName);
if (mCacheFileName[Length] != '/' && mCacheFileName[Length] != '\\')
strcat(mCacheFileName, "/");
strcat(mCacheFileName, "library.cache");
}
if (stat(OfficialFileName, &OfficialStat) == 0)
{
lcuint64 CheckSum[4] =
{
(lcuint64)OfficialStat.st_size, (lcuint64)OfficialStat.st_mtime, 0, 0
};
if (stat(UnofficialFileName, &UnofficialStat) == 0)
{
CheckSum[2] = (lcuint64)UnofficialStat.st_size;
CheckSum[3] = (lcuint64)UnofficialStat.st_mtime;
}
lcZipFile CacheFile;
if (CacheFile.OpenRead(mCacheFileName))
{
lcMemFile VersionFile;
if (CacheFile.ExtractFile("version", VersionFile))
{
lcuint32 CacheVersion;
lcuint32 CacheFlags;
if (VersionFile.ReadU32(&CacheVersion, 1) && VersionFile.ReadU32(&CacheFlags, 1) &&
CacheVersion == LC_LIBRARY_CACHE_VERSION && CacheFlags == LC_LIBRARY_CACHE_ARCHIVE)
{
lcuint64 CacheCheckSum[4];
if (VersionFile.ReadU64(CacheCheckSum, 4))
CacheValid = (memcmp(CacheCheckSum, CheckSum, sizeof(CheckSum)) == 0);
}
}
}
if (CacheValid)
CacheValid = LoadCacheIndex(CacheFile);
}
if (CacheValid)
{
struct stat CacheStat;
if (stat(mCacheFileName, &CacheStat) == 0)
mCacheFileModifiedTime = CacheStat.st_mtime;
}
else
{ {
lcMemFile PieceFile; lcMemFile PieceFile;
mSaveCache = true;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++) for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
{ {
PieceInfo* Info = mPieces[PieceInfoIndex]; PieceInfo* Info = mPieces[PieceInfoIndex];
@ -392,6 +349,8 @@ void lcPiecesLibrary::ReadArchiveDescriptions(const char* OfficialFileName, cons
break; break;
} }
} }
SaveCacheIndex(IndexFileName);
} }
} }
@ -624,199 +583,258 @@ bool lcPiecesLibrary::OpenDirectory(const char* Path)
return true; return true;
} }
bool lcPiecesLibrary::OpenCache() bool lcPiecesLibrary::ReadCacheFile(const QString& FileName, lcMemFile& CacheFile)
{ {
struct stat CacheStat; QFile File(FileName);
if (!mCacheFileName[0]) if (!File.open(QIODevice::ReadOnly))
return false; return false;
if (stat(mCacheFileName, &CacheStat) != 0 || mCacheFileModifiedTime != (lcuint64)CacheStat.st_mtime) quint32 CacheVersion, CacheFlags;
if (File.read((char*)&CacheVersion, sizeof(CacheVersion)) == -1 || CacheVersion != LC_LIBRARY_CACHE_VERSION)
return false; return false;
mCacheFile = new lcZipFile; if (File.read((char*)&CacheFlags, sizeof(CacheFlags)) == -1 || CacheFlags != LC_LIBRARY_CACHE_ARCHIVE)
return false;
if (!mCacheFile->OpenRead(mCacheFileName)) qint64 CacheCheckSum[4];
if (File.read((char*)&CacheCheckSum, sizeof(CacheCheckSum)) == -1 || memcmp(CacheCheckSum, mArchiveCheckSum, sizeof(CacheCheckSum)))
return false;
quint32 UncompressedSize;
if (File.read((char*)&UncompressedSize, sizeof(UncompressedSize)) == -1)
return false;
QByteArray CompressedData = File.readAll();
CacheFile.SetLength(UncompressedSize);
CacheFile.Seek(0, SEEK_SET);
const int CHUNK = 16384;
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
int pos;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
pos = 0;
ret = inflateInit2(&strm, -MAX_WBITS);
if (ret != Z_OK)
return ret;
do
{ {
delete mCacheFile; strm.avail_in = lcMin(CompressedData.size() - pos, CHUNK);
mCacheFile = NULL; strm.next_in = in;
if (strm.avail_in == 0)
break;
memcpy(in, CompressedData.constData() + pos, strm.avail_in);
pos += strm.avail_in;
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
switch (ret)
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
CacheFile.WriteBuffer(out, have);
} while (strm.avail_out == 0);
} while (ret != Z_STREAM_END);
(void)inflateEnd(&strm);
CacheFile.Seek(0, SEEK_SET);
return ret == Z_STREAM_END;
}
bool lcPiecesLibrary::WriteCacheFile(const QString& FileName, lcMemFile& CacheFile)
{
QFile File(FileName);
if (!File.open(QIODevice::WriteOnly))
return false; return false;
}
quint32 CacheVersion = LC_LIBRARY_CACHE_VERSION;
quint32 CacheFlags = LC_LIBRARY_CACHE_ARCHIVE;
if (File.write((char*)&CacheVersion, sizeof(CacheVersion)) == -1)
return false;
if (File.write((char*)&CacheFlags, sizeof(CacheFlags)) == -1)
return false;
if (File.write((char*)&mArchiveCheckSum, sizeof(mArchiveCheckSum)) == -1)
return false;
quint32 UncompressedSize = CacheFile.GetLength();
if (File.write((char*)&UncompressedSize, sizeof(UncompressedSize)) == -1)
return false;
const size_t BufferSize = 16384;
char WriteBuffer[BufferSize];
z_stream Stream;
lcuint32 Crc32 = 0;
CacheFile.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;
Bytef* BufferIn = CacheFile.mBuffer;
int FlushMode;
do
{
uInt Read = lcMin(CacheFile.GetLength() - (BufferIn - CacheFile.mBuffer), BufferSize);
Stream.avail_in = Read;
Stream.next_in = BufferIn;
Crc32 = crc32(Crc32, BufferIn, Read);
BufferIn += Read;
FlushMode = (BufferIn >= CacheFile.mBuffer + CacheFile.GetLength()) ? Z_FINISH : Z_NO_FLUSH;
do
{
Stream.avail_out = BufferSize;
Stream.next_out = (Bytef*)WriteBuffer;
deflate(&Stream, FlushMode);
File.write(WriteBuffer, BufferSize - Stream.avail_out);
} while (Stream.avail_out == 0);
} while (FlushMode != Z_FINISH);
deflateEnd(&Stream);
return true; return true;
} }
void lcPiecesLibrary::CloseCache() bool lcPiecesLibrary::LoadCacheIndex(const QString& FileName)
{
delete mCacheFile;
mCacheFile = NULL;
SaveCacheFile();
}
bool lcPiecesLibrary::LoadCacheIndex(lcZipFile& CacheFile)
{ {
lcMemFile IndexFile; lcMemFile IndexFile;
if (!CacheFile.ExtractFile("index", IndexFile)) if (!ReadCacheFile(FileName, IndexFile))
return false; return false;
lcuint32 NumFiles; qint32 NumFiles;
if (!IndexFile.ReadU32(&NumFiles, 1) || NumFiles != (lcuint32)mPieces.GetSize()) if (IndexFile.ReadBuffer((char*)&NumFiles, sizeof(NumFiles)) == 0 || NumFiles != mPieces.GetSize())
return false; return false;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++) for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
{ {
PieceInfo* Info = mPieces[PieceInfoIndex]; PieceInfo* Info = mPieces[PieceInfoIndex];
lcuint8 Length; quint8 Length;
if (!IndexFile.ReadU8(&Length, 1) || Length >= sizeof(Info->m_strDescription)) if (IndexFile.ReadBuffer((char*)&Length, sizeof(Length)) == 0 || Length >= sizeof(Info->m_strDescription))
return false; return false;
if (!IndexFile.ReadBuffer(Info->m_strDescription, Length) || !IndexFile.ReadU32(&Info->mFlags, 1)) if (IndexFile.ReadBuffer((char*)Info->m_strDescription, Length) == 0 || IndexFile.ReadBuffer((char*)&Info->mFlags, sizeof(Info->mFlags)) == 0)
return false; return false;
Info->m_strDescription[Length] = 0; Info->m_strDescription[Length] = 0;
if (!IndexFile.ReadFloats(Info->m_fDimensions, 6))
return false;
} }
return true; return true;
} }
bool lcPiecesLibrary::LoadCachePiece(PieceInfo* Info) bool lcPiecesLibrary::SaveCacheIndex(const QString& FileName)
{ {
if ((Info->mFlags & LC_PIECE_CACHED) == 0) lcMemFile IndexFile;
qint32 NumFiles = mPieces.GetSize();
if (IndexFile.WriteBuffer((char*)&NumFiles, sizeof(NumFiles)) == 0)
return false; return false;
if (mCacheFile) for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
{ {
lcMemFile PieceFile; PieceInfo* Info = mPieces[PieceInfoIndex];
quint8 Length = strlen(Info->m_strDescription);
if (!mCacheFile->ExtractFile(Info->m_strName, PieceFile)) if (IndexFile.WriteBuffer((char*)&Length, sizeof(Length)) == 0)
return false; return false;
lcMesh* Mesh = new lcMesh; if (IndexFile.WriteBuffer((char*)Info->m_strDescription, Length) == 0 || IndexFile.WriteBuffer((char*)&Info->mFlags, sizeof(Info->mFlags)) == 0)
Info->SetMesh(Mesh); return false;
return Mesh->FileLoad(PieceFile);
} }
else
{
struct stat CacheStat;
if (stat(mCacheFileName, &CacheStat) != 0 || mCacheFileModifiedTime != (lcuint64)CacheStat.st_mtime) return WriteCacheFile(FileName, IndexFile);
return false;
lcZipFile CacheFile;
if (!CacheFile.OpenRead(mCacheFileName))
return false;
lcMemFile PieceFile;
if (!CacheFile.ExtractFile(Info->m_strName, PieceFile))
return false;
lcMesh* Mesh = new lcMesh;
Info->SetMesh(Mesh);
return Mesh->FileLoad(PieceFile);
}
} }
void lcPiecesLibrary::SaveCacheFile() bool lcPiecesLibrary::LoadCachePiece(PieceInfo* Info)
{ {
struct stat CacheStat; QString FileName = QFileInfo(QDir(mCachePath), QString::fromLatin1(Info->m_strName)).absoluteFilePath();
lcZipFile CacheFile; lcMemFile MeshData;
if (!mSaveCache) if (!ReadCacheFile(FileName, MeshData))
return; return false;
if (stat(mCacheFileName, &CacheStat) != 0 || mCacheFileModifiedTime != (lcuint64)CacheStat.st_mtime) lcMesh* Mesh = new lcMesh;
{ Info->SetMesh(Mesh);
if (!CacheFile.OpenWrite(mCacheFileName, false))
return;
struct stat OfficialStat, UnofficialStat; quint32 Flags;
if (MeshData.ReadBuffer((char*)&Flags, sizeof(Flags)) == 0)
return false;
if (stat(mLibraryFileName, &OfficialStat) != 0) Info->mFlags = Flags;
return;
lcuint64 CheckSum[4] = if (MeshData.ReadBuffer((char*)Info->m_fDimensions, sizeof(Info->m_fDimensions)) == 0) // todo: move dimensions to the mesh
{ return false;
(lcuint64)OfficialStat.st_size, (lcuint64)OfficialStat.st_mtime, 0, 0
};
if (stat(mUnofficialFileName, &UnofficialStat) == 0) if (MeshData.ReadBuffer((char*)&Info->GetMesh()->mRadius, sizeof(float)) == 0)
{ return false;
CheckSum[2] = (lcuint64)UnofficialStat.st_size;
CheckSum[3] = (lcuint64)UnofficialStat.st_mtime;
}
lcMemFile VersionFile; return Mesh->FileLoad(MeshData);
}
VersionFile.WriteU32(LC_LIBRARY_CACHE_VERSION); bool lcPiecesLibrary::SaveCachePiece(PieceInfo* Info)
VersionFile.WriteU32(LC_LIBRARY_CACHE_ARCHIVE); {
VersionFile.WriteU64(CheckSum, 4); lcMemFile MeshData;
CacheFile.AddFile("version", VersionFile); quint32 Flags = Info->mFlags;
} if (MeshData.WriteBuffer((char*)&Flags, sizeof(Flags)) == 0)
else return false;
{
if (!CacheFile.OpenWrite(mCacheFileName, true))
return;
CacheFile.DeleteFile("index"); if (MeshData.WriteBuffer((char*)Info->m_fDimensions, sizeof(Info->m_fDimensions)) == 0)
} return false;
lcMemFile IndexFile; if (MeshData.WriteBuffer((char*)&Info->GetMesh()->mRadius, sizeof(float)) == 0)
int NumPieces = 0; return false;
IndexFile.WriteU32(0); if (!Info->GetMesh()->FileSave(MeshData))
return false;
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) QString FileName = QFileInfo(QDir(mCachePath), QString::fromLatin1(Info->m_strName)).absoluteFilePath();
{
PieceInfo* Info = mPieces[PieceIdx];
if (Info->mFlags & LC_PIECE_PLACEHOLDER || Info->mFlags & LC_PIECE_MODEL) return WriteCacheFile(FileName, MeshData);
continue;
bool Cached = (Info->mFlags & LC_PIECE_CACHED) != 0;
lcMesh* Mesh = Info->GetMesh();
if (Mesh)
Info->mFlags |= LC_PIECE_CACHED;
int Length = strlen(Info->m_strDescription);
IndexFile.WriteU8(Length);
IndexFile.WriteBuffer(Info->m_strDescription, Length);
IndexFile.WriteU32(Info->mFlags);
IndexFile.WriteFloats(Info->m_fDimensions, 6);
NumPieces++;
if (Cached || !Mesh)
continue;
lcMemFile PieceFile;
Mesh->FileSave(PieceFile);
CacheFile.AddFile(Info->m_strName, PieceFile);
Info->mFlags |= LC_PIECE_CACHED;
}
IndexFile.Seek(0, SEEK_SET);
IndexFile.WriteU32(NumPieces);
CacheFile.AddFile("index", IndexFile);
mSaveCache = false;
} }
struct lcMergeSection struct lcMergeSection
@ -908,7 +926,7 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info)
CreateMesh(Info, MeshData); CreateMesh(Info, MeshData);
if (mZipFiles[LC_ZIPFILE_OFFICIAL]) if (mZipFiles[LC_ZIPFILE_OFFICIAL])
mSaveCache = true; SaveCachePiece(Info);
return true; return true;
} }
@ -2362,8 +2380,6 @@ bool lcPiecesLibrary::LoadBuiltinPieces()
lcMemFile PieceFile; lcMemFile PieceFile;
mSaveCache = false;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++) for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
{ {
PieceInfo* Info = mPieces[PieceInfoIndex]; PieceInfo* Info = mPieces[PieceInfoIndex];

View file

@ -126,7 +126,7 @@ public:
lcPiecesLibrary(); lcPiecesLibrary();
~lcPiecesLibrary(); ~lcPiecesLibrary();
bool Load(const char* LibraryPath, const char* CachePath); bool Load(const char* LibraryPath);
void Unload(); void Unload();
void RemoveTemporaryPieces(); void RemoveTemporaryPieces();
void RemovePiece(PieceInfo* Info); void RemovePiece(PieceInfo* Info);
@ -138,9 +138,6 @@ public:
lcTexture* FindTexture(const char* TextureName); lcTexture* FindTexture(const char* TextureName);
bool LoadTexture(lcTexture* Texture); bool LoadTexture(lcTexture* Texture);
bool OpenCache();
void CloseCache();
bool PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const; bool PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const;
void SearchPieces(const char* Keyword, lcArray<PieceInfo*>& Pieces) const; void SearchPieces(const char* Keyword, lcArray<PieceInfo*>& Pieces) const;
void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray<PieceInfo*>& SinglePieces, lcArray<PieceInfo*>& GroupedPieces); void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray<PieceInfo*>& SinglePieces, lcArray<PieceInfo*>& GroupedPieces);
@ -178,20 +175,20 @@ protected:
bool OpenArchive(const char* FileName, lcZipFileType ZipFileType); bool OpenArchive(const char* FileName, lcZipFileType ZipFileType);
bool OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType); bool OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType);
bool OpenDirectory(const char* Path); bool OpenDirectory(const char* Path);
void ReadArchiveDescriptions(const char* OfficialFileName, const char* UnofficialFileName, const char* CachePath); void ReadArchiveDescriptions(const QString& OfficialFileName, const QString& UnofficialFileName);
bool LoadCacheIndex(lcZipFile& CacheFile); bool ReadCacheFile(const QString& FileName, lcMemFile& CacheFile);
bool WriteCacheFile(const QString& FileName, lcMemFile& CacheFile);
bool LoadCacheIndex(const QString& FileName);
bool SaveCacheIndex(const QString& FileName);
bool LoadCachePiece(PieceInfo* Info); bool LoadCachePiece(PieceInfo* Info);
void SaveCacheFile(); bool SaveCachePiece(PieceInfo* Info);
int FindPrimitiveIndex(const char* Name) const; int FindPrimitiveIndex(const char* Name) const;
bool LoadPrimitive(int PrimitiveIndex); bool LoadPrimitive(int PrimitiveIndex);
char mCacheFileName[LC_MAXPATH]; QString mCachePath;
lcuint64 mCacheFileModifiedTime; qint64 mArchiveCheckSum[4];
lcZipFile* mCacheFile;
bool mSaveCache;
char mLibraryFileName[LC_MAXPATH]; char mLibraryFileName[LC_MAXPATH];
char mUnofficialFileName[LC_MAXPATH]; char mUnofficialFileName[LC_MAXPATH];
lcZipFile* mZipFiles[LC_NUM_ZIPFILES]; lcZipFile* mZipFiles[LC_NUM_ZIPFILES];

View file

@ -291,9 +291,9 @@ void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int Ver
ExportWavefrontIndices<GLuint>(File, DefaultColorIndex, VertexOffset); ExportWavefrontIndices<GLuint>(File, DefaultColorIndex, VertexOffset);
} }
bool lcMesh::FileLoad(lcFile& File) bool lcMesh::FileLoad(lcMemFile& File)
{ {
if (File.ReadU32() != LC_FILE_ID || File.ReadU32() != LC_MESH_FILE_ID || File.ReadU32() != LC_MESH_FILE_VERSION) if (File.ReadU32() != LC_MESH_FILE_ID || File.ReadU32() != LC_MESH_FILE_VERSION)
return false; return false;
lcuint32 NumVertices, NumTexturedVertices, NumIndices; lcuint32 NumVertices, NumTexturedVertices, NumIndices;
@ -353,9 +353,8 @@ bool lcMesh::FileLoad(lcFile& File)
return true; return true;
} }
void lcMesh::FileSave(lcFile& File) bool lcMesh::FileSave(lcMemFile& File)
{ {
File.WriteU32(LC_FILE_ID);
File.WriteU32(LC_MESH_FILE_ID); File.WriteU32(LC_MESH_FILE_ID);
File.WriteU32(LC_MESH_FILE_VERSION); File.WriteU32(LC_MESH_FILE_VERSION);
@ -394,6 +393,8 @@ void lcMesh::FileSave(lcFile& File)
File.WriteU16((lcuint16*)mIndexData, mIndexDataSize / 2); File.WriteU16((lcuint16*)mIndexData, mIndexDataSize / 2);
else else
File.WriteU32((lcuint32*)mIndexData, mIndexDataSize / 4); File.WriteU32((lcuint32*)mIndexData, mIndexDataSize / 4);
return true;
} }
int lcMesh::GetLodIndex(float Distance) const int lcMesh::GetLodIndex(float Distance) const

View file

@ -49,8 +49,8 @@ public:
void Create(lcuint16 NumSections[LC_NUM_MESH_LODS], int NumVertices, int NumTexturedVertices, int NumIndices); void Create(lcuint16 NumSections[LC_NUM_MESH_LODS], int NumVertices, int NumTexturedVertices, int NumIndices);
void CreateBox(); void CreateBox();
bool FileLoad(lcFile& File); bool FileLoad(lcMemFile& File);
void FileSave(lcFile& File); bool FileSave(lcMemFile& File);
template<typename IndexType> template<typename IndexType>
void ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable); void ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable);

View file

@ -621,7 +621,6 @@ bool lcModel::LoadBinary(lcFile* file)
file->ReadS32(&count, 1); file->ReadS32(&count, 1);
lcPiecesLibrary* Library = lcGetPiecesLibrary(); lcPiecesLibrary* Library = lcGetPiecesLibrary();
Library->OpenCache();
int FirstNewPiece = mPieces.GetSize(); int FirstNewPiece = mPieces.GetSize();
@ -661,8 +660,6 @@ bool lcModel::LoadBinary(lcFile* file)
} }
} }
Library->CloseCache();
if (fv >= 0.4f) if (fv >= 0.4f)
{ {
file->ReadBuffer(&ch, 1); file->ReadBuffer(&ch, 1);

View file

@ -11,8 +11,7 @@
#define LC_PIECE_HAS_TRANSLUCENT 0x04 // Piece has triangles using a translucent color #define LC_PIECE_HAS_TRANSLUCENT 0x04 // Piece has triangles using a translucent color
#define LC_PIECE_HAS_LINES 0x08 // Piece has lines #define LC_PIECE_HAS_LINES 0x08 // Piece has lines
#define LC_PIECE_PLACEHOLDER 0x10 // Placeholder for a piece not in the library #define LC_PIECE_PLACEHOLDER 0x10 // Placeholder for a piece not in the library
#define LC_PIECE_CACHED 0x20 // Piece is saved in the library cache #define LC_PIECE_MODEL 0x20 // Piece is a model
#define LC_PIECE_MODEL 0x40 // Piece if a model
#define LC_PIECE_NAME_LEN 256 #define LC_PIECE_NAME_LEN 256

View file

@ -165,17 +165,7 @@ int main(int argc, char *argv[])
const char* LDrawPath = NULL; const char* LDrawPath = NULL;
#endif #endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) if (!g_App->Initialize(argc, argv, libPath, LDrawPath))
QStringList cachePathList = QStandardPaths::standardLocations(QStandardPaths::CacheLocation);
QString cachePath = cachePathList.first();
#else
QString cachePath = QDesktopServices::storageLocation(QDesktopServices::CacheLocation);
#endif
QDir dir;
dir.mkpath(cachePath);
if (!g_App->Initialize(argc, argv, libPath, LDrawPath, cachePath.toLocal8Bit().data()))
return 1; return 1;
gMainWindow->SetColorIndex(lcGetColorIndex(4)); gMainWindow->SetColorIndex(lcGetColorIndex(4));