using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.Properties;
using Unity.Services.Multiplayer;
using UnityEngine.UIElements;
namespace Blocks.Sessions.Common
{
///
/// Provides a DataBinding compatible representation of a player in a session.
///
public class PlayerViewModel :
/* IReadOnlyPlayer, */
INotifyBindablePropertyChanged, IDataSourceViewHashProvider, IDisposable
{
private IReadOnlyPlayer _player;
private ISession _session;
private long _updateVersion;
///
/// The unique identifier for the player. If not provided for a create or join request, it will be set to the ID of the caller.
///
[CreateProperty]
public string Id => _player?.Id;
///
/// The name of the player retrieved via the Authentication service.
///
[CreateProperty]
public string Name => _player?.GetPlayerName();
///
/// Indicates if the given player is the host of the current Session.
///
[CreateProperty]
public bool IsHost => _session?.Host == Id;
///
/// The allocation id
///
public string AllocationId => _player?.AllocationId;
///
/// Custom game-specific properties that apply to an individual player (e.g. `role` or `skill`).
///
public IReadOnlyDictionary Properties => _player?.Properties;
///
/// The time at which the member joined the Session.
///
public DateTime Joined => _player?.Joined ?? DateTime.UnixEpoch;
///
/// The last time the metadata for this member was updated.
///
public DateTime LastUpdated => _player?.LastUpdated ?? DateTime.UnixEpoch;
///
/// The Session the player is part of.
///
public ISession Session => _session;
public PlayerViewModel(IReadOnlyPlayer player, ISession session)
{
_player = player;
_session = session;
_session.Changed += OnSessionChanged;
_session.SessionHostChanged += OnSessionHostChanged;
_session.PlayerPropertiesChanged += OnSessionPlayerPropertiesChanged;
}
private void OnSessionHostChanged(string obj)
{
_updateVersion++;
Notify(nameof(IsHost));
}
private void OnSessionPlayerPropertiesChanged()
{
_updateVersion++;
if (!string.IsNullOrEmpty(Name))
{
Notify(nameof(Name));
}
Notify(nameof(Properties));
}
private void OnSessionChanged()
{
_updateVersion++;
Notify(nameof(Session));
}
public void Dispose()
{
_session.Changed -= OnSessionChanged;
_session.SessionHostChanged -= OnSessionHostChanged;
_session.PlayerPropertiesChanged -= OnSessionPlayerPropertiesChanged;
_player = null;
_session = null;
}
///
/// This method is used by UIToolkit to determine if any data bound to the UI has changed.
/// Instead of hashing the data, an m_UpdateVersion counter is incremented when changes occur.
///
public long GetViewHashCode() => _updateVersion;
///
/// Suggested implementation of INotifyBindablePropertyChanged from UIToolkit.
///
public event EventHandler propertyChanged;
private void Notify([CallerMemberName] string property = null)
{
propertyChanged?.Invoke(this, new BindablePropertyChangedEventArgs(property));
}
}
}