summaryrefslogtreecommitdiff
path: root/lazycachelist.py
diff options
context:
space:
mode:
Diffstat (limited to 'lazycachelist.py')
-rw-r--r--lazycachelist.py51
1 files changed, 39 insertions, 12 deletions
diff --git a/lazycachelist.py b/lazycachelist.py
index 0c37ba3..b08b85d 100644
--- a/lazycachelist.py
+++ b/lazycachelist.py
@@ -1,4 +1,4 @@
-from dataclasses import dataclass
+from dataclasses import dataclass, asdict
from texture import ImageTextureImmichAsset
@@ -14,8 +14,27 @@ class Album:
return end - start
+@dataclass
+class CallbackStateData:
+ asset_index: int
+ movement: int
+ assets: list[str]
+
+ @classmethod
+ def from_lctl(cls, l):
+ si = (l.asset_index - 5) % l.asset_count
+ ei = (l.asset_index + 6) % l.asset_count
+ sa = l.assets[si:ei] if si < ei else l.assets[si:] + l.assets[:ei]
+ assets = [ a["id"] for a in sa ]
+ return cls(
+ asset_index=l.asset_index,
+ movement=l.last_movement,
+ assets=assets,
+ )
+
+
class LazyCachingTextureList():
- def __init__(self, immich_connector, album_ids, max_cache_items=100):
+ def __init__(self, immich_connector, album_ids, max_cache_items=100, change_callback=None):
self.immich_connector = immich_connector
assert max_cache_items >= 20, "Minimum cache items is 20" # Double small radius
@@ -29,11 +48,16 @@ class LazyCachingTextureList():
self.cache_index = 0
self.asset_index = 0
self.asset_count = 0
+ self.last_movement = 0
self.cached_items = 0
self.album_keys = album_ids
+ # TODO simplify album handling, dont need classes, etc.
self.albums = self._get_albums()
+ self.assets = self._get_album_assets()
+
+ self.change_callback = change_callback
def index_in_cache_range(self, index):
index_range_low = (self.asset_index - self.cache_items_behind) % self.asset_count
@@ -54,18 +78,13 @@ class LazyCachingTextureList():
albums.append(Album(id, i, i + asset_count))
i += asset_count + 1
self.asset_count += asset_count
- #self.asset_count = sum(( album.assets_count for album in self.albums ))
return albums
- def _get_album_asset_by_index(self, asset_index):
- if asset_index < 0:
- asset_index = asset_count - asset_index
+ def _get_album_assets(self):
+ assets = []
for album in self.albums:
- if album.range_start <= asset_index <= album.range_end:
- if album.assets_list is None:
- album.assets_list = self.immich_connector.load_album_assets(album.id)
- return album.assets_list[asset_index - album.range_start]
- raise IndexError("Index out of bounds")
+ assets += self.immich_connector.load_album_assets(album.id)
+ return assets
def _fill_cache(self, current_radius, final_radius, step):
if current_radius >= final_radius:
@@ -76,7 +95,7 @@ class LazyCachingTextureList():
asset_index = (self.asset_index + i) % self.asset_count
if self.cache[cache_index]:
self.cache[cache_index].free() # Since this is a ring buffer, textures outside of range can just get free'd here
- asset = self._get_album_asset_by_index(asset_index)
+ asset = self.assets[asset_index]
tex = ImageTextureImmichAsset(asset, asset_index)
self.immich_connector.load_texture_async(self, tex)
self.cache[cache_index] = tex
@@ -87,6 +106,8 @@ class LazyCachingTextureList():
def _update_cache_get_item(self, asset_index):
prev_asset_index = self.asset_index
self.asset_index = asset_index % self.asset_count
+ #if prev_asset_index == asset_index:
+ # return self.cache[self.cache_index]
# Movement is the distance between the previous and current index in the assets list
# Since the list wraps around, fastest method is just to get the abs min of the 3 cases
movement = min(
@@ -94,6 +115,7 @@ class LazyCachingTextureList():
asset_index - self.asset_count, # Wrap backwards (0 -> -1)
self.asset_count - prev_asset_index, # Wrap forwards (-1 -> 0)
key=abs)
+ self.last_movement = movement
self.cache_index = (self.cache_index + movement) % self.cache_length
ahead = max(0, self.cache_items_ahead - movement)
@@ -114,6 +136,11 @@ class LazyCachingTextureList():
self.cache_items_ahead = ahead
self.cache_items_behind = behind
+
+ # Perform callback
+ if prev_asset_index != asset_index and self.change_callback:
+ self.change_callback(asdict(CallbackStateData.from_lctl(self)))
+
return self.cache[self.cache_index]
def __len__(self):