mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Dirty PVS chunk when visibility mask changes (#3045)
* Dirty PVS chunk when visibility mask changes * fix tests? * aaaaaa * maybe sorta finally fix tests * directly return vis mask, Also defaults to 1 only if visibility component does not exist. * make sure everything has first bit set
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Robust.Client.GameObjects;
|
||||
|
||||
public sealed class ClientMetaDataSystem : MetaDataSystem
|
||||
{
|
||||
// Howdy.
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Robust.Server.GameStates;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Robust.Server.GameObjects;
|
||||
|
||||
public sealed class ServerMetaDataSystem : MetaDataSystem
|
||||
{
|
||||
[Dependency] private readonly PVSSystem _pvsSystem = default!;
|
||||
|
||||
public override void SetVisibilityMask(EntityUid uid, int value, MetaDataComponent? meta = null)
|
||||
{
|
||||
if (!Resolve(uid, ref meta) || meta.VisibilityMask == value)
|
||||
return;
|
||||
|
||||
base.SetVisibilityMask(uid, value, meta);
|
||||
_pvsSystem.MarkDirty(uid);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Robust.Server.GameObjects
|
||||
{
|
||||
public sealed class VisibilitySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly MetaDataSystem _metaSys = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -56,32 +59,24 @@ namespace Robust.Server.GameObjects
|
||||
|
||||
public void RefreshVisibility(EntityUid uid, MetaDataComponent? metaDataComponent = null, VisibilityComponent? visibilityComponent = null)
|
||||
{
|
||||
if (!Resolve(uid, ref metaDataComponent, false))
|
||||
{
|
||||
// This means it's deleting or some shit; I'd love to make it a GetComponent<T> in future.
|
||||
return;
|
||||
}
|
||||
|
||||
var visMask = 1;
|
||||
metaDataComponent.VisibilityMask = GetVisibilityMask(uid, ref visMask, visibilityComponent);
|
||||
if (Resolve(uid, ref metaDataComponent, false))
|
||||
_metaSys.SetVisibilityMask(uid, GetVisibilityMask(uid, visibilityComponent), metaDataComponent);
|
||||
}
|
||||
|
||||
public void RefreshVisibility(VisibilityComponent visibilityComponent)
|
||||
{
|
||||
RefreshVisibility(visibilityComponent.Owner);
|
||||
RefreshVisibility(visibilityComponent.Owner, null, visibilityComponent);
|
||||
}
|
||||
|
||||
private int GetVisibilityMask(EntityUid uid, ref int visMask, VisibilityComponent? visibilityComponent = null, TransformComponent? xform = null)
|
||||
private int GetVisibilityMask(EntityUid uid, VisibilityComponent? visibilityComponent = null, TransformComponent? xform = null)
|
||||
{
|
||||
int visMask = 1; // apparently some content expects everything to have the first bit/flag set to true.
|
||||
if (Resolve(uid, ref visibilityComponent, false))
|
||||
{
|
||||
visMask |= visibilityComponent.Layer;
|
||||
}
|
||||
|
||||
|
||||
// Include parent vis masks
|
||||
if (Resolve(uid, ref xform) && xform.ParentUid.IsValid())
|
||||
{
|
||||
GetVisibilityMask(xform.ParentUid, ref visMask);
|
||||
}
|
||||
visMask |= GetVisibilityMask(xform.ParentUid);
|
||||
|
||||
return visMask;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ namespace Robust.Server.GameStates
|
||||
|
||||
private void OnEntityAdd(EntityUid e)
|
||||
{
|
||||
DebugTools.Assert(_currentIndex == _gameTiming.CurTick.Value % DirtyBufferSize);
|
||||
DebugTools.Assert(_currentIndex == _gameTiming.CurTick.Value % DirtyBufferSize ||
|
||||
_gameTiming.GetType().Name == "IGameTimingProxy");// Look I have NFI how best to excuse this assert if the game timing isn't real (a Mock<IGameTiming>).
|
||||
_addEntities[_currentIndex].Add(e);
|
||||
}
|
||||
|
||||
|
||||
@@ -128,16 +128,25 @@ internal sealed partial class PVSSystem : EntitySystem
|
||||
|
||||
private void OnParentChange(ref EntParentChangedMessage ev)
|
||||
{
|
||||
if (_mapManager.IsGrid(ev.Entity) || _mapManager.IsMap(ev.Entity)) return;
|
||||
if (ev.Transform.GridUid == ev.Entity || _mapManager.IsMap(ev.Entity)) return;
|
||||
|
||||
// If parent changes then the RobustTree for that chunk will no longer be valid and we need to force it as dirty.
|
||||
// Should still be at its old location as moveevent is called after.
|
||||
var xform = Transform(ev.Entity);
|
||||
var coordinates = _transform.GetMoverCoordinates(xform);
|
||||
var coordinates = _transform.GetMoverCoordinates(ev.Transform);
|
||||
var index = _entityPvsCollection.GetChunkIndex(coordinates);
|
||||
_entityPvsCollection.MarkDirty(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks an entity's current chunk as drity.
|
||||
/// </summary>
|
||||
internal void MarkDirty(EntityUid uid)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
var coordinates = _transform.GetMoverCoordinates(xform);
|
||||
_entityPvsCollection.MarkDirty(_entityPvsCollection.GetChunkIndex(coordinates));
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Players;
|
||||
@@ -137,10 +138,19 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
/// <summary>
|
||||
/// The sum of our visibility layer and our parent's visibility layers.
|
||||
/// Server-only.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public int VisibilityMask { get; internal set; }
|
||||
/// <remarks>
|
||||
/// Every entity will always have the first bit set to true.
|
||||
/// </remarks>
|
||||
[Access(typeof(MetaDataSystem))]
|
||||
public int VisibilityMask = 1;
|
||||
|
||||
[UsedImplicitly, ViewVariables(VVAccess.ReadWrite)]
|
||||
private int VVVisibilityMask
|
||||
{
|
||||
get => VisibilityMask;
|
||||
set => IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<MetaDataSystem>().SetVisibilityMask(Owner, value, this);
|
||||
}
|
||||
|
||||
[ViewVariables]
|
||||
public bool EntityPaused
|
||||
|
||||
@@ -4,7 +4,7 @@ using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Robust.Shared.GameObjects;
|
||||
|
||||
public sealed class MetaDataSystem : EntitySystem
|
||||
public abstract class MetaDataSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
@@ -66,6 +66,12 @@ public sealed class MetaDataSystem : EntitySystem
|
||||
|
||||
component.Flags &= ~ev.ToRemove;
|
||||
}
|
||||
|
||||
public virtual void SetVisibilityMask(EntityUid uid, int value, MetaDataComponent? meta = null)
|
||||
{
|
||||
if (Resolve(uid, ref meta))
|
||||
meta.VisibilityMask = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameStates;
|
||||
using Robust.Server.Physics;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Containers;
|
||||
@@ -76,10 +78,22 @@ namespace Robust.UnitTesting
|
||||
|
||||
var systems = IoCManager.Resolve<IEntitySystemManager>();
|
||||
// Required systems
|
||||
systems.LoadExtraSystemType<ContainerSystem>();
|
||||
systems.LoadExtraSystemType<TransformSystem>();
|
||||
systems.LoadExtraSystemType<EntityLookupSystem>();
|
||||
systems.LoadExtraSystemType<MetaDataSystem>();
|
||||
|
||||
// uhhh so maybe these are the wrong system for the client, but I CBF adding sprite system and all the rest,
|
||||
// and it was like this when I found it.
|
||||
systems.LoadExtraSystemType<Robust.Server.Containers.ContainerSystem>();
|
||||
systems.LoadExtraSystemType<Robust.Server.GameObjects.TransformSystem>();
|
||||
|
||||
if (Project == UnitTestProject.Client)
|
||||
{
|
||||
systems.LoadExtraSystemType<ClientMetaDataSystem>();
|
||||
}
|
||||
else
|
||||
{
|
||||
systems.LoadExtraSystemType<ServerMetaDataSystem>();
|
||||
systems.LoadExtraSystemType<PVSSystem>();
|
||||
}
|
||||
|
||||
var entMan = IoCManager.Resolve<IEntityManager>();
|
||||
var mapMan = IoCManager.Resolve<IMapManager>();
|
||||
|
||||
@@ -6,7 +6,9 @@ using Moq;
|
||||
using Robust.Server;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameStates;
|
||||
using Robust.Server.Physics;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Server.Reflection;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Asynchronous;
|
||||
@@ -214,6 +216,14 @@ namespace Robust.UnitTesting.Server
|
||||
container.Register<INetManager, NetManager>();
|
||||
container.Register<IAuthManager, AuthManager>();
|
||||
|
||||
// I just wanted to load pvs system
|
||||
container.Register<IServerEntityManager, ServerEntityManager>();
|
||||
container.Register<INetConfigurationManager, NetConfigurationManager>();
|
||||
container.Register<IServerNetManager, NetManager>();
|
||||
// god help you if you actually need to test pvs functions
|
||||
container.RegisterInstance<IPlayerManager>(new Mock<IPlayerManager>().Object);
|
||||
container.RegisterInstance<IServerGameStateManager>(new Mock<IServerGameStateManager>().Object);
|
||||
|
||||
_diFactory?.Invoke(container);
|
||||
container.BuildGraph();
|
||||
|
||||
@@ -265,7 +275,8 @@ namespace Robust.UnitTesting.Server
|
||||
entitySystemMan.LoadExtraSystemType<GridFixtureSystem>();
|
||||
entitySystemMan.LoadExtraSystemType<TransformSystem>();
|
||||
entitySystemMan.LoadExtraSystemType<EntityLookupSystem>();
|
||||
entitySystemMan.LoadExtraSystemType<MetaDataSystem>();
|
||||
entitySystemMan.LoadExtraSystemType<ServerMetaDataSystem>();
|
||||
entitySystemMan.LoadExtraSystemType<PVSSystem>();
|
||||
|
||||
_systemDelegate?.Invoke(entitySystemMan);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user