Skip to content

Commit

Permalink
Defer clientside BUI opens (#5073)
Browse files Browse the repository at this point in the history
* Defer clientside BUI opens

Needs content fix first as storage UI breaks.

* tweaks

* Re-revert this because it seems needed
  • Loading branch information
metalgearsloth authored May 3, 2024
1 parent caf9e45 commit 7e331ea
Showing 1 changed file with 32 additions and 24 deletions.
56 changes: 32 additions & 24 deletions Robust.Shared/GameObjects/Systems/SharedUserInterfaceSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,18 @@ public override void Initialize()

SubscribeLocalEvent<UserInterfaceComponent, OpenBoundInterfaceMessage>(OnUserInterfaceOpen);
SubscribeLocalEvent<UserInterfaceComponent, CloseBoundInterfaceMessage>(OnUserInterfaceClosed);
SubscribeLocalEvent<UserInterfaceComponent, ComponentStartup>(OnUserInterfaceStartup);
SubscribeLocalEvent<UserInterfaceComponent, ComponentShutdown>(OnUserInterfaceShutdown);
SubscribeLocalEvent<UserInterfaceComponent, ComponentGetState>(OnUserInterfaceGetState);
SubscribeLocalEvent<UserInterfaceComponent, ComponentHandleState>(OnUserInterfaceHandleState);

SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<PlayerDetachedEvent>(OnPlayerDetached);

SubscribeLocalEvent<UserInterfaceUserComponent, ComponentShutdown>(OnActorShutdown);
SubscribeLocalEvent<UserInterfaceUserComponent, ComponentGetStateAttemptEvent>(OnGetStateAttempt);
SubscribeLocalEvent<UserInterfaceUserComponent, ComponentGetState>(OnActorGetState);
SubscribeLocalEvent<UserInterfaceUserComponent, ComponentHandleState>(OnActorHandleState);

_player.PlayerStatusChanged += OnStatusChange;
}

private void OnStatusChange(object? sender, SessionStatusEventArgs e)
{
var attachedEnt = e.Session.AttachedEntity;

if (attachedEnt == null)
return;

// Content can't handle it yet sadly :(
CloseUserUis(attachedEnt.Value);
}

public override void Shutdown()
{
base.Shutdown();
_player.PlayerStatusChanged -= OnStatusChange;
}

/// <summary>
Expand Down Expand Up @@ -135,6 +118,11 @@ private void OnMessageReceived(BoundUIWrapMessage msg, EntityUid sender)

#region User

private void OnActorShutdown(Entity<UserInterfaceUserComponent> ent, ref ComponentShutdown args)
{
CloseUserUis((ent.Owner, ent.Comp));
}

private void OnGetStateAttempt(Entity<UserInterfaceUserComponent> ent, ref ComponentGetStateAttemptEvent args)
{
if (args.Cancelled || args.Player?.AttachedEntity != ent.Owner)
Expand Down Expand Up @@ -233,10 +221,8 @@ private void OnUserInterfaceClosed(Entity<UserInterfaceComponent> ent, ref Close
Dirty(ent);

// If the actor is also deleting then don't worry about updating what they have open.
if (!TerminatingOrDeleted(actor))
if (!TerminatingOrDeleted(actor) && _userQuery.TryComp(actor, out var actorComp))
{
var actorComp = EnsureComp<UserInterfaceUserComponent>(actor);

if (actorComp.OpenInterfaces.TryGetValue(ent.Owner, out var keys))
{
keys.Remove(args.UiKey);
Expand Down Expand Up @@ -282,6 +268,20 @@ private void OnUserInterfaceOpen(Entity<UserInterfaceComponent> ent, ref OpenBou
EnsureClientBui(ent, args.UiKey, ent.Comp.Interfaces[args.UiKey]);
}

private void OnUserInterfaceStartup(Entity<UserInterfaceComponent> ent, ref ComponentStartup args)
{
// PlayerAttachedEvent will catch some of these.
foreach (var (key, bui) in ent.Comp.ClientOpenInterfaces)
{
bui.Open();

if (ent.Comp.States.TryGetValue(key, out var state))
{
bui.UpdateState(state);
}
}
}

private void OnUserInterfaceShutdown(EntityUid uid, UserInterfaceComponent component, ComponentShutdown args)
{
foreach (var bui in component.ClientOpenInterfaces.Values)
Expand Down Expand Up @@ -393,19 +393,22 @@ private void OnUserInterfaceHandleState(Entity<UserInterfaceComponent> ent, ref
// If UI not open then open it
var attachedEnt = _player.LocalEntity;

// If we get the first state for an ent coming in then don't open BUIs yet, just defer it until later.
var open = ent.Comp.LifeStage > ComponentLifeStage.Added;

if (attachedEnt != null)
{
foreach (var (key, value) in ent.Comp.Interfaces)
{
EnsureClientBui(ent, key, value);
EnsureClientBui(ent, key, value, open);
}
}
}

/// <summary>
/// Opens a client's BUI if not already open and applies the state to it.
/// </summary>
private void EnsureClientBui(Entity<UserInterfaceComponent> entity, Enum key, InterfaceData data)
private void EnsureClientBui(Entity<UserInterfaceComponent> entity, Enum key, InterfaceData data, bool open = true)
{
// If it's out BUI open it up and apply the state, otherwise do nothing.
var player = _player.LocalEntity;
Expand All @@ -428,6 +431,11 @@ private void EnsureClientBui(Entity<UserInterfaceComponent> entity, Enum key, In
var boundUserInterface = (BoundUserInterface) _factory.CreateInstance(type, [entity.Owner, key]);

entity.Comp.ClientOpenInterfaces[key] = boundUserInterface;

// This is just so we don't open while applying UI states.
if (!open)
return;

boundUserInterface.Open();

if (entity.Comp.States.TryGetValue(key, out var buiState))
Expand Down

0 comments on commit 7e331ea

Please sign in to comment.