anthonysharpy / sandbank

Sandbank is the easy-to-use database for s&box.
Other
8 stars 0 forks source link

Properties are not saved when their value is modified #70

Open bub-bl opened 6 days ago

bub-bl commented 6 days ago

This is my data model:

public sealed class PlayerData : Component
{
    [Saved, HostSync, ReadOnly, Property, Feature( "Data" )]
    public string UID { get; set; } = null!;

    [Saved, HostSync, ReadOnly, Property, Feature( "Data" )]
    public SteamId Owner { get; init; }

    [Saved, HostSync, ReadOnly, Property, Feature( "Data" )]
    public CharacterId? Character { get; set; }

    [Saved, HostSync, ReadOnly, Property, Feature( "Data" )]
    public List<CharacterId> Characters { get; init; } = new();

    [Saved, HostSync, ReadOnly, Property, Feature( "Data" )]
    public DateTime LastLogin { get; set; }

    [Saved, HostSync, ReadOnly, Property, Feature( "Data" )]
    public DateTime CreatedAt { get; init; }

    public void Load()
    {
        using var _ = Rpc.FilterInclude( Connection.Host );
        LoadHost();
    }

    public void LoadHost()
    {
        Assert.True( Networking.IsHost, "Cannot load player data on a client" );

        var data = Sandbank.SelectOne<PlayerData>( "players", x => x.Owner == Owner );
        Sandbank.CopySavedData( data, this );
    }
}

I use the data model from the Player component When the player is connected, i want to update the LastLogin property with the current date. The time is updated into the PlayerData component but never saved on the disk

public sealed partial class Player : Component
{
    [RequireComponent] public PlayerData Data { get; private set; } = null!;

        private void LoadPlayerHost( Connection channel )
    {
        Assert.True( channel.IsHost, "Cannot load player on a client" );

        var player = Sandbank.SelectOne<PlayerData>( "players", x => x.Owner == channel.SteamId );

        if ( player is null )
        {
            CreatePlayerHost( channel );
        }
        else
        {
                        // When the player is connected, i want to update the LastLogin time
                        // The time is updated into the PlayerData component but never saved on the disk
            Sandbank.CopySavedData( player, Data );
            Data.LastLogin = DateTime.UtcNow;

            Log.Info( "Updated player data for " + Data.LastLogin + ", " + Data.CreatedAt );
        }
    }
}

The PlayerData should be saved when any properties of this class is updated

anthonysharpy commented 1 day ago

Hiya @bub-bl, sorry for taking ages to look at this, I had an exam this weekend so have been a bit busy

From the code above I can't see anywhere where you're saving the data (maybe I just don't have that bit?)

Typically to save with the [Saved] attribute you would use something like Sandbank.Insert(...). Alternatively if you use the [AutoSaved] attribute it should save automatically