[vlc-commits] [Git][videolan/vlc][master] 24 commits: macosx: Constify library model notification change notifications

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Wed Apr 26 16:56:19 UTC 2023



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
ab86e3bf by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Constify library model notification change notifications

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
a03b353b by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Only get library model pointer once in libraryCallback

VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;

- - - - -
90fdba3d by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Granularly update album cache in VLCLibraryModel when notified by media library

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
f482faa9 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Granularly handle media library album deletion event in VLCLibraryModel

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
26b6b960 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Handle album updates from VLCLibraryModel in VLCLibraryAlbumTableCellView

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
e08a4941 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Handle album updates in VLCLibraryAlbumSupplementaryDetailView

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
3d5cb790 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Handle album updates if applicable for VLCLibraryCollectionViewAudioGroupSupplementaryDetailView

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
d6de88ed by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Granularly handle artist update modifications in VLCLibraryModel

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
9c8ef9ef by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Granularly handle artist deletions in VLCLibraryModel

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
0c6c5070 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Make update handler in VLCLibraryCollectionViewAudioGroupSupplementaryDetailView type agnostic by using protocol

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
5343ff34 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Handle artist update notifications in VLCLibraryCollectionViewAudioGroupSupplementaryDetailView

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
aafac603 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Make update handlers in VLCLibraryAudioDataSource type agnostic, use protocol

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
b4e89b60 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Avoid updated VLCLibraryAudioDataSource when receiving update notifications for currently unrepresented types

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
7c15844a by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Handle granular updates for albums in VLCLibraryAudioDataSource

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
5edfb525 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Handle granular updates for artists in VLCLibraryAudioDataSource

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
31bf4a58 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Granularly update genre cache when receiving update genre notification update

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
3644a53c by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Granularly handle genre deletions in VLCLibraryModel

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
5f168b94 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Handle genre updates and deletions in VLCLibraryAudioDataSource

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
5f7bcaea by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Respond to genre updates in VLCLibraryCollectionViewAudioGroupSupplementaryDetailView

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
76b70f95 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Use polymorphic search function with VLCMediaLibraryAudioGroup protocol, removing duplicated search funcs

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
5a9156e7 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Deduplicate implementations of audio group update handlers in VLCLibraryModel, use reusable updater method

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
e0352dc1 by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Deduplicate implementations of audio group delete handlers in VLCLibraryModel, use reusable updater method

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
5aed85fb by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Be less overbearing with deletion nslogs in VLCLibraryModel

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
a3a77f3a by Claudio Cambra at 2023-04-26T16:25:10+00:00
macosx: Fix cache modification queues in VLCLibraryModel

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -


6 changed files:

- modules/gui/macosx/library/VLCLibraryModel.h
- modules/gui/macosx/library/VLCLibraryModel.m
- modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.m
- modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.m
- modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m
- modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m


Changes:

=====================================
modules/gui/macosx/library/VLCLibraryModel.h
=====================================
@@ -32,23 +32,29 @@ NS_ASSUME_NONNULL_BEGIN
 @class VLCMediaLibraryGenre;
 @class VLCMediaLibraryEntryPoint;
 
-extern NSString *VLCLibraryModelArtistListUpdated;
-extern NSString *VLCLibraryModelAlbumListUpdated;
-extern NSString *VLCLibraryModelGenreListUpdated;
-extern NSString *VLCLibraryModelListOfMonitoredFoldersUpdated;
-extern NSString *VLCLibraryModelMediaItemThumbnailGenerated;
-
-extern NSString *VLCLibraryModelAudioMediaListReset;
-extern NSString *VLCLibraryModelVideoMediaListReset;
-extern NSString *VLCLibraryModelRecentsMediaListReset;
-
-extern NSString *VLCLibraryModelAudioMediaItemDeleted;
-extern NSString *VLCLibraryModelVideoMediaItemDeleted;
-extern NSString *VLCLibraryModelRecentsMediaItemDeleted;
-
-extern NSString *VLCLibraryModelAudioMediaItemUpdated;
-extern NSString *VLCLibraryModelVideoMediaItemUpdated;
-extern NSString *VLCLibraryModelRecentsMediaItemUpdated;
+extern NSString * const VLCLibraryModelArtistListUpdated;
+extern NSString * const VLCLibraryModelAlbumListUpdated;
+extern NSString * const VLCLibraryModelGenreListUpdated;
+extern NSString * const VLCLibraryModelListOfMonitoredFoldersUpdated;
+extern NSString * const VLCLibraryModelMediaItemThumbnailGenerated;
+
+extern NSString * const VLCLibraryModelAudioMediaListReset;
+extern NSString * const VLCLibraryModelVideoMediaListReset;
+extern NSString * const VLCLibraryModelRecentsMediaListReset;
+
+extern NSString * const VLCLibraryModelAudioMediaItemDeleted;
+extern NSString * const VLCLibraryModelVideoMediaItemDeleted;
+extern NSString * const VLCLibraryModelRecentsMediaItemDeleted;
+extern NSString * const VLCLibraryModelAlbumDeleted;
+extern NSString * const VLCLibraryModelArtistDeleted;
+extern NSString * const VLCLibraryModelGenreDeleted;
+
+extern NSString * const VLCLibraryModelAudioMediaItemUpdated;
+extern NSString * const VLCLibraryModelVideoMediaItemUpdated;
+extern NSString * const VLCLibraryModelRecentsMediaItemUpdated;
+extern NSString * const VLCLibraryModelAlbumUpdated;
+extern NSString * const VLCLibraryModelArtistUpdated;
+extern NSString * const VLCLibraryModelGenreUpdated;
 
 @interface VLCLibraryModel : NSObject
 


=====================================
modules/gui/macosx/library/VLCLibraryModel.m
=====================================
@@ -26,36 +26,35 @@
 #import "library/VLCLibraryDataTypes.h"
 #import "extensions/NSString+Helpers.h"
 
-NSString *VLCLibraryModelArtistListUpdated = @"VLCLibraryModelArtistListUpdated";
-NSString *VLCLibraryModelAlbumListUpdated = @"VLCLibraryModelAlbumListUpdated";
-NSString *VLCLibraryModelGenreListUpdated = @"VLCLibraryModelGenreListUpdated";
-NSString *VLCLibraryModelListOfMonitoredFoldersUpdated = @"VLCLibraryModelListOfMonitoredFoldersUpdated";
-NSString *VLCLibraryModelMediaItemThumbnailGenerated = @"VLCLibraryModelMediaItemThumbnailGenerated";
-
-NSString *VLCLibraryModelAudioMediaListReset = @"VLCLibraryModelAudioMediaListReset";
-NSString *VLCLibraryModelVideoMediaListReset = @"VLCLibraryModelVideoMediaListReset";
-NSString *VLCLibraryModelRecentsMediaListReset = @"VLCLibraryModelRecentsMediaListReset";
-
-NSString *VLCLibraryModelAudioMediaItemDeleted = @"VLCLibraryModelAudioMediaItemDeleted";
-NSString *VLCLibraryModelVideoMediaItemDeleted = @"VLCLibraryModelVideoMediaItemDeleted";
-NSString *VLCLibraryModelRecentsMediaItemDeleted = @"VLCLibraryModelRecentsMediaItemDeleted";
-
-NSString *VLCLibraryModelAudioMediaItemUpdated = @"VLCLibraryModelAudioMediaItemUpdated";
-NSString *VLCLibraryModelVideoMediaItemUpdated = @"VLCLibraryModelVideoMediaItemUpdated";
-NSString *VLCLibraryModelRecentsMediaItemUpdated = @"VLCLibraryModelRecentsMediaItemUpdated";
+NSString * const VLCLibraryModelArtistListUpdated = @"VLCLibraryModelArtistListUpdated";
+NSString * const VLCLibraryModelAlbumListUpdated = @"VLCLibraryModelAlbumListUpdated";
+NSString * const VLCLibraryModelGenreListUpdated = @"VLCLibraryModelGenreListUpdated";
+NSString * const VLCLibraryModelListOfMonitoredFoldersUpdated = @"VLCLibraryModelListOfMonitoredFoldersUpdated";
+NSString * const VLCLibraryModelMediaItemThumbnailGenerated = @"VLCLibraryModelMediaItemThumbnailGenerated";
+
+NSString * const VLCLibraryModelAudioMediaListReset = @"VLCLibraryModelAudioMediaListReset";
+NSString * const VLCLibraryModelVideoMediaListReset = @"VLCLibraryModelVideoMediaListReset";
+NSString * const VLCLibraryModelRecentsMediaListReset = @"VLCLibraryModelRecentsMediaListReset";
+
+NSString * const VLCLibraryModelAudioMediaItemDeleted = @"VLCLibraryModelAudioMediaItemDeleted";
+NSString * const VLCLibraryModelVideoMediaItemDeleted = @"VLCLibraryModelVideoMediaItemDeleted";
+NSString * const VLCLibraryModelRecentsMediaItemDeleted = @"VLCLibraryModelRecentsMediaItemDeleted";
+NSString * const VLCLibraryModelAlbumDeleted = @"VLCLibraryModelAlbumDeleted";
+NSString * const VLCLibraryModelArtistDeleted = @"VLCLibraryModelArtistDeleted";
+NSString * const VLCLibraryModelGenreDeleted = @"VLCLibraryModelGenreDeleted";
+
+NSString * const VLCLibraryModelAudioMediaItemUpdated = @"VLCLibraryModelAudioMediaItemUpdated";
+NSString * const VLCLibraryModelVideoMediaItemUpdated = @"VLCLibraryModelVideoMediaItemUpdated";
+NSString * const VLCLibraryModelRecentsMediaItemUpdated = @"VLCLibraryModelRecentsMediaItemUpdated";
+NSString * const VLCLibraryModelAlbumUpdated = @"VLCLibraryModelAlbumUpdated";
+NSString * const VLCLibraryModelArtistUpdated = @"VLCLibraryModelArtistUpdated";
+NSString * const VLCLibraryModelGenreUpdated = @"VLCLibraryModelGenreUpdated";
 
 @interface VLCLibraryModel ()
 {
     vlc_medialibrary_t *_p_mediaLibrary;
     vlc_ml_event_callback_t *_p_eventCallback;
 
-    NSArray *_cachedAudioMedia;
-    NSArray *_cachedArtists;
-    NSArray *_cachedAlbums;
-    NSArray *_cachedGenres;
-    NSArray *_cachedVideoMedia;
-    NSArray *_cachedRecentMedia;
-    NSArray *_cachedListOfMonitoredFolders;
     NSNotificationCenter *_defaultNotificationCenter;
 
     enum vlc_ml_sorting_criteria_t _sortCriteria;
@@ -66,6 +65,9 @@ NSString *VLCLibraryModelRecentsMediaItemUpdated = @"VLCLibraryModelRecentsMedia
     size_t _initialAudioCount;
 
     dispatch_queue_t _mediaItemCacheModificationQueue;
+    dispatch_queue_t _albumCacheModificationQueue;
+    dispatch_queue_t _artistCacheModificationQueue;
+    dispatch_queue_t _genreCacheModificationQueue;
 }
 
 @property (readwrite, atomic) NSArray *cachedAudioMedia;
@@ -83,32 +85,34 @@ NSString *VLCLibraryModelRecentsMediaItemUpdated = @"VLCLibraryModelRecentsMedia
 - (void)resetCachedListOfMonitoredFolders;
 - (void)mediaItemThumbnailGenerated:(VLCMediaLibraryMediaItem *)mediaItem;
 - (void)handleMediaItemDeletionEvent:(const vlc_ml_event_t * const)p_event;
+- (void)handleAlbumDeletionEvent:(const vlc_ml_event_t * const)p_event;
+- (void)handleArtistDeletionEvent:(const vlc_ml_event_t * const)p_event;
+- (void)handleGenreDeletionEvent:(const vlc_ml_event_t * const)p_event;
 - (void)handleMediaItemUpdateEvent:(const vlc_ml_event_t * const)p_event;
+- (void)handleAlbumUpdateEvent:(const vlc_ml_event_t * const)p_event;
+- (void)handleArtistUpdateEvent:(const vlc_ml_event_t * const)p_event;
+- (void)handleGenreUpdateEvent:(const vlc_ml_event_t * const)p_event;
 
 @end
 
 static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
 {
+    VLCLibraryModel * const libraryModel = (__bridge VLCLibraryModel *)p_data;
+    if (libraryModel == nil) {
+        return;
+    }
+
     switch(p_event->i_type)
     {
         case VLC_ML_EVENT_MEDIA_ADDED:
-        {
-            VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;
             [libraryModel resetCachedMediaItemLists];
             break;
-        }
         case VLC_ML_EVENT_MEDIA_UPDATED:
-        {
-            VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;
             [libraryModel handleMediaItemUpdateEvent:p_event];
             break;
-        }
         case VLC_ML_EVENT_MEDIA_DELETED:
-        {
-            VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;
             [libraryModel handleMediaItemDeletionEvent:p_event];
             break;
-        }
         case VLC_ML_EVENT_MEDIA_THUMBNAIL_GENERATED:
             if (p_event->media_thumbnail_generated.b_success) {
                 VLCMediaLibraryMediaItem *mediaItem = [[VLCMediaLibraryMediaItem alloc] initWithMediaItem:(struct vlc_ml_media_t *)p_event->media_thumbnail_generated.p_media];
@@ -116,43 +120,42 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
                     return;
                 }
                 dispatch_async(dispatch_get_main_queue(), ^{
-                    VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;
                     [libraryModel mediaItemThumbnailGenerated:mediaItem];
                 });
             }
             break;
         case VLC_ML_EVENT_ARTIST_ADDED:
+            [libraryModel resetCachedListOfArtists];
+            break;
         case VLC_ML_EVENT_ARTIST_UPDATED:
+            [libraryModel handleArtistUpdateEvent:p_event];
+            break;
         case VLC_ML_EVENT_ARTIST_DELETED:
-        {
-            VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;
-            [libraryModel resetCachedListOfArtists];
+            [libraryModel handleArtistDeletionEvent:p_event];
             break;
-        }
         case VLC_ML_EVENT_ALBUM_ADDED:
+            [libraryModel resetCachedListOfAlbums];
+            break;
         case VLC_ML_EVENT_ALBUM_UPDATED:
+            [libraryModel handleAlbumUpdateEvent:p_event];
+            break;
         case VLC_ML_EVENT_ALBUM_DELETED:
-        {
-            VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;
-            [libraryModel resetCachedListOfAlbums];
+            [libraryModel handleAlbumDeletionEvent:p_event];
             break;
-        }
         case VLC_ML_EVENT_GENRE_ADDED:
+            [libraryModel resetCachedListOfGenres];
+            break;
         case VLC_ML_EVENT_GENRE_UPDATED:
+            [libraryModel handleGenreUpdateEvent:p_event];
+            break;
         case VLC_ML_EVENT_GENRE_DELETED:
-        {
-            VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;
-            [libraryModel resetCachedListOfGenres];
+            [libraryModel handleGenreDeletionEvent:p_event];
             break;
-        }
         case VLC_ML_EVENT_FOLDER_ADDED:
         case VLC_ML_EVENT_FOLDER_UPDATED:
         case VLC_ML_EVENT_FOLDER_DELETED:
-        {
-            VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;
             [libraryModel resetCachedListOfMonitoredFolders];
             break;
-        }
         default:
             break;
     }
@@ -182,7 +185,12 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
         _p_mediaLibrary = library;
         _p_eventCallback = vlc_ml_event_register_callback(_p_mediaLibrary, libraryCallback, (__bridge void *)self);
 
+        // Serial queues make avoiding concurrent modification of the caches easy, while avoiding
+        // locking other queues
         _mediaItemCacheModificationQueue = dispatch_queue_create("mediaItemCacheModificationQueue", 0);
+        _albumCacheModificationQueue = dispatch_queue_create("albumCacheModificationQueue", 0);
+        _artistCacheModificationQueue = dispatch_queue_create("artistCacheModificationQueue", 0);
+        _genreCacheModificationQueue = dispatch_queue_create("genreCacheModificationQueue", 0);
 
         _defaultNotificationCenter = [NSNotificationCenter defaultCenter];
         [_defaultNotificationCenter addObserver:self
@@ -636,7 +644,6 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
     NSParameterAssert(p_event != NULL);
 
     const int64_t itemId = p_event->modification.i_entity_id;
-    NSLog(@"Deleting %lli", itemId);
 
     [self performActionOnMediaItemInCache:itemId action:^(NSMutableArray * const cachedMediaArray, const NSUInteger cachedMediaIndex, NSMutableArray * const recentMediaArray, const NSUInteger recentMediaIndex) {
 
@@ -668,4 +675,175 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
     }];
 }
 
+- (NSInteger)indexForAudioGroupInCache:(NSArray * const)cache withItemId:(const int64_t)itemId
+{
+    return [cache indexOfObjectPassingTest:^BOOL(id<VLCMediaLibraryAudioGroupProtocol> audioGroupItem, const NSUInteger idx, BOOL * const stop) {
+        NSAssert(audioGroupItem != nil, @"Cache list should not contain nil audio group items");
+        return audioGroupItem.libraryID == itemId;
+    }];
+}
+
+- (void)updateAudioGroupItem:(const id<VLCMediaLibraryAudioGroupProtocol>)audioGroupItem
+                     inCache:(NSArray * const)cache
+                 usingSetter:(const SEL)setterSelector
+                  usingQueue:(const dispatch_queue_t)queue
+        withNotificationName:(const NSNotificationName)notificationName
+{
+    NSParameterAssert([self respondsToSelector:setterSelector]);
+    const int64_t itemId = audioGroupItem.libraryID;
+
+    dispatch_async(queue, ^{
+        const NSUInteger audioGroupIndex = [self indexForAudioGroupInCache:cache
+                                                                withItemId:itemId];
+        if (audioGroupIndex == NSNotFound) {
+            NSLog(@"Did not find audio group item with id %lli in cache.", itemId);
+            return;
+        }
+
+        // Block calling queue while we modify the cache, preventing dangerous concurrent modification
+        dispatch_sync(dispatch_get_main_queue(), ^{
+            NSMutableArray * const mutableAudioGroupCache = [cache mutableCopy];
+            [mutableAudioGroupCache replaceObjectAtIndex:audioGroupIndex withObject:audioGroupItem];
+            NSArray * const immutableCopy = [mutableAudioGroupCache copy];
+
+            const IMP cacheSetterImp = [self methodForSelector:setterSelector];
+            void (*cacheSetterFunction)(id, SEL, NSArray *) = (void *)cacheSetterImp;
+            cacheSetterFunction(self, setterSelector, immutableCopy);
+
+            [self->_defaultNotificationCenter postNotificationName:notificationName
+                                                            object:audioGroupItem];
+        });
+    });
+}
+
+- (void)deleteAudioGroupItemWithId:(const int64_t)itemId
+                           inCache:(NSArray * const)cache
+                       usingSetter:(const SEL)setterSelector
+                        usingQueue:(const dispatch_queue_t)queue
+              withNotificationName:(const NSNotificationName)notificationName
+{
+    NSParameterAssert([self respondsToSelector:setterSelector]);
+
+    dispatch_async(queue, ^{
+        const NSUInteger audioGroupIndex = [self indexForAudioGroupInCache:cache
+                                                                withItemId:itemId];
+        if (audioGroupIndex == NSNotFound) {
+            NSLog(@"Did not find audio group item with id %lli in cache.", itemId);
+            return;
+        }
+
+        const id<VLCMediaLibraryAudioGroupProtocol> audioGroupItem = cache[audioGroupIndex];
+
+        // Block calling queue while we modify the cache, preventing dangerous concurrent modification
+        dispatch_sync(dispatch_get_main_queue(), ^{
+            NSMutableArray * const mutableAudioGroupCache = [cache mutableCopy];
+            [mutableAudioGroupCache removeObjectAtIndex:audioGroupIndex];
+            NSArray * const immutableCopy = [mutableAudioGroupCache copy];
+
+            const IMP cacheSetterImp = [self methodForSelector:setterSelector];
+            void (*cacheSetterFunction)(id, SEL, NSArray *) = (void *)cacheSetterImp;
+            cacheSetterFunction(self, setterSelector, immutableCopy);
+
+            [self->_defaultNotificationCenter postNotificationName:notificationName
+                                                            object:audioGroupItem];
+        });
+    });
+}
+
+- (void)handleAlbumUpdateEvent:(const vlc_ml_event_t * const)p_event
+{
+    NSParameterAssert(p_event != NULL);
+
+    const int64_t itemId = p_event->modification.i_entity_id;
+
+    VLCMediaLibraryAlbum * const album = [VLCMediaLibraryAlbum albumWithID:itemId];
+    if (album == nil) {
+        NSLog(@"Could not find a library album with this ID. Can't handle update.");
+        return;
+    }
+
+    [self updateAudioGroupItem:album
+                       inCache:_cachedAlbums
+                   usingSetter:@selector(setCachedAlbums:)
+                    usingQueue:_albumCacheModificationQueue
+          withNotificationName:VLCLibraryModelAlbumUpdated];
+}
+
+- (void)handleAlbumDeletionEvent:(const vlc_ml_event_t * const)p_event
+{
+    NSParameterAssert(p_event != NULL);
+
+    const int64_t itemId = p_event->modification.i_entity_id;
+
+    [self deleteAudioGroupItemWithId:itemId
+                             inCache:_cachedAlbums
+                         usingSetter:@selector(setCachedAlbums:)
+                          usingQueue:_albumCacheModificationQueue
+                withNotificationName:VLCLibraryModelAlbumDeleted];
+}
+
+- (void)handleArtistUpdateEvent:(const vlc_ml_event_t * const)p_event
+{
+    NSParameterAssert(p_event != NULL);
+
+    const int64_t itemId = p_event->modification.i_entity_id;
+
+    VLCMediaLibraryArtist * const artist = [VLCMediaLibraryArtist artistWithID:itemId];
+    if (artist == nil) {
+        NSLog(@"Could not find a library artist with this ID. Can't handle update.");
+        return;
+    }
+
+    [self updateAudioGroupItem:artist
+                       inCache:_cachedArtists
+                   usingSetter:@selector(setCachedArtists:)
+                    usingQueue:_artistCacheModificationQueue
+          withNotificationName:VLCLibraryModelArtistUpdated];
+}
+
+- (void)handleArtistDeletionEvent:(const vlc_ml_event_t * const)p_event
+{
+    NSParameterAssert(p_event != NULL);
+
+    const int64_t itemId = p_event->modification.i_entity_id;
+
+    [self deleteAudioGroupItemWithId:itemId
+                             inCache:_cachedArtists
+                         usingSetter:@selector(setCachedArtists:)
+                          usingQueue:_artistCacheModificationQueue
+                withNotificationName:VLCLibraryModelArtistDeleted];
+}
+
+- (void)handleGenreUpdateEvent:(const vlc_ml_event_t * const)p_event
+{
+    NSParameterAssert(p_event != NULL);
+
+    const int64_t itemId = p_event->modification.i_entity_id;
+
+    VLCMediaLibraryGenre * const genre = [VLCMediaLibraryGenre genreWithID:itemId];
+    if (genre == nil) {
+        NSLog(@"Could not find a library genre with this ID. Can't handle update.");
+        return;
+    }
+
+    [self updateAudioGroupItem:genre
+                       inCache:_cachedGenres
+                   usingSetter:@selector(setCachedGenres:)
+                    usingQueue:_genreCacheModificationQueue
+          withNotificationName:VLCLibraryModelGenreUpdated];
+}
+
+- (void)handleGenreDeletionEvent:(const vlc_ml_event_t * const)p_event
+{
+    NSParameterAssert(p_event != NULL);
+
+    const int64_t itemId = p_event->modification.i_entity_id;
+
+    [self deleteAudioGroupItemWithId:itemId
+                             inCache:_cachedGenres
+                         usingSetter:@selector(setCachedGenres:)
+                          usingQueue:_genreCacheModificationQueue
+                withNotificationName:VLCLibraryModelGenreDeleted];
+}
+
 @end


=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.m
=====================================
@@ -34,6 +34,7 @@
 
 #import "library/VLCLibraryController.h"
 #import "library/VLCLibraryDataTypes.h"
+#import "library/VLCLibraryModel.h"
 #import "library/VLCLibraryTableCellView.h"
 #import "library/VLCLibraryTableView.h"
 #import "library/VLCLibraryUIUnits.h"
@@ -127,6 +128,12 @@ const CGFloat VLCLibraryAlbumTableCellViewDefaultHeight = 168.;
     self.artistNameTextField.textColor = [NSColor VLCAccentColor];
 
     [self prepareForReuse];
+
+    NSNotificationCenter * const notificationCenter = NSNotificationCenter.defaultCenter;
+    [notificationCenter addObserver:self
+                           selector:@selector(handleAlbumUpdated:)
+                               name:VLCLibraryModelAlbumUpdated
+                             object:nil];
 }
 
 - (void)setupTracksTableView
@@ -190,6 +197,21 @@ const CGFloat VLCLibraryAlbumTableCellViewDefaultHeight = 168.;
     [_tracksTableView reloadData];
 }
 
+- (void)handleAlbumUpdated:(NSNotification *)notification
+{
+    NSParameterAssert(notification);
+    if (_representedAlbum == nil) {
+        return;
+    }
+
+    VLCMediaLibraryAlbum * const album = (VLCMediaLibraryAlbum *)notification.object;
+    if (album == nil || _representedAlbum.libraryID != album.libraryID) {
+        return;
+    }
+
+    [self setRepresentedAlbum:album];
+}
+
 - (void)setFrameSize:(NSSize)size
 {
     [super setFrameSize:size];


=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.m
=====================================
@@ -89,32 +89,60 @@ NSString * const VLCLibraryYearSortDescriptorKey = @"VLCLibraryYearSortDescripto
 {
     self = [super init];
     if(self) {
-        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
+        NSNotificationCenter * const notificationCenter = NSNotificationCenter.defaultCenter;
         [notificationCenter addObserver:self
-                               selector:@selector(libraryModelUpdated:)
+                               selector:@selector(libraryModelAudioMediaItemsReset:)
                                    name:VLCLibraryModelAudioMediaListReset
                                  object:nil];
         [notificationCenter addObserver:self
-                               selector:@selector(libraryModelAudioItemUpdated:)
+                               selector:@selector(libraryModelAudioMediaItemUpdated:)
                                    name:VLCLibraryModelAudioMediaItemUpdated
                                  object:nil];
         [notificationCenter addObserver:self
-                               selector:@selector(libraryModelAudioItemDeleted:)
+                               selector:@selector(libraryModelAudioMediaItemDeleted:)
                                    name:VLCLibraryModelAudioMediaItemDeleted
                                  object:nil];
 
         [notificationCenter addObserver:self
-                               selector:@selector(libraryModelUpdated:)
+                               selector:@selector(libraryModelArtistsReset:)
                                    name:VLCLibraryModelArtistListUpdated
                                  object:nil];
         [notificationCenter addObserver:self
-                               selector:@selector(libraryModelUpdated:)
+                               selector:@selector(libraryModelArtistUpdated:)
+                                   name:VLCLibraryModelArtistUpdated
+                                 object:nil];
+        [notificationCenter addObserver:self
+                               selector:@selector(libraryModelArtistDeleted:)
+                                   name:VLCLibraryModelArtistDeleted
+                                 object:nil];
+
+
+        [notificationCenter addObserver:self
+                               selector:@selector(libraryModelAlbumsReset:)
                                    name:VLCLibraryModelAlbumListUpdated
                                  object:nil];
         [notificationCenter addObserver:self
-                               selector:@selector(libraryModelUpdated:)
+                               selector:@selector(libraryModelAlbumUpdated:)
+                                   name:VLCLibraryModelAlbumUpdated
+                                 object:nil];
+        [notificationCenter addObserver:self
+                               selector:@selector(libraryModelAlbumDeleted:)
+                                   name:VLCLibraryModelAlbumDeleted
+                                 object:nil];
+
+        [notificationCenter addObserver:self
+                               selector:@selector(libraryModelGenresReset:)
                                    name:VLCLibraryModelGenreListUpdated
                                  object:nil];
+        [notificationCenter addObserver:self
+                               selector:@selector(libraryModelGenresUpdated:)
+                                   name:VLCLibraryModelGenreUpdated
+                                 object:nil];
+        [notificationCenter addObserver:self
+                               selector:@selector(libraryModelGenresDeleted:)
+                                   name:VLCLibraryModelGenreDeleted
+                                 object:nil];
+
         [notificationCenter addObserver:self
                                selector:@selector(currentlyPlayingItemChanged:)
                                    name:VLCPlayerCurrentMediaItemChanged
@@ -162,7 +190,7 @@ NSString * const VLCLibraryYearSortDescriptorKey = @"VLCLibraryYearSortDescripto
     }
 }
 
-- (void)libraryModelUpdated:(NSNotification * const)aNotification
+- (void)libraryModelReset:(NSNotification * const)aNotification
 {
     if(_libraryModel == nil) {
         return;
@@ -171,30 +199,138 @@ NSString * const VLCLibraryYearSortDescriptorKey = @"VLCLibraryYearSortDescripto
     [self reloadData];
 }
 
+- (void)libraryModelAudioMediaItemsReset:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_UNKNOWN) {
+        return;
+    }
+
+    [self libraryModelReset:aNotification];
+}
+
+- (void)libraryModelArtistsReset:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_ARTIST) {
+        return;
+    }
+
+    [self libraryModelReset:aNotification];
+}
+
+- (void)libraryModelAlbumsReset:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_ALBUM) {
+        return;
+    }
+
+    [self libraryModelReset:aNotification];
+}
+
+- (void)libraryModelGenresReset:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_GENRE) {
+        return;
+    }
+
+    [self libraryModelReset:aNotification];
+}
+
 - (void)libraryModelAudioItemUpdated:(NSNotification * const)aNotification
 {
+    NSParameterAssert(aNotification);
+    NSParameterAssert([aNotification.object conformsToProtocol:@protocol(VLCMediaLibraryItemProtocol)]);
+
     if(_libraryModel == nil) {
         return;
     }
 
-    NSParameterAssert(aNotification);
-    VLCMediaLibraryMediaItem * const mediaItem = (VLCMediaLibraryMediaItem * const)aNotification.object;
-    NSAssert(mediaItem != nil, @"Audio item-related notification should carry valid media item");
+    const id <VLCMediaLibraryItemProtocol> item = (id<VLCMediaLibraryItemProtocol>)aNotification.object;
+    [self reloadDataForMediaLibraryItem:item];
+}
+
+- (void)libraryModelAudioMediaItemUpdated:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_UNKNOWN) {
+        return;
+    }
+
+    [self libraryModelAudioItemUpdated:aNotification];
+}
+
+- (void)libraryModelArtistUpdated:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_ARTIST) {
+        return;
+    }
 
-    [self reloadDataForMediaLibraryItem:mediaItem];
+    [self libraryModelAudioItemUpdated:aNotification];
+}
+
+- (void)libraryModelAlbumUpdated:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_ALBUM) {
+        return;
+    }
+
+    [self libraryModelAudioItemUpdated:aNotification];
+}
+
+- (void)libraryModelGenreUpdated:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_GENRE) {
+        return;
+    }
+
+    [self libraryModelAudioItemUpdated:aNotification];
 }
 
 - (void)libraryModelAudioItemDeleted:(NSNotification * const)aNotification
 {
+    NSParameterAssert(aNotification);
+    NSParameterAssert([aNotification.object conformsToProtocol:@protocol(VLCMediaLibraryItemProtocol)]);
+
     if(_libraryModel == nil) {
         return;
     }
 
-    NSParameterAssert(aNotification);
-    VLCMediaLibraryMediaItem * const mediaItem = (VLCMediaLibraryMediaItem * const)aNotification.object;
-    NSAssert(mediaItem != nil, @"Audio item-related notification should carry valid media item");
+    const id <VLCMediaLibraryItemProtocol> item = (id<VLCMediaLibraryItemProtocol>)aNotification.object;
+    [self deleteDataForMediaLibraryItem:item];
+}
+
+- (void)libraryModelAudioMediaItemDeleted:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_UNKNOWN) {
+        return;
+    }
+
+    [self libraryModelAudioItemDeleted:aNotification];
+}
+
+- (void)libraryModelArtistDeleted:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_ARTIST) {
+        return;
+    }
+
+    [self libraryModelAudioItemDeleted:aNotification];
+}
+
+- (void)libraryModelAlbumDeleted:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_ALBUM) {
+        return;
+    }
+
+    [self libraryModelAudioItemDeleted:aNotification];
+}
+
+- (void)libraryModelGenreDeleted:(NSNotification * const)aNotification
+{
+    if (_currentParentType != VLC_ML_PARENT_GENRE) {
+        return;
+    }
 
-    [self deleteDataForMediaLibraryItem:mediaItem];
+    [self libraryModelAudioMediaItemDeleted:aNotification];
 }
 
 - (void)retainSelectedMediaItem
@@ -461,22 +597,22 @@ NSString * const VLCLibraryYearSortDescriptorKey = @"VLCLibraryYearSortDescripto
 
 - (NSUInteger)indexForMediaLibraryItemWithId:(const int64_t)itemId
 {
-    return [self.displayedCollection indexOfObjectPassingTest:^BOOL(VLCMediaLibraryMediaItem * const mediaItem, const NSUInteger idx, BOOL * const stop) {
-        NSAssert(mediaItem != nil, @"Cache list should not contain nil media items");
-        return mediaItem.libraryID == itemId;
+    return [self.displayedCollection indexOfObjectPassingTest:^BOOL(const id<VLCMediaLibraryItemProtocol> item, const NSUInteger idx, BOOL * const stop) {
+        NSAssert(item != nil, @"Cache list should not contain nil items");
+        return item.libraryID == itemId;
     }];
 }
 
-- (void)reloadDataForMediaLibraryItem:(VLCMediaLibraryMediaItem * const)mediaItem
+- (void)reloadDataForMediaLibraryItem:(const id<VLCMediaLibraryItemProtocol>)item
 {
     [self resetLayoutsForOperation:^{
-        const NSUInteger index = [self indexForMediaLibraryItemWithId:mediaItem.libraryID];
+        const NSUInteger index = [self indexForMediaLibraryItemWithId:item.libraryID];
         if (index == NSNotFound) {
             return;
         }
 
         NSMutableArray * const mutableCollectionCopy = [self.displayedCollection mutableCopy];
-        [mutableCollectionCopy replaceObjectAtIndex:index withObject:mediaItem];
+        [mutableCollectionCopy replaceObjectAtIndex:index withObject:item];
         self.displayedCollection = [mutableCollectionCopy copy];
 
         NSIndexPath * const indexPath = [NSIndexPath indexPathForItem:index inSection:0];
@@ -499,10 +635,10 @@ NSString * const VLCLibraryYearSortDescriptorKey = @"VLCLibraryYearSortDescripto
     }];
 }
 
-- (void)deleteDataForMediaLibraryItem:(VLCMediaLibraryMediaItem * const)mediaItem
+- (void)deleteDataForMediaLibraryItem:(const id<VLCMediaLibraryItemProtocol>)item
 {
     [self resetLayoutsForOperation:^{
-        const NSUInteger index = [self indexForMediaLibraryItemWithId:mediaItem.libraryID];
+        const NSUInteger index = [self indexForMediaLibraryItemWithId:item.libraryID];
         if (index == NSNotFound) {
             return;
         }


=====================================
modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m
=====================================
@@ -4,7 +4,7 @@
  * Copyright (C) 2021 VLC authors and VideoLAN
  *
  * Authors: Samuel Bassaly <shkshk90 # gmail -dot- com>
- *          Claudio Cambra <claudio.cambra at gmail.com>
+ *          Claudio Cambra <developer at 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
@@ -75,6 +75,27 @@ NSCollectionViewSupplementaryElementKind const VLCLibraryCollectionViewAlbumSupp
     if(@available(macOS 10.12.2, *)) {
         _playAlbumButton.bezelColor = [NSColor VLCAccentColor];
     }
+
+    NSNotificationCenter * const notificationCenter = NSNotificationCenter.defaultCenter;
+    [notificationCenter addObserver:self
+                           selector:@selector(handleAlbumUpdated:)
+                               name:VLCLibraryModelAlbumUpdated
+                             object:nil];
+}
+
+- (void)handleAlbumUpdated:(NSNotification *)notification
+{
+    NSParameterAssert(notification);
+    if (_representedAlbum == nil) {
+        return;
+    }
+
+    VLCMediaLibraryAlbum * const album = (VLCMediaLibraryAlbum *)notification.object;
+    if (album == nil || _representedAlbum.libraryID != album.libraryID) {
+        return;
+    }
+
+    [self setRepresentedAlbum:album];
 }
 
 - (void)setRepresentedAlbum:(VLCMediaLibraryAlbum *)representedAlbum


=====================================
modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m
=====================================
@@ -22,9 +22,11 @@
 
 #import "VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h"
 
-#import "library/VLCLibraryDataTypes.h"
 #import "extensions/NSFont+VLCAdditions.h"
 
+#import "library/VLCLibraryDataTypes.h"
+#import "library/VLCLibraryModel.h"
+
 #import "library/audio-library/VLCLibraryAudioGroupDataSource.h"
 #import "library/audio-library/VLCLibraryAudioGroupTableViewDelegate.h"
 
@@ -50,6 +52,35 @@ NSCollectionViewSupplementaryElementKind const VLCLibraryCollectionViewAudioGrou
     _audioGroupAlbumsTableView.delegate = _audioGroupAlbumsTableViewDelegate;
     
     _audioGroupNameTextField.font = [NSFont VLCLibrarySupplementaryDetailViewTitleFont];
+
+    NSNotificationCenter * const notificationCenter = NSNotificationCenter.defaultCenter;
+    [notificationCenter addObserver:self
+                           selector:@selector(handleAudioGroupUpdated:)
+                               name:VLCLibraryModelAlbumUpdated
+                             object:nil];
+    [notificationCenter addObserver:self
+                           selector:@selector(handleAudioGroupUpdated:)
+                               name:VLCLibraryModelArtistUpdated
+                             object:nil];
+    [notificationCenter addObserver:self
+                           selector:@selector(handleAudioGroupUpdated:)
+                               name:VLCLibraryModelGenreUpdated
+                             object:nil];
+}
+
+- (void)handleAudioGroupUpdated:(NSNotification *)notification
+{
+    NSParameterAssert(notification);
+    
+    if (_representedAudioGroup == nil ||
+        notification.object == nil ||
+        ![notification.object conformsToProtocol:@protocol(VLCMediaLibraryAudioGroupProtocol)]) {
+
+        return;
+    }
+
+    const id<VLCMediaLibraryAudioGroupProtocol> audioGroup = (id<VLCMediaLibraryAudioGroupProtocol>)notification.object;
+    [self setRepresentedAudioGroup:audioGroup];
 }
 
 - (void)setRepresentedAudioGroup:(id<VLCMediaLibraryAudioGroupProtocol>)representedAudioGroup



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2a45305669ec8f96eec488e6f9d636c3af52fed4...a3a77f3a7408c4f8619fe633f39755623577356d

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2a45305669ec8f96eec488e6f9d636c3af52fed4...a3a77f3a7408c4f8619fe633f39755623577356d
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list