Cache library contents between runs.
This commit is contained in:
@@ -47,7 +47,7 @@ void lcApplication::AddProject(Project* project)
|
||||
m_ActiveProject = project;
|
||||
}
|
||||
|
||||
bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* SysLibPath)
|
||||
bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LibraryCachePath)
|
||||
{
|
||||
// Create an empty library.
|
||||
if (m_Library == NULL)
|
||||
@@ -55,19 +55,19 @@ bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* SysLibPat
|
||||
|
||||
// Check if the user specified a library path in the command line.
|
||||
if (LibPath != NULL)
|
||||
if (m_Library->Load(LibPath))
|
||||
if (m_Library->Load(LibPath, LibraryCachePath))
|
||||
return true;
|
||||
|
||||
// Check for the LEOCAD_LIB environment variable.
|
||||
char* EnvPath = getenv("LEOCAD_LIB");
|
||||
|
||||
if (EnvPath != NULL)
|
||||
if (m_Library->Load(EnvPath))
|
||||
if (m_Library->Load(EnvPath, LibraryCachePath))
|
||||
return true;
|
||||
|
||||
// Try the executable install path last.
|
||||
if (SysLibPath != NULL)
|
||||
if (m_Library->Load(SysLibPath))
|
||||
if (LibraryInstallPath != NULL)
|
||||
if (m_Library->Load(LibraryInstallPath, LibraryCachePath))
|
||||
return true;
|
||||
|
||||
lcLoadDefaultColors();
|
||||
@@ -114,12 +114,11 @@ void lcApplication::ParseStringArgument(int* CurArg, int argc, char* argv[], cha
|
||||
}
|
||||
}
|
||||
|
||||
bool lcApplication::Initialize(int argc, char* argv[], const char* SysLibPath)
|
||||
bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstallPath, const char* LibraryCachePath)
|
||||
{
|
||||
// System setup parameters.
|
||||
char* LibPath = NULL;
|
||||
char* GLPath = NULL;
|
||||
char* LDrawPath = NULL;
|
||||
|
||||
// Image output options.
|
||||
bool SaveImage = false;
|
||||
@@ -208,7 +207,6 @@ bool lcApplication::Initialize(int argc, char* argv[], const char* SysLibPath)
|
||||
printf(" [options] can be:\n");
|
||||
printf(" --libgl <path>: Searches for OpenGL libraries in path.\n");
|
||||
printf(" --libpath <path>: Loads the Pieces Library from path.\n");
|
||||
printf(" --convert <srcpath> <dstpath>: Generates Pieces Library from LDraw files.\n");
|
||||
printf(" -i, --image <outfile.ext>: Saves a picture in the format specified by ext.\n");
|
||||
printf(" -w, --width <width>: Sets the picture width.\n");
|
||||
printf(" -h, --height <height>: Sets the picture height.\n");
|
||||
@@ -232,7 +230,7 @@ bool lcApplication::Initialize(int argc, char* argv[], const char* SysLibPath)
|
||||
if (!GL_Initialize(GLPath))
|
||||
return false;
|
||||
|
||||
if (!LoadPiecesLibrary(LibPath, SysLibPath))
|
||||
if (!LoadPiecesLibrary(LibPath, LibraryInstallPath, LibraryCachePath))
|
||||
return false;
|
||||
|
||||
SystemInit();
|
||||
|
||||
@@ -12,11 +12,11 @@ public:
|
||||
lcApplication();
|
||||
~lcApplication();
|
||||
|
||||
bool Initialize(int argc, char *argv[], const char* SysLibPath);
|
||||
bool Initialize(int argc, char *argv[], const char* LibraryInstallPath, const char* LibraryCachePath);
|
||||
void Shutdown();
|
||||
|
||||
// Pieces library.
|
||||
bool LoadPiecesLibrary(const char* LibPath, const char* SysLibPath);
|
||||
bool LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LibraryCachePath);
|
||||
lcPiecesLibrary* GetPiecesLibrary() const
|
||||
{
|
||||
return m_Library;
|
||||
|
||||
+118
-19
@@ -5,6 +5,12 @@
|
||||
#include "pieceinf.h"
|
||||
#include "lc_colors.h"
|
||||
#include "system.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define LC_LIBRARY_CACHE_VERSION 0x0100
|
||||
#define LC_LIBRARY_CACHE_ARCHIVE 0x0001
|
||||
#define LC_LIBRARY_CACHE_DIRECTORY 0x0002
|
||||
|
||||
lcPiecesLibrary::lcPiecesLibrary()
|
||||
{
|
||||
@@ -41,7 +47,7 @@ PieceInfo* lcPiecesLibrary::CreatePlaceholder(const char* PieceName)
|
||||
return Info;
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::Load(const char* SearchPath)
|
||||
bool lcPiecesLibrary::Load(const char* SearchPath, const char* CacheFilePath)
|
||||
{
|
||||
char LibraryPath[LC_MAXPATH];
|
||||
|
||||
@@ -54,7 +60,7 @@ bool lcPiecesLibrary::Load(const char* SearchPath)
|
||||
strcpy(mLibraryPath, LibraryPath);
|
||||
strcat(LibraryPath, "complete.zip");
|
||||
|
||||
if (OpenArchive(LibraryPath))
|
||||
if (OpenArchive(LibraryPath, CacheFilePath))
|
||||
{
|
||||
lcMemFile ColorFile;
|
||||
|
||||
@@ -85,7 +91,7 @@ bool lcPiecesLibrary::Load(const char* SearchPath)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::OpenArchive(const char* FileName)
|
||||
bool lcPiecesLibrary::OpenArchive(const char* FileName, const char* CacheFilePath)
|
||||
{
|
||||
mZipFile = new lcZipFile();
|
||||
|
||||
@@ -151,29 +157,122 @@ bool lcPiecesLibrary::OpenArchive(const char* FileName)
|
||||
}
|
||||
}
|
||||
|
||||
lcMemFile PieceFile;
|
||||
bool CacheValid = false;
|
||||
struct stat LibraryStat;
|
||||
|
||||
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||
strcpy(mCacheFileName, CacheFilePath);
|
||||
if (CacheFilePath[0])
|
||||
strcat(mCacheFileName, "library.cache");
|
||||
|
||||
if (stat(FileName, &LibraryStat) == 0)
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||
lcZipFile CacheFile;
|
||||
|
||||
mZipFile->ExtractFile(Info->mZipFileIndex, PieceFile, 256);
|
||||
PieceFile.Seek(0, SEEK_END);
|
||||
PieceFile.WriteU8(0);
|
||||
|
||||
char* Src = (char*)PieceFile.mBuffer + 2;
|
||||
char* Dst = Info->m_strDescription;
|
||||
|
||||
for (;;)
|
||||
if (CacheFile.OpenRead(mCacheFileName))
|
||||
{
|
||||
if (*Src != '\r' && *Src != '\n' && *Src && Dst - Info->m_strDescription < sizeof(Info->m_strDescription) - 1)
|
||||
lcMemFile VersionFile;
|
||||
|
||||
if (CacheFile.ExtractFile("version", VersionFile))
|
||||
{
|
||||
*Dst++ = *Src++;
|
||||
continue;
|
||||
lcuint32 CacheVersion;
|
||||
lcuint32 CacheFlags;
|
||||
lcuint64 LibrarySize;
|
||||
lcuint64 LibraryModified;
|
||||
|
||||
if (VersionFile.ReadU32(&CacheVersion, 1) && VersionFile.ReadU32(&CacheFlags, 1) &&
|
||||
VersionFile.ReadU64(&LibrarySize, 1) && VersionFile.ReadU64(&LibraryModified, 1))
|
||||
{
|
||||
if (CacheVersion == LC_LIBRARY_CACHE_VERSION && CacheFlags == LC_LIBRARY_CACHE_ARCHIVE &&
|
||||
LibrarySize == LibraryStat.st_size && LibraryModified == LibraryStat.st_mtime)
|
||||
CacheValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CacheValid)
|
||||
{
|
||||
lcMemFile IndexFile;
|
||||
|
||||
if (CacheFile.ExtractFile("index", IndexFile))
|
||||
{
|
||||
lcuint32 NumFiles;
|
||||
|
||||
if (IndexFile.ReadU32(&NumFiles, 1) && NumFiles == mPieces.GetSize())
|
||||
{
|
||||
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||
|
||||
LC_CASSERT(sizeof(Info->m_strDescription) == 128);
|
||||
|
||||
if (!IndexFile.ReadBuffer(Info->m_strDescription, sizeof(Info->m_strDescription)))
|
||||
{
|
||||
CacheValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
CacheValid = false;
|
||||
}
|
||||
else
|
||||
CacheValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CacheValid)
|
||||
{
|
||||
lcMemFile PieceFile;
|
||||
|
||||
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||
|
||||
mZipFile->ExtractFile(Info->mZipFileIndex, PieceFile, 256);
|
||||
PieceFile.Seek(0, SEEK_END);
|
||||
PieceFile.WriteU8(0);
|
||||
|
||||
char* Src = (char*)PieceFile.mBuffer + 2;
|
||||
char* Dst = Info->m_strDescription;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*Src != '\r' && *Src != '\n' && *Src && Dst - Info->m_strDescription < sizeof(Info->m_strDescription) - 1)
|
||||
{
|
||||
*Dst++ = *Src++;
|
||||
continue;
|
||||
}
|
||||
|
||||
*Dst = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lcZipFile CacheFile;
|
||||
|
||||
if (CacheFile.OpenWrite(mCacheFileName, false))
|
||||
{
|
||||
lcMemFile VersionFile;
|
||||
|
||||
VersionFile.WriteU32(LC_LIBRARY_CACHE_VERSION);
|
||||
VersionFile.WriteU32(LC_LIBRARY_CACHE_ARCHIVE);
|
||||
VersionFile.WriteU64(LibraryStat.st_size);
|
||||
VersionFile.WriteU64(LibraryStat.st_mtime);
|
||||
|
||||
CacheFile.AddFile("version", VersionFile);
|
||||
|
||||
lcMemFile IndexFile;
|
||||
|
||||
IndexFile.WriteU32(mPieces.GetSize());
|
||||
|
||||
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||
{
|
||||
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||
|
||||
IndexFile.WriteBuffer(Info->m_strDescription, sizeof(Info->m_strDescription));
|
||||
}
|
||||
|
||||
*Dst = 0;
|
||||
break;
|
||||
CacheFile.AddFile("index", IndexFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -84,7 +84,7 @@ public:
|
||||
lcPiecesLibrary();
|
||||
~lcPiecesLibrary();
|
||||
|
||||
bool Load(const char* SearchPath);
|
||||
bool Load(const char* SearchPath, const char* CacheFilePath);
|
||||
|
||||
PieceInfo* FindPiece(const char* PieceName, bool CreatePlaceholderIfMissing);
|
||||
PieceInfo* CreatePlaceholder(const char* PieceName);
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
char mLibraryPath[LC_MAXPATH];
|
||||
|
||||
protected:
|
||||
bool OpenArchive(const char* FileName);
|
||||
bool OpenArchive(const char* FileName, const char* CacheFileName);
|
||||
bool OpenDirectory(const char* Path);
|
||||
int FindPrimitiveIndex(const char* Name);
|
||||
bool LoadPrimitive(int PrimitiveIndex);
|
||||
@@ -119,6 +119,8 @@ protected:
|
||||
bool mCategoriesModified;
|
||||
char mCategoriesFile[LC_MAXPATH];
|
||||
|
||||
char mCacheFileName[LC_MAXPATH];
|
||||
|
||||
lcZipFile* mZipFile;
|
||||
};
|
||||
|
||||
|
||||
+11
-4
@@ -31,15 +31,22 @@ bool lcZipFile::OpenRead(const char* FilePath)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lcZipFile::OpenWrite(const char* FilePath)
|
||||
bool lcZipFile::OpenWrite(const char* FilePath, bool Append)
|
||||
{
|
||||
lcDiskFile* File = new lcDiskFile();
|
||||
mFile = File;
|
||||
bool Exists = true;
|
||||
|
||||
if (!File->Open(FilePath, "r+b") || !Open())
|
||||
if (Append)
|
||||
{
|
||||
if (!File->Open(FilePath, "r+b") || !Open())
|
||||
{
|
||||
delete File;
|
||||
mFile = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Exists = false;
|
||||
mNumEntries = 0;
|
||||
mCentralDirSize = 0;
|
||||
mCentralDirOffset = 0;
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ public:
|
||||
~lcZipFile();
|
||||
|
||||
bool OpenRead(const char* FilePath);
|
||||
bool OpenWrite(const char* FilePath);
|
||||
bool OpenWrite(const char* FilePath, bool Append);
|
||||
void Flush();
|
||||
|
||||
bool ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
|
||||
|
||||
+14
-4
@@ -5,6 +5,7 @@
|
||||
#include "CADDoc.h"
|
||||
#include "CADView.h"
|
||||
#include <wininet.h>
|
||||
#include <direct.h>
|
||||
#include <process.h>
|
||||
#include "project.h"
|
||||
#include "globals.h"
|
||||
@@ -180,16 +181,25 @@ BOOL CCADApp::InitInstance()
|
||||
|
||||
InitKeyboardShortcuts();
|
||||
|
||||
char app[LC_MAXPATH], *ptr;
|
||||
GetModuleFileName (NULL, app, LC_MAXPATH);
|
||||
ptr = strrchr(app,'\\');
|
||||
char ApplicationPath[LC_MAXPATH], *ptr;
|
||||
GetModuleFileName (NULL, ApplicationPath, LC_MAXPATH);
|
||||
ptr = strrchr(ApplicationPath,'\\');
|
||||
if (ptr)
|
||||
*(++ptr) = 0;
|
||||
|
||||
char CacheFilePath[LC_MAXPATH];
|
||||
if (SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, CacheFilePath) == S_OK)
|
||||
{
|
||||
PathAppend(CacheFilePath, "LeoCAD\\");
|
||||
_mkdir(CacheFilePath);
|
||||
}
|
||||
else
|
||||
CacheFilePath[0] = 0;
|
||||
|
||||
g_App = new lcApplication();
|
||||
main_window = new MainWnd();
|
||||
|
||||
if (!g_App->Initialize(__argc, __targv, app))
|
||||
if (!g_App->Initialize(__argc, __targv, ApplicationPath, CacheFilePath))
|
||||
return false;
|
||||
|
||||
// Register the application's document templates. Document templates
|
||||
|
||||
Reference in New Issue
Block a user