Map Pausing. (#710)

You can now "pause" a map. Ideally this would result in the map not doing significant processing until unpaused.

This can be used later to code proper map editor modes that won't have any side effects while being edited.
This commit is contained in:
Pieter-Jan Briers
2018-11-27 00:32:45 +01:00
committed by GitHub
parent 1e00b864b4
commit 8397c955a8
12 changed files with 204 additions and 2 deletions

View File

@@ -49,6 +49,8 @@ namespace SS14.Client.GameObjects
Register<ClientUserInterfaceComponent>();
RegisterReference<ClientUserInterfaceComponent, SharedUserInterfaceComponent>();
RegisterIgnore("IgnorePause");
}
}
}

View File

@@ -1,6 +1,8 @@
using SS14.Server.Interfaces.Console;
using System.Globalization;
using SS14.Server.Interfaces.Console;
using SS14.Server.Interfaces.Maps;
using SS14.Server.Interfaces.Player;
using SS14.Server.Interfaces.Timing;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.Interfaces.Map;
using SS14.Shared.IoC;
@@ -147,4 +149,67 @@ namespace SS14.Server.Console.Commands
shell.SendText(player, $"MapID:{pos.MapID} GridID:{pos.GridID} X:{pos.X:N2} Y:{pos.Y:N2}");
}
}
class PauseMapCommand : IClientCommand
{
public string Command => "pausemap";
public string Description => "Pauses a map, pausing all simulation processing on it.";
public string Help => "Usage: pausemap <map ID>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var arg = args[0];
var mapId = new MapId(int.Parse(arg, CultureInfo.InvariantCulture));
var pauseManager = IoCManager.Resolve<IPauseManager>();
var mapManager = IoCManager.Resolve<IMapManager>();
if (!mapManager.MapExists(mapId))
{
shell.SendText(player, "That map does not exist.");
return;
}
pauseManager.SetMapPaused(mapId, true);
}
}
class UnpauseMapCommand : IClientCommand
{
public string Command => "unpausemap";
public string Description => "unpauses a map, resuming all simulation processing on it.";
public string Help => "Usage: unpausemap <map ID>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var arg = args[0];
var mapId = new MapId(int.Parse(arg, CultureInfo.InvariantCulture));
var pauseManager = IoCManager.Resolve<IPauseManager>();
var mapManager = IoCManager.Resolve<IMapManager>();
if (!mapManager.MapExists(mapId))
{
shell.SendText(player, "That map does not exist.");
return;
}
pauseManager.SetMapPaused(mapId, false);
}
}
class QueryMapPausedCommand : IClientCommand
{
public string Command => "querymappaused";
public string Description => "Check whether a map is paused or not.";
public string Help => "Usage: querymappaused <map ID>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var arg = args[0];
var mapId = new MapId(int.Parse(arg, CultureInfo.InvariantCulture));
var pauseManager = IoCManager.Resolve<IPauseManager>();
var mapManager = IoCManager.Resolve<IMapManager>();
if (!mapManager.MapExists(mapId))
{
shell.SendText(player, "That map does not exist.");
return;
}
shell.SendText(player, pauseManager.IsMapPaused(mapId).ToString());
}
}
}

View File

@@ -0,0 +1,9 @@
using SS14.Shared.GameObjects;
namespace SS14.Server.GameObjects.Components.Markers
{
public class IgnorePauseComponent : Component
{
public override string Name => "IgnorePause";
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using SS14.Server.AI;
using SS14.Server.GameObjects.Components;
using SS14.Server.Interfaces.Timing;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Systems;
using SS14.Shared.Interfaces.Reflection;
@@ -12,11 +13,13 @@ namespace SS14.Server.GameObjects.EntitySystems
internal class AiSystem : EntitySystem
{
private readonly Dictionary<string, Type> _processorTypes = new Dictionary<string, Type>();
private IPauseManager _pauseManager;
public AiSystem()
{
// register entity query
EntityQuery = new TypeEntityQuery(typeof(AiControllerComponent));
_pauseManager = IoCManager.Resolve<IPauseManager>();
var reflectionMan = IoCManager.Resolve<IReflectionManager>();
var processors = reflectionMan.GetAllChildren<AiLogicProcessor>();
@@ -35,6 +38,11 @@ namespace SS14.Server.GameObjects.EntitySystems
var entities = EntityManager.GetEntities(EntityQuery);
foreach (var entity in entities)
{
if (_pauseManager.IsEntityPaused(entity))
{
continue;
}
var aiComp = entity.GetComponent<AiControllerComponent>();
if (aiComp.Processor == null)
{

View File

@@ -1,8 +1,10 @@
using SS14.Server.Interfaces.Player;
using SS14.Server.Interfaces.Timing;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Systems;
using SS14.Shared.Input;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using SS14.Shared.Maths;
using SS14.Shared.Players;
@@ -10,9 +12,12 @@ namespace SS14.Server.GameObjects.EntitySystems
{
class MoverSystem : EntitySystem
{
private IPauseManager _pauseManager;
/// <inheritdoc />
public override void Initialize()
{
_pauseManager = IoCManager.Resolve<IPauseManager>();
EntityQuery = new TypeEntityQuery(typeof(PlayerInputMoverComponent));
var moveUpCmdHandler = InputCmdHandler.FromDelegate(
@@ -60,6 +65,10 @@ namespace SS14.Server.GameObjects.EntitySystems
{
foreach (var entity in RelevantEntities)
{
if (_pauseManager.IsEntityPaused(entity))
{
continue;
}
var mover = entity.GetComponent<PlayerInputMoverComponent>();
var physics = entity.GetComponent<PhysicsComponent>();

View File

@@ -1,13 +1,16 @@
using SS14.Shared.GameObjects;
using SS14.Server.Interfaces.Timing;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Systems;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using SS14.Shared.Maths;
namespace SS14.Server.GameObjects.EntitySystems
{
internal class PhysicsSystem : EntitySystem
{
private IPauseManager _pauseManager;
private const float Epsilon = 1.0e-6f;
private const float GlobalFriction = 0.01f;
@@ -16,12 +19,25 @@ namespace SS14.Server.GameObjects.EntitySystems
EntityQuery = new TypeEntityQuery(typeof(PhysicsComponent));
}
public override void Initialize()
{
base.Initialize();
_pauseManager = IoCManager.Resolve<IPauseManager>();
}
/// <inheritdoc />
public override void Update(float frameTime)
{
var entities = EntityManager.GetEntities(EntityQuery);
foreach (var entity in entities)
{
if (_pauseManager.IsEntityPaused(entity))
{
continue;
}
DoMovement(entity, frameTime);
}
}
private static void DoMovement(IEntity entity, float frameTime)

View File

@@ -1,5 +1,6 @@
using SS14.Server.GameObjects.Components;
using SS14.Server.GameObjects.Components.Container;
using SS14.Server.GameObjects.Components.Markers;
using SS14.Server.GameObjects.Components.UserInterface;
using SS14.Server.Interfaces.GameObjects;
using SS14.Shared.GameObjects;
@@ -49,6 +50,8 @@ namespace SS14.Server.GameObjects
Register<ServerUserInterfaceComponent>();
RegisterReference<ServerUserInterfaceComponent, SharedUserInterfaceComponent>();
Register<IgnorePauseComponent>();
}
}
}

View File

@@ -0,0 +1,35 @@
using JetBrains.Annotations;
using SS14.Server.GameObjects.Components.Markers;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Map;
using SS14.Shared.Map;
namespace SS14.Server.Interfaces.Timing
{
public interface IPauseManager
{
void SetMapPaused(IMap map, bool paused);
void SetMapPaused(MapId mapId, bool paused);
[Pure]
bool IsMapPaused(IMap map);
[Pure]
bool IsMapPaused(MapId mapId);
[Pure]
bool IsGridPaused(IMapGrid grid);
[Pure]
bool IsGridPaused(GridId gridId);
}
public static class PauseManagerExt
{
[Pure]
public static bool IsEntityPaused(this IPauseManager manager, IEntity entity)
{
return !entity.HasComponent<IgnorePauseComponent>() && manager.IsGridPaused(entity.Transform.GridID);
}
}
}

View File

@@ -43,7 +43,9 @@ using SS14.Shared.Interfaces.Resources;
using SS14.Server.Console;
using SS14.Server.Interfaces.Console;
using SS14.Server.Interfaces.ServerStatus;
using SS14.Server.Interfaces.Timing;
using SS14.Server.ServerStatus;
using SS14.Server.Timing;
using SS14.Server.ViewVariables;
using SS14.Shared.Asynchronous;
@@ -138,6 +140,7 @@ namespace SS14.Server
IoCManager.Register<IViewVariablesHost, ViewVariablesHost>();
IoCManager.Register<IConGroupController, ConGroupController>();
IoCManager.Register<IStatusHost, StatusHost>();
IoCManager.Register<IPauseManager, PauseManager>();
IoCManager.BuildGraph();
}

View File

@@ -121,12 +121,14 @@
<Compile Include="Console\IConGroupController.cs" />
<Compile Include="Console\SessionGroupContainer.cs" />
<Compile Include="GameObjects\Components\Appearance\AppearanceComponent.cs" />
<Compile Include="GameObjects\Components\Markers\IgnorePauseComponent.cs" />
<Compile Include="GameObjects\Components\UserInterface\ServerUserInterfaceComponent.cs" />
<Compile Include="GameObjects\EntitySystems\InputSystem.cs" />
<Compile Include="GameObjects\EntitySystems\MoverSystem.cs" />
<Compile Include="GameObjects\EntitySystems\UserInterfaceSystem.cs" />
<Compile Include="Interfaces\Player\IPlayerData.cs" />
<Compile Include="Interfaces\ServerStatus\IStatusHost.cs" />
<Compile Include="Interfaces\Timing\IPauseManager.cs" />
<Compile Include="Player\PlayerData.cs" />
<Compile Include="Prototypes\ServerPrototypeManager.cs" />
<Compile Include="Console\Commands\SpawnCommand.cs" />
@@ -151,6 +153,7 @@
<Compile Include="Console\Commands\LogCommands.cs" />
<Compile Include="ServerStatus\StatusHost.cs" />
<Compile Include="Signals.cs" />
<Compile Include="Timing\PauseManager.cs" />
<Compile Include="ViewVariables\IViewVariablesHost.cs" />
<Compile Include="ViewVariables\Traits\ViewVariablesTraitEntity.cs" />
<Compile Include="ViewVariables\Traits\ViewVariablesTraitEnumerable.cs" />

View File

@@ -0,0 +1,46 @@
using System.Collections.Generic;
using SS14.Server.Interfaces.Timing;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Map;
using SS14.Shared.IoC;
using SS14.Shared.Map;
using SS14.Shared.ViewVariables;
namespace SS14.Server.Timing
{
public class PauseManager : IPauseManager, IPostInjectInit
{
[Dependency] private IMapManager _mapManager;
[ViewVariables] private readonly HashSet<MapId> _pausedMaps = new HashSet<MapId>();
public void SetMapPaused(IMap map, bool paused) => SetMapPaused(map.Index, paused);
public void SetMapPaused(MapId mapId, bool paused)
{
if (paused)
{
_pausedMaps.Add(mapId);
}
else
{
_pausedMaps.Remove(mapId);
}
}
public bool IsMapPaused(IMap map) => IsMapPaused(map.Index);
public bool IsMapPaused(MapId mapId) => _pausedMaps.Contains(mapId);
public bool IsGridPaused(IMapGrid grid) => _pausedMaps.Contains(grid.MapID);
public bool IsGridPaused(GridId gridId)
{
var grid = _mapManager.GetGrid(gridId);
return IsGridPaused(grid);
}
public void PostInject()
{
_mapManager.MapDestroyed += (sender, args) => _pausedMaps.Remove(args.Map.Index);
}
}
}

View File

@@ -38,12 +38,14 @@ using SS14.Server.Interfaces.Maps;
using SS14.Server.Interfaces.Placement;
using SS14.Server.Interfaces.Player;
using SS14.Server.Interfaces.ServerStatus;
using SS14.Server.Interfaces.Timing;
using SS14.Server.Maps;
using SS14.Server.Placement;
using SS14.Server.Player;
using SS14.Server.Prototypes;
using SS14.Server.Reflection;
using SS14.Server.ServerStatus;
using SS14.Server.Timing;
using SS14.Server.ViewVariables;
using SS14.Shared.Asynchronous;
using SS14.Shared.Configuration;
@@ -239,6 +241,7 @@ namespace SS14.UnitTesting
IoCManager.Register<IViewVariablesHost, ViewVariablesHost>();
IoCManager.Register<IConGroupController, ConGroupController>();
IoCManager.Register<IStatusHost, StatusHost>();
IoCManager.Register<IPauseManager, PauseManager>();
break;
default: