You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

231 lines
6.4 KiB

/*****************************************************************************
* VLCLibraryNameCache.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2025 VLC authors and VideoLAN
*
* Authors: Claudio Cambra <developer@claudiocambra.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCLibraryNameCache.h"
#import "VLCLibraryDataTypes.h"
#import "VLCLibraryModel.h"
#import "extensions/NSString+Helpers.h"
#include <vlc_media_library.h>
const NSUInteger kVLCMaximumLibraryNameCacheSize = 1024 * 1024 * 1; // 1MB
@implementation VLCLibraryNameCache {
NSCache<NSNumber *, NSString *> *_albumTitleCache;
NSCache<NSNumber *, NSString *> *_albumArtistCache;
NSCache<NSNumber *, NSString *> *_artistNameCache;
NSCache<NSNumber *, NSString *> *_genreNameCache;
}
+ (instancetype)sharedInstance
{
static VLCLibraryNameCache *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[VLCLibraryNameCache alloc] init];
});
return instance;
}
- (instancetype)init
{
self = [super init];
if (self) {
_albumTitleCache = [NSCache new];
_albumArtistCache = [NSCache new];
_artistNameCache = [NSCache new];
_genreNameCache = [NSCache new];
_albumTitleCache.totalCostLimit = kVLCMaximumLibraryNameCacheSize;
_albumArtistCache.totalCostLimit = kVLCMaximumLibraryNameCacheSize;
_artistNameCache.totalCostLimit = kVLCMaximumLibraryNameCacheSize;
_genreNameCache.totalCostLimit = kVLCMaximumLibraryNameCacheSize;
NSNotificationCenter * const center = NSNotificationCenter.defaultCenter;
[center addObserver:self
selector:@selector(handleAlbumUpdate:)
name:VLCLibraryModelAlbumUpdated
object:nil];
[center addObserver:self
selector:@selector(handleGenreUpdate:)
name:VLCLibraryModelGenreUpdated
object:nil];
[center addObserver:self
selector:@selector(handleArtistUpdate:)
name:VLCLibraryModelArtistUpdated
object:nil];
}
return self;
}
- (void)dealloc
{
[NSNotificationCenter.defaultCenter removeObserver:self];
}
- (void)handleAlbumUpdate:(NSNotification *)notification
{
[self invalidateAlbumWithID:((VLCMediaLibraryAlbum *)notification.object).libraryID];
}
- (void)handleGenreUpdate:(NSNotification *)notification
{
[self invalidateGenreWithID:((VLCMediaLibraryGenre *)notification.object).libraryID];
}
- (void)handleArtistUpdate:(NSNotification *)notification
{
[self invalidateArtistWithID:((VLCMediaLibraryArtist *)notification.object).libraryID];
}
- (NSString *)albumTitleForID:(int64_t)albumID
{
if (albumID <= 0) {
return nil;
}
NSNumber * const key = @(albumID);
NSString * const cached = [_albumTitleCache objectForKey:key];
if (cached) {
return cached;
}
vlc_medialibrary_t * const p_ml = getMediaLibrary();
if (!p_ml) {
return nil;
}
vlc_ml_album_t * const p_album = vlc_ml_get_album(p_ml, albumID);
if (!p_album) {
return nil;
}
NSString * const title = toNSStr(p_album->psz_title);
NSString * const artist = toNSStr(p_album->psz_artist);
[_albumTitleCache setObject:title forKey:key];
[_albumArtistCache setObject:artist forKey:key];
vlc_ml_album_release(p_album);
return title;
}
- (NSString *)albumArtistForID:(int64_t)albumID
{
if (albumID <= 0) {
return nil;
}
NSNumber * const key = @(albumID);
NSString * const cached = [_albumArtistCache objectForKey:key];
if (cached) {
return cached;
}
[self albumTitleForID:albumID];
return [_albumArtistCache objectForKey:key];
}
- (NSString *)genreNameForID:(int64_t)genreID
{
if (genreID <= 0) {
return nil;
}
NSNumber * const key = @(genreID);
NSString * const cached = [_genreNameCache objectForKey:key];
if (cached) {
return cached;
}
vlc_medialibrary_t * const p_ml = getMediaLibrary();
if (!p_ml) {
return nil;
}
vlc_ml_genre_t * const p_genre = vlc_ml_get_genre(p_ml, genreID);
if (!p_genre) {
return nil;
}
NSString * const name = toNSStr(p_genre->psz_name);
[_genreNameCache setObject:name forKey:key];
vlc_ml_genre_release(p_genre);
return name;
}
- (NSString *)artistNameForID:(int64_t)artistID
{
if (artistID <= 0) {
return nil;
}
NSNumber * const key = @(artistID);
NSString * const cached = [_artistNameCache objectForKey:key];
if (cached) {
return cached;
}
vlc_medialibrary_t * const p_ml = getMediaLibrary();
if (!p_ml) {
return nil;
}
vlc_ml_artist_t * const p_artist = vlc_ml_get_artist(p_ml, artistID);
if (!p_artist) {
return nil;
}
NSString * const name = toNSStr(p_artist->psz_name);
[_artistNameCache setObject:name forKey:key];
vlc_ml_artist_release(p_artist);
return name;
}
- (void)invalidateAlbumWithID:(int64_t)albumID
{
[_albumTitleCache removeObjectForKey:@(albumID)];
[_albumArtistCache removeObjectForKey:@(albumID)];
}
- (void)invalidateGenreWithID:(int64_t)genreID
{
[_genreNameCache removeObjectForKey:@(genreID)];
}
- (void)invalidateArtistWithID:(int64_t)artistID
{
[_artistNameCache removeObjectForKey:@(artistID)];
}
- (void)invalidateAll
{
[_albumTitleCache removeAllObjects];
[_albumArtistCache removeAllObjects];
[_artistNameCache removeAllObjects];
[_genreNameCache removeAllObjects];
}
@end