using System;
using System.Collections.Generic;
using Robust.Shared.IoC;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Robust.Shared.GameObjects
{
///
/// An abstract class to override to implement bound user interfaces.
///
public abstract class BoundUserInterface : IDisposable
{
[Dependency] protected internal readonly IEntityManager EntMan = default!;
[Dependency] protected readonly ISharedPlayerManager PlayerManager = default!;
protected readonly SharedUserInterfaceSystem UiSystem;
public bool IsOpened { get; protected set; }
public readonly Enum UiKey;
public EntityUid Owner { get; }
///
/// Additional controls to be disposed when this BUI is disposed.
///
internal List? Disposals;
///
/// The last received state object sent from the server.
///
protected internal BoundUserInterfaceState? State { get; internal set; }
protected BoundUserInterface(EntityUid owner, Enum uiKey)
{
IoCManager.Resolve(ref EntMan);
EntMan.EntitySysManager.DependencyCollection.InjectDependencies(this);
UiSystem = EntMan.System();
Owner = owner;
UiKey = uiKey;
}
///
/// Invoked when the UI is opened.
/// Do all creation and opening of things like windows in here.
///
[MustCallBase]
protected internal virtual void Open()
{
if (IsOpened)
return;
IsOpened = true;
}
///
/// Invoked when the server uses SetState.
///
protected internal virtual void UpdateState(BoundUserInterfaceState state)
{
}
///
/// Calls if the supplied state exists and calls
///
public void Update() where T : BoundUserInterfaceState
{
if (UiSystem.TryGetUiState(Owner, UiKey, out var state))
{
UpdateState(state);
}
Update();
}
///
/// Generic update method called whenever the BUI should update.
///
public virtual void Update()
{
}
///
/// Helper method that gets called upon prototype reload.
///
public virtual void OnProtoReload(PrototypesReloadedEventArgs args)
{
}
///
/// Invoked when the server sends an arbitrary message.
///
protected internal virtual void ReceiveMessage(BoundUserInterfaceMessage message)
{
}
///
/// Invoked to close the UI.
///
public void Close()
{
if (!IsOpened)
return;
IsOpened = false;
UiSystem.CloseUi(Owner, UiKey, PlayerManager.LocalEntity, predicted: true);
}
///
/// Sends a message to the server-side UI.
///
public void SendMessage(BoundUserInterfaceMessage message)
{
UiSystem.ClientSendUiMessage(Owner, UiKey, message);
}
public void SendPredictedMessage(BoundUserInterfaceMessage message)
{
UiSystem.SendPredictedUiMessage(this, message);
}
~BoundUserInterface()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (Disposals != null)
{
foreach (var control in Disposals)
{
control.Dispose();
}
Disposals = null;
}
}
}
}
}