UI: Add UUID to file-based list widgets - #11126
Conversation
List widgets are currently used as playlists in source properties, but only contain the file paths and no other identifying information. This can lead to files being added multiple times, so when changes to list order occurs, plugins cannot uniquely identify which duplicate item was actually changed (because they're only identified by the path). By adding a UUID to the user data role of a list item, an additional unique information is added that allows plugins to de-duplicate list items.
|
It appears that when changing the playlist setting programmatically, one has to generate their own uuid as well, as the uuid is only added when it is done through the UI, or the settings are saved using the UI. Is that fine? Or perhaps the sources that utilize this uuid feature are supposed to fix the data themselves by adding a uuid property? |
I feel like the entire functionality might need to be revisited from a conceptual point of view, because I have a hunch that we just lack the tools or APIs to properly support "playlist" as a first class functionality: Say a plugin has a full-fledged implementation of a playlist, including the ability to handle duplicate entries (because there is conceptually no reason why a user couldn't add the same item at different places), and to keep track of the "current" item without also being confused about the duplicates and all, then there is no way for the plugin to communicate all those details to So instead of interpreting a simple "list of things"-property as a playlist, the properties API would need to provide an actual "playlist" property, with all the internal plumbing necessary for it but also exposing additional API methods to manage its state (necessary to be able to correctly track the "current" playlist item and also being able to rearrange or sort the playlist without losing track of which item is still the "current" one). With that in place, the plugin as well as the UI code converting properties into the property dialog could manage and query the state of the playlist without duplicating the code and effort (and even API consumers would just use those bespoke methods). Otherwise it ends up any consumer's responsibility to
And there is no way to ensure or enforce this right now (and cannot be with the design of properties as-is). |
Description
List widgets are currently used as playlists in source properties, but only contain the file paths and no other identifying information.
This can lead to files being added multiple times, so when changes to list order occurs, plugins cannot uniquely identify which duplicate item was actually changed (because they're only identified by the path).
By adding a UUID to the user data role of a list item, an additional unique information is added that allows plugins to de-duplicate list items.
Motivation and Context
Initially wrote #8051 and @PatTheMav suggested that the obs_data should be left unmodified and this is one of their suggestions. I merely added a way for this to be backwards-compatible with existing editable lists (by generating UUIDs for items without uuids yet, however this is only done if the properties of the source loaded during runtime).
I am writing a playlist plugin, similar to VLC Video Source, but uses the ffmpeg source. In addition, I wanted to fix the limitations of the vlc source, namely: (1) restarts playback from the first file everytime the settings is opened and saved (even without actually changing anything; (2) saving the currently playing file even if OBS is reopened. this behavior can be changed by the user. Because of this, I need to add an ID field to each item that is added in the editable list, so that i can find the currently playing file in the list, without the issue of duplicated items (string matching would only return the position of the first file). This also lets me edit the currently playing file, which means the file would change, but the position of the currently playing file is the same. String searching would not allow that. In addition, comparing by ID will be faster than string searching. However, whenever the list is modified, the ID field that i add to each item in the array gets cleared. With this change, my plugin works now. The concept behind my plugin may also be used later on in the vlc source.
Additional context: some OBS users like me want to use a playlist and add/remove files while it is playing, or even just toggle the Loop option without the source restarting. This change enables that.
The downside of this compared to my original suggestion (as I mentioned in the original PR) is that no other metadata can be attached to each item without us adding other api functions. Though this can be worked around by having the plugin code handle the metadata by themselves, by matching uuids.
How Has This Been Tested?
I tested adding files while checking the scene collection json to see if the uuid is added, and that old items retain their old uuids. Moving files also works normally (UUIDs are also moved). I also tried deleting the uuid fields from the json, opening the properties, and verified the UUIDs were regenerated. UUIDs also persist across program restarts. I have also successfully made a build of my media-playlist-source that works with this new change and tested it.
Types of changes
Checklist: