Fixes EntityLookup not being restarted correctly on reconnect.

This commit is contained in:
Vera Aguilera Puerto
2021-05-18 17:48:40 +02:00
parent a6dae8e30a
commit ae9c2423ff
8 changed files with 48 additions and 25 deletions

View File

@@ -26,6 +26,7 @@ namespace Robust.Client
[Dependency] private readonly IPlayerManager _playMan = default!;
[Dependency] private readonly INetConfigurationManager _configManager = default!;
[Dependency] private readonly IClientEntityManager _entityManager = default!;
[Dependency] private readonly IEntityLookup _entityLookup = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IDiscordRichPresence _discord = default!;
[Dependency] private readonly IGameTiming _timing = default!;
@@ -176,15 +177,6 @@ namespace Robust.Client
PlayerJoinedServer?.Invoke(this, new PlayerEventArgs(session));
}
private void GameStartedSetup()
{
_entityManager.Startup();
_mapManager.Startup();
_timing.ResetSimTime();
_timing.Paused = false;
}
/// <summary>
/// Player is joining the game
/// </summary>
@@ -219,12 +211,22 @@ namespace Robust.Client
GameStoppedReset();
}
private void GameStartedSetup()
{
_entityManager.Startup();
_mapManager.Startup();
_entityLookup.Startup();
_timing.ResetSimTime();
_timing.Paused = false;
}
private void GameStoppedReset()
{
IoCManager.Resolve<INetConfigurationManager>().FlushMessages();
_gameStates.Reset();
_playMan.Shutdown();
IoCManager.Resolve<IEntityLookup>().Shutdown();
_entityLookup.Shutdown();
_entityManager.Shutdown();
_mapManager.Shutdown();
_discord.ClearPresence();

View File

@@ -45,7 +45,7 @@ namespace Robust.Client
IoCManager.Register<IMapManagerInternal, ClientMapManager>();
IoCManager.Register<IClientMapManager, ClientMapManager>();
IoCManager.Register<IEntityManager, ClientEntityManager>();
IoCManager.Register<IEntityLookup, SharedEntityLookup>();
IoCManager.Register<IEntityLookup, EntityLookup>();
IoCManager.Register<IComponentFactory, ClientComponentFactory>();
IoCManager.Register<ITileDefinitionManager, ClydeTileDefinitionManager>();
IoCManager.Register<IClydeTileDefinitionManager, ClydeTileDefinitionManager>();

View File

@@ -125,7 +125,6 @@ namespace Robust.Client
_prototypeManager.Resync();
_mapManager.Initialize();
_entityManager.Initialize();
IoCManager.Resolve<IEntityLookup>().Initialize();
_gameStateManager.Initialize();
_placementManager.Initialize();
_viewVariablesManager.Initialize();

View File

@@ -306,7 +306,6 @@ namespace Robust.Server
// Call Init in game assemblies.
_modLoader.BroadcastRunLevel(ModRunLevel.Init);
_entityManager.Initialize();
IoCManager.Resolve<IEntityLookup>().Initialize();
IoCManager.Resolve<ISerializationManager>().Initialize();
@@ -319,6 +318,7 @@ namespace Robust.Server
IoCManager.Resolve<IServerConsoleHost>().Initialize();
_entityManager.Startup();
IoCManager.Resolve<IEntityLookup>().Startup();
_stateManager.Initialize();
_scriptHost.Initialize();

View File

@@ -46,7 +46,7 @@ namespace Robust.Server
IoCManager.Register<IMapManagerInternal, ServerMapManager>();
IoCManager.Register<IServerMapManager, ServerMapManager>();
IoCManager.Register<IEntityManager, ServerEntityManager>();
IoCManager.Register<IEntityLookup, SharedEntityLookup>();
IoCManager.Register<IEntityLookup, EntityLookup>();
IoCManager.Register<IEntityNetworkManager, ServerEntityManager>();
IoCManager.Register<IServerEntityNetworkManager, ServerEntityManager>();
IoCManager.Register<IMapLoader, MapLoader>();

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
@@ -12,7 +14,7 @@ namespace Robust.Shared.GameObjects
{
// Not an EntitySystem given EntityManager has a dependency on it which means it's just easier to IoC it for tests.
void Initialize();
void Startup();
void Shutdown();
@@ -61,7 +63,8 @@ namespace Robust.Shared.GameObjects
Box2 GetWorldAabbFromEntity(in IEntity ent);
}
public class SharedEntityLookup : IEntityLookup, IEntityEventSubscriber
[UsedImplicitly]
public class EntityLookup : IEntityLookup, IEntityEventSubscriber
{
private readonly IEntityManager _entityManager;
private readonly IMapManager _mapManager;
@@ -69,25 +72,32 @@ namespace Robust.Shared.GameObjects
private readonly Dictionary<MapId, DynamicTree<IEntity>> _entityTreesPerMap = new();
// Using stacks so we always use latest data (given we only run it once per entity).
private Stack<MoveEvent> _moveQueue = new();
private Stack<RotateEvent> _rotateQueue = new();
private Queue<EntMapIdChangedMessage> _mapChangeQueue = new();
private readonly Stack<MoveEvent> _moveQueue = new();
private readonly Stack<RotateEvent> _rotateQueue = new();
private readonly Queue<EntMapIdChangedMessage> _mapChangeQueue = new();
/// <summary>
/// Move and rotate events generate the same update so no point duplicating work in the same tick.
/// </summary>
private HashSet<EntityUid> _handledThisTick = new();
private readonly HashSet<EntityUid> _handledThisTick = new();
// TODO: Should combine all of the methods that check for IPhysBody and just use the one GetWorldAabbFromEntity method
public SharedEntityLookup(IEntityManager entityManager, IMapManager mapManager)
public bool Started { get; private set; } = false;
public EntityLookup(IEntityManager entityManager, IMapManager mapManager)
{
_entityManager = entityManager;
_mapManager = mapManager;
}
public void Initialize()
public void Startup()
{
if (Started)
{
throw new InvalidOperationException("Startup() called multiple times.");
}
var eventBus = _entityManager.EventBus;
eventBus.SubscribeEvent<MoveEvent>(EventSource.Local, this, ev => _moveQueue.Push(ev));
eventBus.SubscribeEvent<RotateEvent>(EventSource.Local, this, ev => _rotateQueue.Push(ev));
@@ -96,15 +106,27 @@ namespace Robust.Shared.GameObjects
_entityManager.EntityStarted += HandleEntityStarted;
_mapManager.MapCreated += HandleMapCreated;
_mapManager.MapDestroyed += HandleMapDestroyed;
Started = true;
}
public void Shutdown()
{
// If we haven't even started up, there's nothing to clean up then.
if (!Started)
return;
_moveQueue.Clear();
_rotateQueue.Clear();
_handledThisTick.Clear();
_mapChangeQueue.Clear();
_entityTreesPerMap.Clear();
_entityManager.EventBus.UnsubscribeEvents(this);
_entityManager.EntityDeleted -= HandleEntityDeleted;
_entityManager.EntityStarted -= HandleEntityStarted;
_mapManager.MapCreated -= HandleMapCreated;
_mapManager.MapDestroyed -= HandleMapDestroyed;
Started = false;
}
private void HandleEntityDeleted(object? sender, EntityUid uid)

View File

@@ -73,7 +73,7 @@ namespace Robust.UnitTesting
entMan.Startup();
}
IoCManager.Resolve<IEntityLookup>().Initialize();
IoCManager.Resolve<IEntityLookup>().Startup();
var mapMan = IoCManager.Resolve<IMapManager>();
mapMan.Initialize();
mapMan.Startup();

View File

@@ -175,7 +175,7 @@ namespace Robust.UnitTesting.Server
//Tier 2: Simulation
container.Register<IEntityManager, EntityManager>();
container.Register<IMapManager, MapManager>();
container.Register<IEntityLookup, SharedEntityLookup>();
container.Register<IEntityLookup, EntityLookup>();
container.Register<ISerializationManager, SerializationManager>();
container.Register<IComponentManager, ComponentManager>();
container.Register<IPrototypeManager, PrototypeManager>();
@@ -203,9 +203,9 @@ namespace Robust.UnitTesting.Server
var entityMan = container.Resolve<IEntityManager>();
entityMan.Initialize();
IoCManager.Resolve<IEntityLookup>().Initialize();
_systemDelegate?.Invoke(container.Resolve<IEntitySystemManager>());
entityMan.Startup();
IoCManager.Resolve<IEntityLookup>().Startup();
var mapManager = container.Resolve<IMapManager>();
mapManager.Initialize();