mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Adds ComponentGetState ECS event (#1988)
This commit is contained in:
committed by
GitHub
parent
b982b94c83
commit
051d47f4ff
@@ -51,6 +51,7 @@ namespace Robust.Client.GameStates
|
||||
[Dependency] private readonly IClientGameTiming _timing = default!;
|
||||
[Dependency] private readonly INetConfigurationManager _config = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||
[Dependency] private readonly IClientEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IComponentManager _componentManager = default!;
|
||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||
#if EXCEPTION_TOLERANCE
|
||||
@@ -335,8 +336,6 @@ namespace Robust.Client.GameStates
|
||||
|
||||
private void ResetPredictedEntities(GameTick curTick)
|
||||
{
|
||||
var bus = (EntityEventBus) _entities.EventBus;
|
||||
|
||||
foreach (var entity in _entities.GetEntities())
|
||||
{
|
||||
// TODO: 99% there's an off-by-one here.
|
||||
@@ -366,7 +365,7 @@ namespace Robust.Client.GameStates
|
||||
Logger.DebugS(CVars.NetPredict.Name, $" And also its component {comp.Name}");
|
||||
// TODO: Handle interpolation.
|
||||
var handleState = new ComponentHandleState(compState, null);
|
||||
bus.RaiseComponentEvent(comp, ref handleState);
|
||||
_entities.EventBus.RaiseComponentEvent(comp, ref handleState);
|
||||
comp.HandleComponentState(compState, null);
|
||||
}
|
||||
}
|
||||
@@ -383,6 +382,8 @@ namespace Robust.Client.GameStates
|
||||
Debug.Assert(_players.LocalPlayer != null, "_players.LocalPlayer != null");
|
||||
var player = _players.LocalPlayer.Session;
|
||||
|
||||
var bus = _entityManager.EventBus;
|
||||
|
||||
foreach (var createdEntity in createdEntities)
|
||||
{
|
||||
var compData = new Dictionary<uint, ComponentState>();
|
||||
@@ -390,7 +391,7 @@ namespace Robust.Client.GameStates
|
||||
|
||||
foreach (var (netId, component) in _componentManager.GetNetComponents(createdEntity))
|
||||
{
|
||||
var state = component.GetComponentState(player);
|
||||
var state = _componentManager.GetComponentState(bus, component, player);
|
||||
|
||||
if(state.GetType() == typeof(ComponentState))
|
||||
continue;
|
||||
@@ -474,14 +475,12 @@ namespace Robust.Client.GameStates
|
||||
}
|
||||
}
|
||||
|
||||
var bus = (EntityEventBus) _entities.EventBus;
|
||||
|
||||
// Make sure this is done after all entities have been instantiated.
|
||||
foreach (var kvStates in toApply)
|
||||
{
|
||||
var ent = kvStates.Key;
|
||||
var entity = (Entity) ent;
|
||||
HandleEntityState(entity.EntityManager.ComponentManager, entity, bus, kvStates.Value.Item1,
|
||||
HandleEntityState(entity.EntityManager.ComponentManager, entity, _entities.EventBus, kvStates.Value.Item1,
|
||||
kvStates.Value.Item2);
|
||||
}
|
||||
|
||||
@@ -549,7 +548,7 @@ namespace Robust.Client.GameStates
|
||||
return created;
|
||||
}
|
||||
|
||||
private void HandleEntityState(IComponentManager compMan, IEntity entity, EntityEventBus bus, EntityState? curState,
|
||||
private void HandleEntityState(IComponentManager compMan, IEntity entity, IEventBus bus, EntityState? curState,
|
||||
EntityState? nextState)
|
||||
{
|
||||
var compStateWork = new Dictionary<ushort, (ComponentState? curState, ComponentState? nextState)>();
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace Robust.Server.GameStates
|
||||
if (ent.LastModifiedTick < lastSeenChunk)
|
||||
continue;
|
||||
|
||||
var newState = ServerGameStateManager.GetEntityState(_entMan.ComponentManager, session, anchoredEnt, lastSeenChunk);
|
||||
var newState = ServerGameStateManager.GetEntityState(_entMan, session, anchoredEnt, lastSeenChunk);
|
||||
entityStates.Add(newState);
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ namespace Robust.Server.GameStates
|
||||
continue;
|
||||
|
||||
// only send new changes
|
||||
var newState = ServerGameStateManager.GetEntityState(_entMan.ComponentManager, session, entityUid, fromTick);
|
||||
var newState = ServerGameStateManager.GetEntityState(_entMan, session, entityUid, fromTick);
|
||||
|
||||
if (!newState.Empty)
|
||||
entityStates.Add(newState);
|
||||
@@ -342,7 +342,7 @@ namespace Robust.Server.GameStates
|
||||
// PVS enter message
|
||||
|
||||
// don't assume the client knows anything about us
|
||||
var newState = ServerGameStateManager.GetEntityState(_entMan.ComponentManager, session, entityUid, GameTick.Zero);
|
||||
var newState = ServerGameStateManager.GetEntityState(_entMan, session, entityUid, GameTick.Zero);
|
||||
entityStates.Add(newState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,13 +268,15 @@ namespace Robust.Server.GameStates
|
||||
/// <summary>
|
||||
/// Generates a network entity state for the given entity.
|
||||
/// </summary>
|
||||
/// <param name="compMan">ComponentManager that contains the components for the entity.</param>
|
||||
/// <param name="entMan">EntityManager that contains the entity.</param>
|
||||
/// <param name="player">The player to generate this state for.</param>
|
||||
/// <param name="entityUid">Uid of the entity to generate the state from.</param>
|
||||
/// <param name="fromTick">Only provide delta changes from this tick.</param>
|
||||
/// <returns>New entity State for the given entity.</returns>
|
||||
internal static EntityState GetEntityState(IComponentManager compMan, ICommonSession player, EntityUid entityUid, GameTick fromTick)
|
||||
internal static EntityState GetEntityState(IEntityManager entMan, ICommonSession player, EntityUid entityUid, GameTick fromTick)
|
||||
{
|
||||
var bus = entMan.EventBus;
|
||||
var compMan = entMan.ComponentManager;
|
||||
var changed = new List<ComponentChange>();
|
||||
|
||||
foreach (var (netId, component) in compMan.GetNetComponents(entityUid))
|
||||
@@ -294,7 +296,7 @@ namespace Robust.Server.GameStates
|
||||
{
|
||||
ComponentState? state = null;
|
||||
if (component.NetSyncEnabled && component.LastModifiedTick != GameTick.Zero && component.LastModifiedTick >= fromTick)
|
||||
state = component.GetComponentState(player);
|
||||
state = compMan.GetComponentState(bus, component, player);
|
||||
|
||||
// Can't be null since it's returned by GetNetComponents
|
||||
// ReSharper disable once PossibleInvalidOperationException
|
||||
@@ -302,7 +304,7 @@ namespace Robust.Server.GameStates
|
||||
}
|
||||
else if (component.NetSyncEnabled && component.LastModifiedTick != GameTick.Zero && component.LastModifiedTick >= fromTick)
|
||||
{
|
||||
changed.Add(ComponentChange.Changed(netId, component.GetComponentState(player)));
|
||||
changed.Add(ComponentChange.Changed(netId, compMan.GetComponentState(bus, component, player)));
|
||||
}
|
||||
else if (component.Deleted && component.LastModifiedTick >= fromTick)
|
||||
{
|
||||
@@ -331,7 +333,7 @@ namespace Robust.Server.GameStates
|
||||
DebugTools.Assert(entity.Initialized);
|
||||
|
||||
if (entity.LastModifiedTick >= fromTick)
|
||||
stateEntities.Add(GetEntityState(entityMan.ComponentManager, player, entity.Uid, fromTick));
|
||||
stateEntities.Add(GetEntityState(entityMan, player, entity.Uid, fromTick));
|
||||
}
|
||||
|
||||
// no point sending an empty collection
|
||||
|
||||
@@ -137,14 +137,14 @@ namespace Robust.Shared.GameObjects
|
||||
private static readonly ComponentShutdown CompShutdownInstance = new();
|
||||
private static readonly ComponentRemove CompRemoveInstance = new();
|
||||
|
||||
private EntityEventBus GetBus()
|
||||
private IEventBus GetBus()
|
||||
{
|
||||
// Apparently components are being created outside of the ComponentManager,
|
||||
// and the Owner is not being set correctly.
|
||||
// ReSharper disable once RedundantAssertionStatement
|
||||
DebugTools.AssertNotNull(Owner);
|
||||
|
||||
return (EntityEventBus) Owner.EntityManager.EventBus;
|
||||
return Owner.EntityManager.EventBus;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -6,7 +6,9 @@ using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Internal.TypeSystem;
|
||||
using Robust.Shared.Exceptions;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using DependencyAttribute = Robust.Shared.IoC.DependencyAttribute;
|
||||
@@ -588,6 +590,15 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ComponentState GetComponentState(IEventBus eventBus, IComponent component, ICommonSession player)
|
||||
{
|
||||
var getState = new ComponentGetState(player);
|
||||
eventBus.RaiseComponentEvent(component, ref getState);
|
||||
|
||||
return getState.State ?? component.GetComponentState(player);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
||||
@@ -48,6 +48,32 @@ namespace Robust.Shared.GameObjects
|
||||
void UnsubscribeLocalEvent<TComp, TEvent>()
|
||||
where TComp : IComponent
|
||||
where TEvent : notnull;
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches an event directly to a specific component.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This has a very specific purpose, and has massive potential to be abused.
|
||||
/// DO NOT EXPOSE THIS TO CONTENT.
|
||||
/// </remarks>
|
||||
/// <typeparam name="TEvent">Event to dispatch.</typeparam>
|
||||
/// <param name="component">Component receiving the event.</param>
|
||||
/// <param name="args">Event arguments for the event.</param>
|
||||
internal void RaiseComponentEvent<TEvent>(IComponent component, TEvent args)
|
||||
where TEvent : notnull;
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches an event directly to a specific component, by-ref.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This has a very specific purpose, and has massive potential to be abused.
|
||||
/// DO NOT EXPOSE THIS TO CONTENT.
|
||||
/// </remarks>
|
||||
/// <typeparam name="TEvent">Event to dispatch.</typeparam>
|
||||
/// <param name="component">Component receiving the event.</param>
|
||||
/// <param name="args">Event arguments for the event.</param>
|
||||
internal void RaiseComponentEvent<TEvent>(IComponent component, ref TEvent args)
|
||||
where TEvent : notnull;
|
||||
}
|
||||
|
||||
internal partial class EntityEventBus : IDirectedEventBus, IEventBus, IDisposable
|
||||
@@ -70,36 +96,16 @@ namespace Robust.Shared.GameObjects
|
||||
_eventTables = new EventTables(_entMan);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches an event directly to a specific component.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This has a very specific purpose, and has massive potential to be abused.
|
||||
/// DO NOT EXPOSE THIS TO CONTENT.
|
||||
/// </remarks>
|
||||
/// <typeparam name="TEvent">Event to dispatch.</typeparam>
|
||||
/// <param name="component">Component receiving the event.</param>
|
||||
/// <param name="args">Event arguments for the event.</param>
|
||||
internal void RaiseComponentEvent<TEvent>(IComponent component, TEvent args)
|
||||
where TEvent : notnull
|
||||
/// <inheritdoc />
|
||||
void IDirectedEventBus.RaiseComponentEvent<TEvent>(IComponent component, TEvent args)
|
||||
{
|
||||
ref var unitRef = ref Unsafe.As<TEvent, Unit>(ref args);
|
||||
|
||||
_eventTables.DispatchComponent<TEvent>(component.Owner.Uid, component, ref unitRef, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches an event directly to a specific component, by-ref.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This has a very specific purpose, and has massive potential to be abused.
|
||||
/// DO NOT EXPOSE THIS TO CONTENT.
|
||||
/// </remarks>
|
||||
/// <typeparam name="TEvent">Event to dispatch.</typeparam>
|
||||
/// <param name="component">Component receiving the event.</param>
|
||||
/// <param name="args">Event arguments for the event.</param>
|
||||
internal void RaiseComponentEvent<TEvent>(IComponent component, ref TEvent args)
|
||||
where TEvent : notnull
|
||||
/// <inheritdoc />
|
||||
void IDirectedEventBus.RaiseComponentEvent<TEvent>(IComponent component, ref TEvent args)
|
||||
{
|
||||
ref var unitRef = ref Unsafe.As<TEvent, Unit>(ref args);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Players;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
@@ -197,6 +198,15 @@ namespace Robust.Shared.GameObjects
|
||||
/// <returns>All components that have a network ID.</returns>
|
||||
NetComponentEnumerable GetNetComponents(EntityUid uid);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a component state for a certain player.
|
||||
/// </summary>
|
||||
/// <param name="eventBus">A reference to the event bus instance.</param>
|
||||
/// <param name="component">Component to generate the state for.</param>
|
||||
/// <param name="player">The player to generate the state for.</param>
|
||||
/// <returns>The component state of the component, for the player.</returns>
|
||||
ComponentState GetComponentState(IEventBus eventBus, IComponent component, ICommonSession player);
|
||||
|
||||
/// <summary>
|
||||
/// Returns ALL component instances of a specified type.
|
||||
/// </summary>
|
||||
|
||||
@@ -14,4 +14,26 @@ namespace Robust.Shared.GameStates
|
||||
Next = next;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component event for getting the component state for a specific player.
|
||||
/// </summary>
|
||||
public struct ComponentGetState
|
||||
{
|
||||
/// <summary>
|
||||
/// Input parameter. The player the state is being generated for.
|
||||
/// </summary>
|
||||
public readonly ICommonSession Player;
|
||||
|
||||
/// <summary>
|
||||
/// Output parameter. Set this to the component's state for the player.
|
||||
/// </summary>
|
||||
public ComponentState? State { get; set; }
|
||||
|
||||
public ComponentGetState(ICommonSession player)
|
||||
{
|
||||
Player = player;
|
||||
State = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
compManMock.Raise(m => m.ComponentAdded += null, new AddedComponentEventArgs(compInstance, entUid));
|
||||
|
||||
// Raise
|
||||
bus.RaiseComponentEvent(compInstance, new ComponentInit());
|
||||
((IEventBus)bus).RaiseComponentEvent(compInstance, new ComponentInit());
|
||||
|
||||
// Assert
|
||||
Assert.That(calledCount, Is.EqualTo(1));
|
||||
|
||||
Reference in New Issue
Block a user