using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.Properties;
using Unity.Services.Multiplayer;
using UnityEngine.UIElements;
namespace Blocks.Sessions
{
///
/// Provides a DataBinding compatible representation of a Session associated information.
///
public class SessionInfoViewModel : ISessionInfo,
INotifyBindablePropertyChanged, IDataSourceViewHashProvider, IDisposable
{
private const string k_Unavailalble = "N/A";
private ISession _session;
private ISessionInfo _sessionInfo;
private long _updateVersion;
public SessionInfoViewModel(ISessionInfo sessionInfo)
{
_sessionInfo = sessionInfo;
}
public SessionInfoViewModel(ISession session)
{
_session = session;
_session.Changed += OnSessionChanged;
_session.SessionHostChanged += OnSessionHostChanged;
_session.SessionPropertiesChanged += OnSessionPropertiesChanged;
// should we attempt to query the associated info?
}
///
[CreateProperty]
public string Name
=> _sessionInfo?.Name ?? _session?.Name;
///
[CreateProperty]
public string Id
=> _sessionInfo?.Id ?? _session?.Id;
///
[CreateProperty]
public string Upid
=> _sessionInfo?.Upid ?? k_Unavailalble;
///
[CreateProperty]
public string HostId
=> _sessionInfo?.HostId ?? _session?.Host;
///
[CreateProperty]
public int AvailableSlots
=> _sessionInfo?.AvailableSlots ?? _session?.AvailableSlots ?? 0;
///
[CreateProperty]
public int MaxPlayers
=> _sessionInfo?.MaxPlayers ?? _session?.MaxPlayers ?? 0;
///
[CreateProperty]
public bool IsLocked
=> _sessionInfo?.IsLocked ?? _session?.IsLocked ?? true;
///
[CreateProperty]
public bool HasPassword
=> _sessionInfo?.HasPassword ?? _session?.HasPassword ?? true;
///
[CreateProperty]
public DateTime LastUpdated
=> _sessionInfo?.LastUpdated ?? DateTime.UnixEpoch;
///
[CreateProperty]
public DateTime Created
=> _sessionInfo?.Created ?? DateTime.UnixEpoch;
///
[CreateProperty]
public IReadOnlyDictionary Properties
=> _sessionInfo?.Properties ?? _session?.Properties;
private void OnSessionHostChanged(string obj)
{
_updateVersion++;
Notify(nameof(HostId));
}
private void OnSessionPropertiesChanged()
{
_updateVersion++;
Notify(nameof(Properties));
}
private void OnSessionChanged()
{
_updateVersion++;
Notify(nameof(Name));
Notify(nameof(LastUpdated));
Notify(nameof(HasPassword));
Notify(nameof(IsLocked));
Notify(nameof(MaxPlayers));
Notify(nameof(AvailableSlots));
}
public void Dispose()
{
if (_session != null)
{
_session.Changed -= OnSessionChanged;
_session.SessionHostChanged -= OnSessionHostChanged;
_session.SessionPropertiesChanged -= OnSessionPropertiesChanged;
}
_session = null;
_sessionInfo = 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));
}
}
}