mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-05 07:07:38 +03:00
Move section data into new cache directory
This commit is contained in:
parent
ea3584a918
commit
85188afc8e
27
README.md
27
README.md
@ -98,9 +98,9 @@ CrossPoint Reader is pretty aggressive about caching data down to the SD card to
|
|||||||
has ~380KB of usable RAM, so we have to be careful. A lot of the decisions made in the design of the firmware were based
|
has ~380KB of usable RAM, so we have to be careful. A lot of the decisions made in the design of the firmware were based
|
||||||
on this constraint.
|
on this constraint.
|
||||||
|
|
||||||
### EPUB caching
|
### Data caching
|
||||||
|
|
||||||
The first time chapters of an EPUB are loaded, they are cached to the SD card. Subsequent loads are served from the
|
The first time chapters of a book are loaded, they are cached to the SD card. Subsequent loads are served from the
|
||||||
cache. This cache directory exists at `.crosspoint` on the SD card. The structure is as follows:
|
cache. This cache directory exists at `.crosspoint` on the SD card. The structure is as follows:
|
||||||
|
|
||||||
|
|
||||||
@ -108,25 +108,22 @@ cache. This cache directory exists at `.crosspoint` on the SD card. The structur
|
|||||||
.crosspoint/
|
.crosspoint/
|
||||||
├── epub_12471232/ # Each EPUB is cached to a subdirectory named `epub_<hash>`
|
├── epub_12471232/ # Each EPUB is cached to a subdirectory named `epub_<hash>`
|
||||||
│ ├── progress.bin # Stores reading progress (chapter, page, etc.)
|
│ ├── progress.bin # Stores reading progress (chapter, page, etc.)
|
||||||
│ ├── 0/ # Each chapter is stored in a subdirectory named by its index (based on the spine order)
|
│ ├── cover.bmp # Book cover image (once generated)
|
||||||
│ │ ├── section.bin # Section metadata (page count)
|
│ ├── book.bin # Book metadata (title, author, spine, table of contents, etc.)
|
||||||
│ │ ├── page_0.bin # Each page is stored in a separate file, it
|
│ └── sections/ # All chapter data is stored in the sections subdirectory
|
||||||
│ │ ├── page_1.bin # contains the position (x, y) and text for each word
|
│ ├── 0.bin # Chapter data (screen count, all text layout info, etc.)
|
||||||
│ │ └── ...
|
│ ├── 1.bin # files are named by their index in the spine
|
||||||
│ ├── 1/
|
|
||||||
│ │ ├── section.bin
|
|
||||||
│ │ ├── page_0.bin
|
|
||||||
│ │ ├── page_1.bin
|
|
||||||
│ │ └── ...
|
|
||||||
│ └── ...
|
│ └── ...
|
||||||
│
|
│
|
||||||
└── epub_189013891/
|
└── epub_189013891/
|
||||||
```
|
```
|
||||||
|
|
||||||
Deleting the `.crosspoint` directory will clear the cache.
|
Deleting the `.crosspoint` directory will clear the entire cache.
|
||||||
|
|
||||||
Due the way it's currently implemented, the cache is not automatically cleared when the EPUB is deleted and moving an
|
Due the way it's currently implemented, the cache is not automatically cleared when a book is deleted and moving a book
|
||||||
EPUB file will reset the reading progress.
|
file will use a new cache directory, resetting the reading progress.
|
||||||
|
|
||||||
|
For more details on the internal file structures, see the [file formats document](./docs/file-formats.md).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,6 @@ namespace {
|
|||||||
constexpr uint8_t SECTION_FILE_VERSION = 7;
|
constexpr uint8_t SECTION_FILE_VERSION = 7;
|
||||||
constexpr size_t HEADER_SIZE = sizeof(uint8_t) + sizeof(int) + sizeof(float) + sizeof(bool) + sizeof(int) +
|
constexpr size_t HEADER_SIZE = sizeof(uint8_t) + sizeof(int) + sizeof(float) + sizeof(bool) + sizeof(int) +
|
||||||
sizeof(int) + sizeof(int) + sizeof(size_t);
|
sizeof(int) + sizeof(int) + sizeof(size_t);
|
||||||
constexpr char sectionFileName[] = "/section.bin";
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
size_t Section::onPageComplete(std::unique_ptr<Page> page) {
|
size_t Section::onPageComplete(std::unique_ptr<Page> page) {
|
||||||
@ -49,7 +48,7 @@ void Section::writeSectionFileHeader(const int fontId, const float lineCompressi
|
|||||||
|
|
||||||
bool Section::loadSectionFile(const int fontId, const float lineCompression, const bool extraParagraphSpacing,
|
bool Section::loadSectionFile(const int fontId, const float lineCompression, const bool extraParagraphSpacing,
|
||||||
const int viewportWidth, const int viewportHeight) {
|
const int viewportWidth, const int viewportHeight) {
|
||||||
if (!FsHelpers::openFileForRead("SCT", cachePath + sectionFileName, file)) {
|
if (!FsHelpers::openFileForRead("SCT", filePath, file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,19 +88,14 @@ bool Section::loadSectionFile(const int fontId, const float lineCompression, con
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Section::setupCacheDir() const {
|
|
||||||
epub->setupCacheDir();
|
|
||||||
SD.mkdir(cachePath.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Your updated class method (assuming you are using the 'SD' object, which is a wrapper for a specific filesystem)
|
// Your updated class method (assuming you are using the 'SD' object, which is a wrapper for a specific filesystem)
|
||||||
bool Section::clearCache() const {
|
bool Section::clearCache() const {
|
||||||
if (!SD.exists(cachePath.c_str())) {
|
if (!SD.exists(filePath.c_str())) {
|
||||||
Serial.printf("[%lu] [SCT] Cache does not exist, no action needed\n", millis());
|
Serial.printf("[%lu] [SCT] Cache does not exist, no action needed\n", millis());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FsHelpers::removeDir(cachePath.c_str())) {
|
if (!SD.remove(filePath.c_str())) {
|
||||||
Serial.printf("[%lu] [SCT] Failed to clear cache\n", millis());
|
Serial.printf("[%lu] [SCT] Failed to clear cache\n", millis());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -159,7 +153,7 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c
|
|||||||
progressSetupFn();
|
progressSetupFn();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FsHelpers::openFileForWrite("SCT", cachePath + sectionFileName, file)) {
|
if (!FsHelpers::openFileForWrite("SCT", filePath, file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
writeSectionFileHeader(fontId, lineCompression, extraParagraphSpacing, viewportWidth, viewportHeight);
|
writeSectionFileHeader(fontId, lineCompression, extraParagraphSpacing, viewportWidth, viewportHeight);
|
||||||
@ -175,7 +169,7 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
Serial.printf("[%lu] [SCT] Failed to parse XML and build pages\n", millis());
|
Serial.printf("[%lu] [SCT] Failed to parse XML and build pages\n", millis());
|
||||||
file.close();
|
file.close();
|
||||||
SD.remove((cachePath + sectionFileName).c_str());
|
SD.remove(filePath.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +187,7 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Page> Section::loadPageFromSectionFile() {
|
std::unique_ptr<Page> Section::loadPageFromSectionFile() {
|
||||||
if (!FsHelpers::openFileForRead("SCT", cachePath + sectionFileName, file)) {
|
if (!FsHelpers::openFileForRead("SCT", filePath, file)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ class Section {
|
|||||||
std::shared_ptr<Epub> epub;
|
std::shared_ptr<Epub> epub;
|
||||||
const int spineIndex;
|
const int spineIndex;
|
||||||
GfxRenderer& renderer;
|
GfxRenderer& renderer;
|
||||||
std::string cachePath;
|
std::string filePath;
|
||||||
File file;
|
File file;
|
||||||
|
|
||||||
void writeSectionFileHeader(int fontId, float lineCompression, bool extraParagraphSpacing, int viewportWidth,
|
void writeSectionFileHeader(int fontId, float lineCompression, bool extraParagraphSpacing, int viewportWidth,
|
||||||
@ -26,11 +26,10 @@ class Section {
|
|||||||
: epub(epub),
|
: epub(epub),
|
||||||
spineIndex(spineIndex),
|
spineIndex(spineIndex),
|
||||||
renderer(renderer),
|
renderer(renderer),
|
||||||
cachePath(epub->getCachePath() + "/" + std::to_string(spineIndex)) {}
|
filePath(epub->getCachePath() + "/sections/" + std::to_string(spineIndex) + ".bin") {}
|
||||||
~Section() = default;
|
~Section() = default;
|
||||||
bool loadSectionFile(int fontId, float lineCompression, bool extraParagraphSpacing, int viewportWidth,
|
bool loadSectionFile(int fontId, float lineCompression, bool extraParagraphSpacing, int viewportWidth,
|
||||||
int viewportHeight);
|
int viewportHeight);
|
||||||
void setupCacheDir() const;
|
|
||||||
bool clearCache() const;
|
bool clearCache() const;
|
||||||
bool createSectionFile(int fontId, float lineCompression, bool extraParagraphSpacing, int viewportWidth,
|
bool createSectionFile(int fontId, float lineCompression, bool extraParagraphSpacing, int viewportWidth,
|
||||||
int viewportHeight, const std::function<void()>& progressSetupFn = nullptr,
|
int viewportHeight, const std::function<void()>& progressSetupFn = nullptr,
|
||||||
|
|||||||
@ -282,8 +282,6 @@ void EpubReaderActivity::renderScreen() {
|
|||||||
pagesUntilFullRefresh = 0;
|
pagesUntilFullRefresh = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
section->setupCacheDir();
|
|
||||||
|
|
||||||
// Setup callback - only called for chapters >= 50KB, redraws with progress bar
|
// Setup callback - only called for chapters >= 50KB, redraws with progress bar
|
||||||
auto progressSetup = [this, boxXWithBar, boxWidthWithBar, boxHeightWithBar, barX, barY] {
|
auto progressSetup = [this, boxXWithBar, boxWidthWithBar, boxHeightWithBar, barX, barY] {
|
||||||
renderer.fillRect(boxXWithBar, boxY, boxWidthWithBar, boxHeightWithBar, false);
|
renderer.fillRect(boxXWithBar, boxY, boxWidthWithBar, boxHeightWithBar, false);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user