Playnite Forums
Using Reference Fields in Playnite Extensions - Printable Version

+- Playnite Forums (https://playnite.link/forum)
+-- Forum: Development (https://playnite.link/forum/forum-10.html)
+--- Forum: Extensions (https://playnite.link/forum/forum-5.html)
+--- Thread: Using Reference Fields in Playnite Extensions (/thread-297.html)



Using Reference Fields in Playnite Extensions - bburky - 06-09-2020

I had a conversation with @darklinkpower about how to use `IItemCollection`/reference objects in Playnite. I thought I'd share my notes for everyone else here. The below text talks about `Feature` objects, but all of this should apply to `Categories`, `Tags`, `Series` or anything else that works like this.

This is actually covered in the Playnite docs, but I thought some example code might help everyone here. https://playnite.link/docs/tutorials/scripts/scriptingDatabase.html#handling-reference-fields

* * *

A Game object has a `Features` field with all the features it currently has. This list is read only, you must instead make changes to `FeatureIds`.

Listing a game's feature names

$game = $playniteApi.MainView.SelectedGames[0]
$game.Features.Name # Returns a list of strings for all the feature names

Query for all games with a feature name

$playniteApi.Database.Games | Where-Object {$_.Features.Name -Contains "Achievements"}
Both of the above examples convert the Features list to a list of strings for easier querying in PowerShell. If you'd like to actually work with the `Feature` object you can do something like this:

$feature = $PlayniteApi.Database.Features | Where-Object {$_.Name -Eq "Achievements"}
# $feature is $null if it did not exist in the DB
$playniteApi.Database.Games | Where-Object {$_.Features -Contains $feature}

Add a new Feature to a List of Games

ItemCollection.Add(String) is documented to return the existing item from the database if it already exists, so you can safely just always try to create the `Feature` in the DB, even if it's already there. (Assuming that's the behavior you want.) This function also takes a string, so can pass it a string and it returns the existing `Feature` or it creates it for you and returns it. Please note that the comparison is case insensitive when checking the DB, whatever you use the first time becomes the capitalization stored in the DB. https://playnite.link/docs/api/Playnite.SDK.IItemCollection-1.html#Playnite_SDK_IItemCollection_1_Add_System_String_

Here's some half tested code to demonstrate adding a Feature:

$featureName = "Test"
$feature = $PlayniteApi.Database.Features.Add($featureName)
# "Test" is guaranteed to be an existing Feature in the DB now

foreach ($game in $PlayniteApi.MainView.SelectedGames) {
    # Neither of these work, you can't add to Features directly:
    # $game.Features.Add($feature)
    # $game.Features.Add("Test")

    # Instead add the GUID of the $feature to the FeatureIds list
    # Also, += is a nice shortcut for .Add()
    # Make sure you test for the case where a game has no features yet ($game.FeatureIds can be null)
    [guid[]]$featureIds = $feature.Id
    if ($game.FeatureIds) {
        $game.FeatureIds += $featureIds
    } else {
        $game.FeatureIds = $featureIds
    }

    # Remember to always update the game
    $PlayniteApi.Database.Games.Update($game)
}



RE: Using Reference Fields in Playnite Extensions - Crow - 06-10-2020

Thanks for this. We should definitely describe this better in official docs.


RE: Using Reference Fields in Playnite Extensions - bburky - 06-10-2020

Looking at some old code of mine, I had to handle `FeatureIds` being null. But now I can't reproduce that behavior.

Crow, is it still the case that the ids list can be null?

I used to have to use some code like this:
$features = "foo", "bar"
[guid[]]$featureIds = $PlayniteApi.Database.Features.Add($features).Id

if ($game.FeatureIds) {
    $game.FeatureIds += $featureIds
} else {
    $game.FeatureIds = $featureIds
}



RE: Using Reference Fields in Playnite Extensions - Crow - 06-10-2020

Yes it can be null, the default state is null.


RE: Using Reference Fields in Playnite Extensions - bburky - 06-10-2020

Thanks for clarifying. I updated the original post in this thread. (Didn't actually test the code, but I think it works. Hopefully has no type errors.)


RE: Using Reference Fields in Playnite Extensions - steve-o - 09-26-2020

How would I go about accessing an element from one of these collections (say, Tags) in xaml? Say I wanted to grab the first element, or a specific element with id=X? (Let's not worry about variable ids, just hardcoding a known value woud be sufficient.)


RE: Using Reference Fields in Playnite Extensions - Crow - 09-26-2020

Since those are lists, you can only index them by a position. Adding "[0]" would get you first tag for example.