using System.Collections.Generic; using NUnit.Framework; using Robust.Shared.GameObjects; using Robust.Shared.Map; using Robust.Shared.Reflection; using Robust.UnitTesting.Server; namespace Robust.UnitTesting.Shared.GameObjects; internal sealed partial class EntityEventBusTests { // Explanation of what bug this is testing: // Because event ordering is keyed on system type, we have a problem. // If you register to a directed event like FooEvent twice for different components, // you now have different subscriptions with the same key. // // To trigger this, at least one subscription to this event (possibly another system entirely) // needs to demand some ordering calculation to happen. [Test] public void TestDifferentComponentsOrderedSameKeySub() { var simulation = RobustServerSimulation .NewSimulation() .RegisterEntitySystems(factory => { factory.LoadExtraSystemType(); factory.LoadExtraSystemType(); }) .RegisterComponents(factory => factory.RegisterClass()) .InitializeInstance(); var map = simulation.CreateMap().MapId; var entMan = simulation.Resolve(); var entity = entMan.Spawn(null, new MapCoordinates(0, 0, map)); entMan.AddComponent(entity); var foo = new FooEvent(); entMan.EventBus.RaiseLocalEvent(entity, foo, true); Assert.That(foo.EventOrder, Is.EquivalentTo(new[]{"Foo", "Transform", "Metadata"}).Or.EquivalentTo(new[]{"Foo", "Metadata", "Transform"})); } [Reflect(false)] private sealed class DifferentComponentsSameKeySubSystem : EntitySystem { public override void Initialize() { SubscribeLocalEvent((_, _, e) => { e.EventOrder.Add("Transform"); }); SubscribeLocalEvent((_, _, e) => { e.EventOrder.Add("Metadata"); }); } } [Reflect(false)] private sealed class DifferentComponentsSameKeySubSystem2 : EntitySystem { public override void Initialize() { SubscribeLocalEvent( (_, _, e) => e.EventOrder.Add("Foo"), before: new[] {typeof(DifferentComponentsSameKeySubSystem)}); } } [Reflect(false)] private sealed partial class FooComponent : Component { } private sealed class FooEvent { public List EventOrder = new(); } }