mirror of
https://github.com/leozide/leocad
synced 2025-01-17 18:11:42 +01:00
Changed the library cache to use loose files.
This commit is contained in:
parent
4e0d23e3df
commit
b53debf017
10 changed files with 250 additions and 254 deletions
|
@ -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)
|
||||
mLibrary = new lcPiecesLibrary();
|
||||
|
||||
if (LibPath && LibPath[0])
|
||||
return mLibrary->Load(LibPath, LibraryCachePath);
|
||||
return mLibrary->Load(LibPath);
|
||||
|
||||
char* EnvPath = getenv("LEOCAD_LIB");
|
||||
|
||||
if (EnvPath && EnvPath[0])
|
||||
{
|
||||
return mLibrary->Load(EnvPath, LibraryCachePath);
|
||||
return mLibrary->Load(EnvPath);
|
||||
}
|
||||
|
||||
QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY);
|
||||
|
||||
if (!CustomPath.isEmpty())
|
||||
return mLibrary->Load(CustomPath.toLatin1().constData(), LibraryCachePath); // todo: qstring
|
||||
return mLibrary->Load(CustomPath.toLatin1().constData()); // todo: qstring
|
||||
|
||||
if (LibraryInstallPath && LibraryInstallPath[0])
|
||||
{
|
||||
|
@ -139,7 +139,7 @@ bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryIn
|
|||
|
||||
strcat(LibraryPath, "library.bin");
|
||||
|
||||
if (mLibrary->Load(LibraryPath, LibraryCachePath))
|
||||
if (mLibrary->Load(LibraryPath))
|
||||
{
|
||||
mLibrary->SetOfficialPieces();
|
||||
return true;
|
||||
|
@ -156,7 +156,7 @@ bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryIn
|
|||
if ((LibraryPath[i] != '\\') && (LibraryPath[i] != '/'))
|
||||
strcat(LibraryPath, "/");
|
||||
|
||||
if (mLibrary->Load(LibraryPath, LibraryCachePath))
|
||||
if (mLibrary->Load(LibraryPath))
|
||||
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;
|
||||
|
||||
|
@ -312,7 +312,7 @@ bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstal
|
|||
gMainWindow = new lcMainWindow();
|
||||
lcLoadDefaultKeyboardShortcuts();
|
||||
|
||||
if (!LoadPiecesLibrary(LibPath, LibraryInstallPath, LDrawPath, LibraryCachePath))
|
||||
if (!LoadPiecesLibrary(LibPath, LibraryInstallPath, LDrawPath))
|
||||
{
|
||||
if (SaveImage || SaveWavefront || Save3DS)
|
||||
{
|
||||
|
|
|
@ -42,11 +42,11 @@ public:
|
|||
~lcApplication();
|
||||
|
||||
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 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 SetClipboard(const QByteArray& Clipboard);
|
||||
|
|
|
@ -8,10 +8,6 @@
|
|||
#define LC_FOURCC(ch0, ch1, ch2, ch3) (lcuint32)((lcuint32)(lcuint8)(ch0) | ((lcuint32)(lcuint8)(ch1) << 8) | \
|
||||
((lcuint32)(lcuint8)(ch2) << 16) | ((lcuint32)(lcuint8)(ch3) << 24 ))
|
||||
|
||||
#define LC_FILE_ID LC_FOURCC('L','C','D', 0)
|
||||
|
||||
class String;
|
||||
|
||||
class lcFile
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -15,6 +15,13 @@
|
|||
#include <sys/stat.h>
|
||||
#include <ctype.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_ARCHIVE 0x0001
|
||||
|
@ -22,17 +29,22 @@
|
|||
|
||||
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;
|
||||
mLibraryPath[0] = 0;
|
||||
mCacheFileName[0] = 0;
|
||||
mCacheFileModifiedTime = 0;
|
||||
mLibraryFileName[0] = 0;
|
||||
mUnofficialFileName[0] = 0;
|
||||
mZipFiles[LC_ZIPFILE_OFFICIAL] = NULL;
|
||||
mZipFiles[LC_ZIPFILE_UNOFFICIAL] = NULL;
|
||||
mCacheFile = NULL;
|
||||
mCacheFileName[0] = 0;
|
||||
mSaveCache = false;
|
||||
mBuffersDirty = false;
|
||||
}
|
||||
|
||||
|
@ -43,8 +55,6 @@ lcPiecesLibrary::~lcPiecesLibrary()
|
|||
|
||||
void lcPiecesLibrary::Unload()
|
||||
{
|
||||
SaveCacheFile();
|
||||
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
delete mPieces[PieceIdx];
|
||||
mPieces.RemoveAll();
|
||||
|
@ -124,7 +134,7 @@ lcTexture* lcPiecesLibrary::FindTexture(const char* TextureName)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::Load(const char* LibraryPath, const char* CachePath)
|
||||
bool lcPiecesLibrary::Load(const char* LibraryPath)
|
||||
{
|
||||
Unload();
|
||||
|
||||
|
@ -146,7 +156,7 @@ bool lcPiecesLibrary::Load(const char* LibraryPath, const char* CachePath)
|
|||
|
||||
OpenArchive(UnofficialFileName, LC_ZIPFILE_UNOFFICIAL);
|
||||
|
||||
ReadArchiveDescriptions(LibraryPath, UnofficialFileName, CachePath);
|
||||
ReadArchiveDescriptions(LibraryPath, UnofficialFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -300,75 +310,22 @@ bool lcPiecesLibrary::OpenArchive(lcFile* File, const char* FileName, lcZipFileT
|
|||
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;
|
||||
struct stat OfficialStat, UnofficialStat;
|
||||
QFileInfo OfficialInfo(OfficialFileName);
|
||||
QFileInfo UnofficialInfo(OfficialFileName);
|
||||
|
||||
mArchiveCheckSum[0] = OfficialInfo.size();
|
||||
mArchiveCheckSum[1] = OfficialInfo.lastModified().toMSecsSinceEpoch();
|
||||
mArchiveCheckSum[2] = UnofficialInfo.size();
|
||||
mArchiveCheckSum[3] = UnofficialInfo.lastModified().toMSecsSinceEpoch();
|
||||
|
||||
strcpy(mCacheFileName, CachePath);
|
||||
mCacheFileModifiedTime = 0;
|
||||
QString IndexFileName = QFileInfo(QDir(mCachePath), QLatin1String("index")).absoluteFilePath();
|
||||
|
||||
if (mCacheFileName[0])
|
||||
{
|
||||
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
|
||||
if (!LoadCacheIndex(IndexFileName))
|
||||
{
|
||||
lcMemFile PieceFile;
|
||||
|
||||
mSaveCache = true;
|
||||
|
||||
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||
|
@ -392,6 +349,8 @@ void lcPiecesLibrary::ReadArchiveDescriptions(const char* OfficialFileName, cons
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SaveCacheIndex(IndexFileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,199 +583,258 @@ bool lcPiecesLibrary::OpenDirectory(const char* Path)
|
|||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
mCacheFile = NULL;
|
||||
strm.avail_in = lcMin(CompressedData.size() - pos, CHUNK);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::CloseCache()
|
||||
{
|
||||
delete mCacheFile;
|
||||
mCacheFile = NULL;
|
||||
|
||||
SaveCacheFile();
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::LoadCacheIndex(lcZipFile& CacheFile)
|
||||
bool lcPiecesLibrary::LoadCacheIndex(const QString& FileName)
|
||||
{
|
||||
lcMemFile IndexFile;
|
||||
|
||||
if (!CacheFile.ExtractFile("index", IndexFile))
|
||||
if (!ReadCacheFile(FileName, IndexFile))
|
||||
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;
|
||||
|
||||
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); 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;
|
||||
|
||||
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;
|
||||
|
||||
Info->m_strDescription[Length] = 0;
|
||||
|
||||
if (!IndexFile.ReadFloats(Info->m_fDimensions, 6))
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
lcMesh* Mesh = new lcMesh;
|
||||
Info->SetMesh(Mesh);
|
||||
|
||||
return Mesh->FileLoad(PieceFile);
|
||||
if (IndexFile.WriteBuffer((char*)Info->m_strDescription, Length) == 0 || IndexFile.WriteBuffer((char*)&Info->mFlags, sizeof(Info->mFlags)) == 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct stat CacheStat;
|
||||
|
||||
if (stat(mCacheFileName, &CacheStat) != 0 || mCacheFileModifiedTime != (lcuint64)CacheStat.st_mtime)
|
||||
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);
|
||||
}
|
||||
return WriteCacheFile(FileName, IndexFile);
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::SaveCacheFile()
|
||||
bool lcPiecesLibrary::LoadCachePiece(PieceInfo* Info)
|
||||
{
|
||||
struct stat CacheStat;
|
||||
lcZipFile CacheFile;
|
||||
QString FileName = QFileInfo(QDir(mCachePath), QString::fromLatin1(Info->m_strName)).absoluteFilePath();
|
||||
lcMemFile MeshData;
|
||||
|
||||
if (!mSaveCache)
|
||||
return;
|
||||
if (!ReadCacheFile(FileName, MeshData))
|
||||
return false;
|
||||
|
||||
if (stat(mCacheFileName, &CacheStat) != 0 || mCacheFileModifiedTime != (lcuint64)CacheStat.st_mtime)
|
||||
{
|
||||
if (!CacheFile.OpenWrite(mCacheFileName, false))
|
||||
return;
|
||||
lcMesh* Mesh = new lcMesh;
|
||||
Info->SetMesh(Mesh);
|
||||
|
||||
struct stat OfficialStat, UnofficialStat;
|
||||
quint32 Flags;
|
||||
if (MeshData.ReadBuffer((char*)&Flags, sizeof(Flags)) == 0)
|
||||
return false;
|
||||
|
||||
if (stat(mLibraryFileName, &OfficialStat) != 0)
|
||||
return;
|
||||
Info->mFlags = Flags;
|
||||
|
||||
lcuint64 CheckSum[4] =
|
||||
{
|
||||
(lcuint64)OfficialStat.st_size, (lcuint64)OfficialStat.st_mtime, 0, 0
|
||||
};
|
||||
if (MeshData.ReadBuffer((char*)Info->m_fDimensions, sizeof(Info->m_fDimensions)) == 0) // todo: move dimensions to the mesh
|
||||
return false;
|
||||
|
||||
if (stat(mUnofficialFileName, &UnofficialStat) == 0)
|
||||
{
|
||||
CheckSum[2] = (lcuint64)UnofficialStat.st_size;
|
||||
CheckSum[3] = (lcuint64)UnofficialStat.st_mtime;
|
||||
}
|
||||
if (MeshData.ReadBuffer((char*)&Info->GetMesh()->mRadius, sizeof(float)) == 0)
|
||||
return false;
|
||||
|
||||
lcMemFile VersionFile;
|
||||
return Mesh->FileLoad(MeshData);
|
||||
}
|
||||
|
||||
VersionFile.WriteU32(LC_LIBRARY_CACHE_VERSION);
|
||||
VersionFile.WriteU32(LC_LIBRARY_CACHE_ARCHIVE);
|
||||
VersionFile.WriteU64(CheckSum, 4);
|
||||
bool lcPiecesLibrary::SaveCachePiece(PieceInfo* Info)
|
||||
{
|
||||
lcMemFile MeshData;
|
||||
|
||||
CacheFile.AddFile("version", VersionFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CacheFile.OpenWrite(mCacheFileName, true))
|
||||
return;
|
||||
quint32 Flags = Info->mFlags;
|
||||
if (MeshData.WriteBuffer((char*)&Flags, sizeof(Flags)) == 0)
|
||||
return false;
|
||||
|
||||
CacheFile.DeleteFile("index");
|
||||
}
|
||||
if (MeshData.WriteBuffer((char*)Info->m_fDimensions, sizeof(Info->m_fDimensions)) == 0)
|
||||
return false;
|
||||
|
||||
lcMemFile IndexFile;
|
||||
int NumPieces = 0;
|
||||
if (MeshData.WriteBuffer((char*)&Info->GetMesh()->mRadius, sizeof(float)) == 0)
|
||||
return false;
|
||||
|
||||
IndexFile.WriteU32(0);
|
||||
if (!Info->GetMesh()->FileSave(MeshData))
|
||||
return false;
|
||||
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceIdx];
|
||||
QString FileName = QFileInfo(QDir(mCachePath), QString::fromLatin1(Info->m_strName)).absoluteFilePath();
|
||||
|
||||
if (Info->mFlags & LC_PIECE_PLACEHOLDER || Info->mFlags & LC_PIECE_MODEL)
|
||||
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;
|
||||
return WriteCacheFile(FileName, MeshData);
|
||||
}
|
||||
|
||||
struct lcMergeSection
|
||||
|
@ -908,7 +926,7 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info)
|
|||
CreateMesh(Info, MeshData);
|
||||
|
||||
if (mZipFiles[LC_ZIPFILE_OFFICIAL])
|
||||
mSaveCache = true;
|
||||
SaveCachePiece(Info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2362,8 +2380,6 @@ bool lcPiecesLibrary::LoadBuiltinPieces()
|
|||
|
||||
lcMemFile PieceFile;
|
||||
|
||||
mSaveCache = false;
|
||||
|
||||
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||
|
|
|
@ -126,7 +126,7 @@ public:
|
|||
lcPiecesLibrary();
|
||||
~lcPiecesLibrary();
|
||||
|
||||
bool Load(const char* LibraryPath, const char* CachePath);
|
||||
bool Load(const char* LibraryPath);
|
||||
void Unload();
|
||||
void RemoveTemporaryPieces();
|
||||
void RemovePiece(PieceInfo* Info);
|
||||
|
@ -138,9 +138,6 @@ public:
|
|||
lcTexture* FindTexture(const char* TextureName);
|
||||
bool LoadTexture(lcTexture* Texture);
|
||||
|
||||
bool OpenCache();
|
||||
void CloseCache();
|
||||
|
||||
bool PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const;
|
||||
void SearchPieces(const char* Keyword, lcArray<PieceInfo*>& Pieces) const;
|
||||
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(lcFile* File, const char* FileName, lcZipFileType ZipFileType);
|
||||
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);
|
||||
void SaveCacheFile();
|
||||
bool SaveCachePiece(PieceInfo* Info);
|
||||
|
||||
int FindPrimitiveIndex(const char* Name) const;
|
||||
bool LoadPrimitive(int PrimitiveIndex);
|
||||
|
||||
char mCacheFileName[LC_MAXPATH];
|
||||
lcuint64 mCacheFileModifiedTime;
|
||||
lcZipFile* mCacheFile;
|
||||
bool mSaveCache;
|
||||
|
||||
QString mCachePath;
|
||||
qint64 mArchiveCheckSum[4];
|
||||
char mLibraryFileName[LC_MAXPATH];
|
||||
char mUnofficialFileName[LC_MAXPATH];
|
||||
lcZipFile* mZipFiles[LC_NUM_ZIPFILES];
|
||||
|
|
|
@ -291,9 +291,9 @@ void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int Ver
|
|||
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;
|
||||
|
||||
lcuint32 NumVertices, NumTexturedVertices, NumIndices;
|
||||
|
@ -353,9 +353,8 @@ bool lcMesh::FileLoad(lcFile& File)
|
|||
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_VERSION);
|
||||
|
||||
|
@ -394,6 +393,8 @@ void lcMesh::FileSave(lcFile& File)
|
|||
File.WriteU16((lcuint16*)mIndexData, mIndexDataSize / 2);
|
||||
else
|
||||
File.WriteU32((lcuint32*)mIndexData, mIndexDataSize / 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int lcMesh::GetLodIndex(float Distance) const
|
||||
|
|
|
@ -49,8 +49,8 @@ public:
|
|||
void Create(lcuint16 NumSections[LC_NUM_MESH_LODS], int NumVertices, int NumTexturedVertices, int NumIndices);
|
||||
void CreateBox();
|
||||
|
||||
bool FileLoad(lcFile& File);
|
||||
void FileSave(lcFile& File);
|
||||
bool FileLoad(lcMemFile& File);
|
||||
bool FileSave(lcMemFile& File);
|
||||
|
||||
template<typename IndexType>
|
||||
void ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable);
|
||||
|
|
|
@ -621,7 +621,6 @@ bool lcModel::LoadBinary(lcFile* file)
|
|||
|
||||
file->ReadS32(&count, 1);
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
Library->OpenCache();
|
||||
|
||||
int FirstNewPiece = mPieces.GetSize();
|
||||
|
||||
|
@ -661,8 +660,6 @@ bool lcModel::LoadBinary(lcFile* file)
|
|||
}
|
||||
}
|
||||
|
||||
Library->CloseCache();
|
||||
|
||||
if (fv >= 0.4f)
|
||||
{
|
||||
file->ReadBuffer(&ch, 1);
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
#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_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 0x40 // Piece if a model
|
||||
#define LC_PIECE_MODEL 0x20 // Piece is a model
|
||||
|
||||
#define LC_PIECE_NAME_LEN 256
|
||||
|
||||
|
|
|
@ -165,17 +165,7 @@ int main(int argc, char *argv[])
|
|||
const char* LDrawPath = NULL;
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
||||
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()))
|
||||
if (!g_App->Initialize(argc, argv, libPath, LDrawPath))
|
||||
return 1;
|
||||
|
||||
gMainWindow->SetColorIndex(lcGetColorIndex(4));
|
||||
|
|
Loading…
Reference in a new issue