Selaa lähdekoodia

Improve cover handling and caching

- Limit placeholder texture cache to 8 entries to prevent unbounded growth
- Skip cover loading if texture already loaded (avoid redundant disk I/O)
- Check file existence before attempting texture load
- Graceful fallback to placeholder for missing/corrupted covers

These changes improve memory usage and reduce unnecessary file operations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bernardo Magri 1 kuukausi sitten
vanhempi
sitoutus
e4ca346237
3 muutettua tiedostoa jossa 28 lisäystä ja 6 poistoa
  1. 9 5
      PLAN.md
  2. 11 1
      src/Book.cpp
  3. 8 0
      src/BookTile.cpp

+ 9 - 5
PLAN.md

@@ -113,12 +113,16 @@ Implemented:
 - [x] Search entry text preserved across view transitions
 
 ### 2.4 Improve Cover Handling
-**Files**: `src/BookImport.cpp`, `src/BookTile.cpp`
-**Status**: Not Started
+**Files**: `src/Book.cpp`, `src/BookTile.cpp`
+**Status**: COMPLETED
+
+Implemented:
+- [x] Limit placeholder texture cache to 8 entries (prevents unbounded growth)
+- [x] Skip cover loading if already loaded (avoid redundant disk I/O)
+- [x] Check file existence before attempting texture load
+- [x] Graceful fallback to placeholder for missing/corrupted covers
 
-- [ ] Validate cover image format before saving
-- [ ] Add cache clearing mechanism for placeholder textures
-- [ ] Handle missing/corrupted cover files gracefully
+Note: Format validation deferred - GTK handles format detection internally
 
 ---
 

+ 11 - 1
src/Book.cpp

@@ -42,8 +42,18 @@ void Book::set_cover(Glib::RefPtr<Gdk::Texture>&& tex) {
 }
 
 void Book::load_cover_from_disk() {
-	// Try to load the cover from disk first
+	// Skip if already loaded
+	if (m_cover)
+		return;
+
+	// Try to load the cover from disk
 	if (!m_coverPath.empty()) {
+		// Check if file exists before attempting load
+		if (!Glib::file_test(m_coverPath, Glib::FileTest::EXISTS)) {
+			std::cerr << "Cover file missing: " << m_coverPath << std::endl;
+			return;
+		}
+
 		try {
 			auto tex = Gdk::Texture::create_from_filename(m_coverPath);
 			if (tex) {

+ 8 - 0
src/BookTile.cpp

@@ -12,6 +12,9 @@
 
 namespace {
 
+// Maximum number of cached placeholder textures to prevent unbounded growth
+constexpr size_t kMaxPlaceholderCacheSize = 8;
+
 Glib::RefPtr<Gdk::Texture> make_placeholder_texture(int width, int height) {
   using Key = std::pair<int, int>;
   static std::map<Key, Glib::RefPtr<Gdk::Texture>> cache;
@@ -20,6 +23,11 @@ Glib::RefPtr<Gdk::Texture> make_placeholder_texture(int width, int height) {
   if (auto it = cache.find(key); it != cache.end())
     return it->second;
 
+  // Limit cache size - remove oldest entry if full
+  if (cache.size() >= kMaxPlaceholderCacheSize) {
+    cache.erase(cache.begin());
+  }
+
   const int stride = width * 4;
   std::vector<guint8> pixels(static_cast<std::size_t>(stride) * height);