using System; using NUnit.Framework; using Robust.Shared.GameObjects; using Robust.Shared.Reflection; using Robust.UnitTesting.Server; namespace Robust.UnitTesting.Shared.GameObjects { [TestFixture] internal sealed partial class EntityEventBusTests { [Test] public void SubscribeCompRefBroadcastEvent() { // Arrange. var simulation = RobustServerSimulation .NewSimulation() .RegisterEntitySystems(factory => factory.LoadExtraSystemType()) .InitializeInstance(); var ev = new TestStructEvent() {TestNumber = 5}; simulation.Resolve().EventBus.RaiseEvent(EventSource.Local, ref ev); Assert.That(ev.TestNumber, Is.EqualTo(15)); } [Reflect(false)] internal sealed class SubscribeCompRefBroadcastSystem : EntitySystem { public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnTestEvent); } private void OnTestEvent(ref TestStructEvent ev) { Assert.That(ev.TestNumber, Is.EqualTo(5)); ev.TestNumber += 10; } } [Test] public void SubscriptionNoMixedRefValueBroadcastEvent() { // Arrange. var simulation = RobustServerSimulation .NewSimulation() .RegisterEntitySystems(factory => factory.LoadExtraSystemType()); // Act. No mixed ref and value subscriptions are allowed. Assert.Throws(typeof(InvalidOperationException), () => simulation.InitializeInstance()); } [Reflect(false)] private sealed class SubscriptionNoMixedRefValueBroadcastEventSystem : EntitySystem { public override void Initialize() { // The below is not allowed, as you're subscribing by-ref and by-value to the same event... #pragma warning disable RA0013 SubscribeLocalEvent(MyRefHandler); SubscribeLocalEvent(MyValueHandler); #pragma warning restore RA0013 } private void MyValueHandler(TestStructEvent args) { } private void MyRefHandler(ref TestStructEvent args) { } } [Test] public void SortedBroadcastRefEvents() { // Arrange. var simulation = RobustServerSimulation .NewSimulation() .RegisterEntitySystems(factory => { factory.LoadExtraSystemType(); factory.LoadExtraSystemType(); factory.LoadExtraSystemType(); }) .InitializeInstance(); // Act. var testEvent = new TestStructEvent {TestNumber = 5}; var eventBus = simulation.Resolve().EventBus; eventBus.RaiseEvent(EventSource.Local, ref testEvent); // Check that the entity systems changed the value correctly Assert.That(testEvent.TestNumber, Is.EqualTo(15)); } [Reflect(false)] private sealed class BroadcastOrderASystem : EntitySystem { public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnA, new[]{typeof(BroadcastOrderBSystem)}, new[]{typeof(BroadcastOrderCSystem)}); } private void OnA(ref TestStructEvent args) { // Second handler being ran. Assert.That(args.TestNumber, Is.EqualTo(0)); args.TestNumber = 10; } } [Reflect(false)] private sealed class BroadcastOrderBSystem : EntitySystem { public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnB, null, new []{typeof(BroadcastOrderASystem)}); } private void OnB(ref TestStructEvent args) { // Last handler being ran. Assert.That(args.TestNumber, Is.EqualTo(10)); args.TestNumber = 15; } } [Reflect(false)] private sealed class BroadcastOrderCSystem : EntitySystem { public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnC); } private void OnC(ref TestStructEvent args) { // First handler being ran. Assert.That(args.TestNumber, Is.EqualTo(5)); args.TestNumber = 0; } } } }