From 1de87314650b19715c502124a0dffbfd4db5fb84 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Mon, 17 Jun 2024 03:46:51 +1200 Subject: [PATCH] Reduce uses of `IComponentFactory.GetIndex(Type)` (#5242) * Update `RaiseComponentEvent` & component lifestatge methods * Fix ComponentNetworkGenerator * a * A --- RELEASE-NOTES.md | 3 +- .../Components/Renderable/SpriteComponent.cs | 4 +- .../GameStates/ClientGameStateManager.cs | 8 +- .../ComponentNetworkGenerator.cs | 2 +- .../GameObjects/ComponentEventArgs.cs | 7 +- .../GameObjects/EntityEventBus.Directed.cs | 115 ++++++++++-------- .../GameObjects/EntityManager.Components.cs | 111 ++++++++++------- .../GameObjects/EntityManager.LifeCycle.cs | 20 +-- Robust.Shared/GameObjects/EntityManager.cs | 2 +- .../GameObjects/IEntityManager.Components.cs | 4 +- .../GameObjects/Components/Container_Test.cs | 2 +- .../EntityEventBusTests.ComponentEvent.cs | 6 +- 12 files changed, 160 insertions(+), 124 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 452df952a..2b5e4f3f3 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -35,7 +35,8 @@ END TEMPLATE--> ### Breaking changes -*None yet* +* `IEventBus.RaiseComponentEvent` now requires an EntityUid argument. +* The `AddedComponentEventArgs` and `RemovedComponentEventArgs` constructors are now internal ### New features diff --git a/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs b/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs index a666e735e..a4bdcae91 100644 --- a/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs +++ b/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs @@ -1379,7 +1379,7 @@ namespace Robust.Client.GameObjects // TODO whenever sprite comp gets ECS'd , just make this a direct method call. var ev = new QueueSpriteTreeUpdateEvent(entities.GetComponent(Owner)); - entities.EventBus.RaiseComponentEvent(this, ref ev); + entities.EventBus.RaiseComponentEvent(Owner, this, ref ev); } private void QueueUpdateIsInert() @@ -1389,7 +1389,7 @@ namespace Robust.Client.GameObjects // TODO whenever sprite comp gets ECS'd , just make this a direct method call. var ev = new SpriteUpdateInertEvent(); - entities.EventBus.RaiseComponentEvent(this, ref ev); + entities.EventBus.RaiseComponentEvent(Owner, this, ref ev); } [Obsolete("Use SpriteSystem instead.")] diff --git a/Robust.Client/GameStates/ClientGameStateManager.cs b/Robust.Client/GameStates/ClientGameStateManager.cs index 5bea213d9..f1d015668 100644 --- a/Robust.Client/GameStates/ClientGameStateManager.cs +++ b/Robust.Client/GameStates/ClientGameStateManager.cs @@ -603,7 +603,7 @@ namespace Robust.Client.GameStates if (compState != null) { var handleState = new ComponentHandleState(compState, null); - _entities.EventBus.RaiseComponentEvent(comp, ref handleState); + _entities.EventBus.RaiseComponentEvent(entity, comp, ref handleState); } comp.LastModifiedTick = _timing.LastRealTick; @@ -640,7 +640,7 @@ namespace Robust.Client.GameStates if (state != null) { var stateEv = new ComponentHandleState(state, null); - _entities.EventBus.RaiseComponentEvent(comp, ref stateEv); + _entities.EventBus.RaiseComponentEvent(entity, comp, ref stateEv); } comp.ClearCreationTick(); // don't undo the re-adding. @@ -1361,7 +1361,7 @@ namespace Robust.Client.GameStates continue; var handleState = new ComponentHandleState(cur, next); - bus.RaiseComponentEvent(comp, ref handleState); + bus.RaiseComponentEvent(uid, comp, ref handleState); } } @@ -1516,7 +1516,7 @@ namespace Robust.Client.GameStates continue; var handleState = new ComponentHandleState(state, null); - _entityManager.EventBus.RaiseComponentEvent(comp, ref handleState); + _entityManager.EventBus.RaiseComponentEvent(uid, comp, ref handleState); } // ensure we don't have any extra components diff --git a/Robust.Shared.CompNetworkGenerator/ComponentNetworkGenerator.cs b/Robust.Shared.CompNetworkGenerator/ComponentNetworkGenerator.cs index 894e9369a..69cd47bed 100644 --- a/Robust.Shared.CompNetworkGenerator/ComponentNetworkGenerator.cs +++ b/Robust.Shared.CompNetworkGenerator/ComponentNetworkGenerator.cs @@ -275,7 +275,7 @@ namespace Robust.Shared.CompNetworkGenerator { eventRaise = @" var ev = new AfterAutoHandleStateEvent(args.Current); - EntityManager.EventBus.RaiseComponentEvent(component, ref ev);"; + EntityManager.EventBus.RaiseComponentEvent(uid, component, ref ev);"; } return $@"// diff --git a/Robust.Shared/GameObjects/ComponentEventArgs.cs b/Robust.Shared/GameObjects/ComponentEventArgs.cs index 367cb2570..9e97dc0b4 100644 --- a/Robust.Shared/GameObjects/ComponentEventArgs.cs +++ b/Robust.Shared/GameObjects/ComponentEventArgs.cs @@ -33,7 +33,7 @@ namespace Robust.Shared.GameObjects public readonly ComponentEventArgs BaseArgs; public readonly ComponentRegistration ComponentType; - public AddedComponentEventArgs(ComponentEventArgs baseArgs, ComponentRegistration componentType) + internal AddedComponentEventArgs(ComponentEventArgs baseArgs, ComponentRegistration componentType) { BaseArgs = baseArgs; ComponentType = componentType; @@ -48,11 +48,14 @@ namespace Robust.Shared.GameObjects public readonly MetaDataComponent Meta; - public RemovedComponentEventArgs(ComponentEventArgs baseArgs, bool terminating, MetaDataComponent meta) + public readonly CompIdx Idx; + + internal RemovedComponentEventArgs(ComponentEventArgs baseArgs, bool terminating, MetaDataComponent meta, CompIdx idx) { BaseArgs = baseArgs; Terminating = terminating; Meta = meta; + Idx = idx; } } } diff --git a/Robust.Shared/GameObjects/EntityEventBus.Directed.cs b/Robust.Shared/GameObjects/EntityEventBus.Directed.cs index f7381b70c..e20e72603 100644 --- a/Robust.Shared/GameObjects/EntityEventBus.Directed.cs +++ b/Robust.Shared/GameObjects/EntityEventBus.Directed.cs @@ -69,39 +69,29 @@ namespace Robust.Shared.GameObjects /// DO NOT USE THIS IN CONTENT UNLESS YOU KNOW WHAT YOU'RE DOING, the only reason it's not internal /// is because of the component network source generator. /// - /// Event to dispatch. - /// Component receiving the event. - /// Event arguments for the event. - public void RaiseComponentEvent(IComponent component, TEvent args) + public void RaiseComponentEvent(EntityUid uid, TComponent component, TEvent args) + where TEvent : notnull + where TComponent : IComponent; + + /// + public void RaiseComponentEvent(EntityUid uid, IComponent component, TEvent args) where TEvent : notnull; - /// - /// Dispatches an event directly to a specific component. - /// - /// - /// This has a very specific purpose, and has massive potential to be abused. - /// DO NOT USE THIS IN CONTENT UNLESS YOU KNOW WHAT YOU'RE DOING, the only reason it's not internal - /// is because of the component network source generator. - /// - /// Event to dispatch. - /// Component receiving the event. - /// Type of the component, for faster lookups. - /// Event arguments for the event. - public void RaiseComponentEvent(IComponent component, CompIdx idx, TEvent args) + /// + public void RaiseComponentEvent(EntityUid uid, IComponent component, CompIdx idx, TEvent args) where TEvent : notnull; - /// - /// Dispatches an event directly to a specific component, by-ref. - /// - /// - /// This has a very specific purpose, and has massive potential to be abused. - /// DO NOT USE THIS IN CONTENT UNLESS YOU KNOW WHAT YOU'RE DOING, the only reason it's not internal - /// is because of the component network source generator. - /// - /// Event to dispatch. - /// Component receiving the event. - /// Event arguments for the event. - public void RaiseComponentEvent(IComponent component, ref TEvent args) + /// + public void RaiseComponentEvent(EntityUid uid, IComponent component, ref TEvent args) + where TEvent : notnull; + + /// + public void RaiseComponentEvent(EntityUid uid, TComponent component, ref TEvent args) + where TEvent : notnull + where TComponent : IComponent; + + /// + public void RaiseComponentEvent(EntityUid uid, IComponent component, CompIdx idx, ref TEvent args) where TEvent : notnull; public void OnlyCallOnRobustUnitTestISwearToGodPleaseSomebodyKillThisNightmare(); @@ -140,37 +130,58 @@ namespace Robust.Shared.GameObjects } /// - void IDirectedEventBus.RaiseComponentEvent(IComponent component, TEvent args) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RaiseComponentEvent(EntityUid uid, IComponent component, TEvent args) + where TEvent : notnull { - ref var unitRef = ref Unsafe.As(ref args); - - DispatchComponent( - component.Owner, - component, - _comFac.GetIndex(component.GetType()), - ref unitRef); - } - - void IDirectedEventBus.RaiseComponentEvent(IComponent component, CompIdx type, TEvent args) - { - ref var unitRef = ref Unsafe.As(ref args); - - DispatchComponent( - component.Owner, - component, - type, - ref unitRef); + RaiseComponentEvent(uid, component, _comFac.GetIndex(component.GetType()), ref args); } /// - void IDirectedEventBus.RaiseComponentEvent(IComponent component, ref TEvent args) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RaiseComponentEvent(EntityUid uid, TComponent component, TEvent args) + where TEvent : notnull + where TComponent : IComponent + { + RaiseComponentEvent(uid, component, CompIdx.Index(), ref args); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RaiseComponentEvent(EntityUid uid, IComponent component, CompIdx type, TEvent args) + where TEvent : notnull + { + RaiseComponentEvent(uid, component, type, ref args); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RaiseComponentEvent(EntityUid uid, IComponent component, ref TEvent args) + where TEvent : notnull + { + RaiseComponentEvent(uid, component, _comFac.GetIndex(component.GetType()), ref args); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RaiseComponentEvent(EntityUid uid, TComponent component, ref TEvent args) + where TEvent : notnull + where TComponent : IComponent + { + RaiseComponentEvent(uid, component, CompIdx.Index(), ref args); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RaiseComponentEvent(EntityUid uid, IComponent component, CompIdx type, ref TEvent args) + where TEvent : notnull { ref var unitRef = ref Unsafe.As(ref args); DispatchComponent( - component.Owner, + uid, component, - _comFac.GetIndex(component.GetType()), + type, ref unitRef); } @@ -399,7 +410,7 @@ namespace Robust.Shared.GameObjects public void OnComponentRemoved(in RemovedComponentEventArgs e) { - EntRemoveComponent(e.BaseArgs.Owner, _comFac.GetIndex(e.BaseArgs.Component.GetType())); + EntRemoveComponent(e.BaseArgs.Owner, e.Idx); } private void EntAddSubscription( diff --git a/Robust.Shared/GameObjects/EntityManager.Components.cs b/Robust.Shared/GameObjects/EntityManager.Components.cs index d71c8a57d..35d911c0c 100644 --- a/Robust.Shared/GameObjects/EntityManager.Components.cs +++ b/Robust.Shared/GameObjects/EntityManager.Components.cs @@ -125,8 +125,8 @@ namespace Robust.Shared.GameObjects foreach (var comp in comps) { - if (comp is { LifeStage: ComponentLifeStage.Added }) - LifeInitialize(comp, _componentFactory.GetIndex(comp.GetType())); + if (comp is {LifeStage: ComponentLifeStage.Added}) + LifeInitialize(uid, comp, _componentFactory.GetIndex(comp.GetType())); } #if DEBUG @@ -159,19 +159,19 @@ namespace Robust.Shared.GameObjects // Init transform first, we always have it. var transform = TransformQuery.GetComponent(uid); if (transform.LifeStage == ComponentLifeStage.Initialized) - LifeStartup(transform); + LifeStartup(uid, transform, CompIdx.Index()); // Init physics second if it exists. if (_physicsQuery.TryComp(uid, out var phys) && phys.LifeStage == ComponentLifeStage.Initialized) { - LifeStartup(phys); + LifeStartup(uid, phys, CompIdx.Index()); } // Do rest of components. foreach (var comp in comps) { if (comp is { LifeStage: ComponentLifeStage.Initialized }) - LifeStartup(comp); + LifeStartup(uid, comp, _componentFactory.GetIndex(comp.GetType())); } } @@ -267,10 +267,10 @@ namespace Robust.Shared.GameObjects return; if (!Comp.Initialized) - ((EntityManager) _entMan).LifeInitialize(Comp, CompType); + ((EntityManager) _entMan).LifeInitialize(_owner, Comp, CompType); if (metadata.EntityInitialized && !Comp.Running) - ((EntityManager) _entMan).LifeStartup(Comp); + ((EntityManager) _entMan).LifeStartup(_owner, Comp, CompType); } public static implicit operator T(CompInitializeHandle handle) @@ -355,7 +355,7 @@ namespace Robust.Shared.GameObjects // This will invalidate the comp ref as it removes the key from the dictionary. // This is inefficient, but component overriding rarely ever happens. - RemoveComponentImmediate(comp!, uid, false, metadata); + RemoveComponentImmediate(uid, comp!, type, false, metadata); dict.Add(uid, component); } else @@ -382,7 +382,7 @@ namespace Robust.Shared.GameObjects ComponentAdded?.Invoke(eventArgs); _eventBus.OnComponentAdded(eventArgs); - LifeAddToEntity(component, reg.Idx); + LifeAddToEntity(uid, component, reg.Idx); if (skipInit) return; @@ -395,20 +395,24 @@ namespace Robust.Shared.GameObjects if (component.Networked) DirtyEntity(uid, metadata); - LifeInitialize(component, reg.Idx); + LifeInitialize(uid, component, reg.Idx); if (metadata.EntityInitialized) - LifeStartup(component); + LifeStartup(uid, component, reg.Idx); if (metadata.EntityLifeStage >= EntityLifeStage.MapInitialized) - EventBus.RaiseComponentEvent(component, MapInitEventInstance); + EventBus.RaiseComponentEvent(uid, component, reg.Idx, MapInitEventInstance); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool RemoveComponent(EntityUid uid, MetaDataComponent? meta = null) + public bool RemoveComponent(EntityUid uid, MetaDataComponent? meta = null) where T : IComponent { - return RemoveComponent(uid, typeof(T), meta); + if (!TryGetComponent(uid, out T? comp)) + return false; + + RemoveComponentImmediate(uid, comp, CompIdx.Index(), false, meta); + return true; } /// @@ -418,7 +422,7 @@ namespace Robust.Shared.GameObjects if (!TryGetComponent(uid, type, out var comp)) return false; - RemoveComponentImmediate(comp, uid, false, meta); + RemoveComponentImmediate(uid, comp, _componentFactory.GetIndex(type), false, meta); return true; } @@ -432,7 +436,8 @@ namespace Robust.Shared.GameObjects if (!TryGetComponent(uid, netId, out var comp, meta)) return false; - RemoveComponentImmediate(comp, uid, false, meta); + var idx = _componentFactory.GetIndex(comp.GetType()); + RemoveComponentImmediate(uid, comp, idx, false, meta); return true; } @@ -440,7 +445,8 @@ namespace Robust.Shared.GameObjects [MethodImpl(MethodImplOptions.AggressiveInlining)] public void RemoveComponent(EntityUid uid, IComponent component, MetaDataComponent? meta = null) { - RemoveComponentImmediate(component, uid, false, meta); + var idx = _componentFactory.GetIndex(component.GetType()); + RemoveComponentImmediate(uid, component, idx, false, meta); } /// @@ -510,7 +516,8 @@ namespace Robust.Shared.GameObjects foreach (var comp in InSafeOrder(_entCompIndex[uid])) { - RemoveComponentImmediate(comp, uid, false, meta); + var idx = _componentFactory.GetIndex(comp.GetType()); + RemoveComponentImmediate(uid, comp, idx, false, meta); } } @@ -524,7 +531,8 @@ namespace Robust.Shared.GameObjects { try { - RemoveComponentImmediate(comp, uid, true, meta); + var idx = _componentFactory.GetIndex(comp.GetType()); + RemoveComponentImmediate(uid, comp, idx, true, meta); } catch (Exception) { @@ -537,14 +545,16 @@ namespace Robust.Shared.GameObjects private void RemoveComponentDeferred(IComponent component, EntityUid uid, bool terminating) { - if (component == null) throw new ArgumentNullException(nameof(component)); + if (component == null) + throw new ArgumentNullException(nameof(component)); #pragma warning disable CS0618 // Type or member is obsolete if (component.Owner != uid) #pragma warning restore CS0618 // Type or member is obsolete throw new InvalidOperationException("Component is not owned by entity."); - if (component.Deleted) return; + if (component.Deleted) + return; #if EXCEPTION_TOLERANCE try @@ -564,7 +574,7 @@ namespace Robust.Shared.GameObjects } if (component.LifeStage >= ComponentLifeStage.Initialized && component.LifeStage <= ComponentLifeStage.Running) - LifeShutdown(component); + LifeShutdown(uid, component, _componentFactory.GetIndex(component.GetType())); #if EXCEPTION_TOLERANCE } catch (Exception e) @@ -575,7 +585,11 @@ namespace Robust.Shared.GameObjects #endif } - private void RemoveComponentImmediate(IComponent component, EntityUid uid, bool terminating, + private void RemoveComponentImmediate( + EntityUid uid, + IComponent component, + CompIdx idx, + bool terminating, MetaDataComponent? meta) { if (component.Deleted) @@ -596,10 +610,10 @@ namespace Robust.Shared.GameObjects } if (component.Running) - LifeShutdown(component); + LifeShutdown(uid, component, idx); if (component.LifeStage != ComponentLifeStage.PreAdd) - LifeRemoveFromEntity(component); // Sets delete + LifeRemoveFromEntity(uid, component, idx); // Sets delete #if EXCEPTION_TOLERANCE } @@ -609,7 +623,7 @@ namespace Robust.Shared.GameObjects _runtimeLog.LogException(e, nameof(RemoveComponentImmediate)); } #endif - DeleteComponent(uid, component, terminating, meta); + DeleteComponent(uid, component, idx, terminating, meta); } /// @@ -620,6 +634,7 @@ namespace Robust.Shared.GameObjects if (component.Deleted) continue; var uid = component.Owner; + var idx = _componentFactory.GetIndex(component.GetType()); #if EXCEPTION_TOLERANCE try @@ -630,11 +645,11 @@ namespace Robust.Shared.GameObjects { // TODO add options to cancel deferred deletion? _sawmill.Warning($"Found a running component while culling deferred deletions, owner={ToPrettyString(uid)}, type={component.GetType()}"); - LifeShutdown(component); + LifeShutdown(uid, component, idx); } if (component.LifeStage != ComponentLifeStage.PreAdd) - LifeRemoveFromEntity(component); + LifeRemoveFromEntity(uid, component, idx); #if EXCEPTION_TOLERANCE } @@ -645,43 +660,49 @@ namespace Robust.Shared.GameObjects } #endif var meta = MetaQuery.GetComponent(uid); - DeleteComponent(uid, component, false, meta); + DeleteComponent(uid, component, idx, false, meta); } _deleteSet.Clear(); } - private void DeleteComponent(EntityUid entityUid, IComponent component, bool terminating, MetaDataComponent? metadata) + private void DeleteComponent( + EntityUid entityUid, + IComponent component, + CompIdx idx, + bool terminating, + MetaDataComponent? metadata) { if (!MetaQuery.ResolveInternal(entityUid, ref metadata)) return; - var eventArgs = new RemovedComponentEventArgs(new ComponentEventArgs(component, entityUid), false, metadata); + var eventArgs = new RemovedComponentEventArgs(new ComponentEventArgs(component, entityUid), false, metadata, idx); ComponentRemoved?.Invoke(eventArgs); _eventBus.OnComponentRemoved(eventArgs); - var reg = _componentFactory.GetRegistration(component); - DebugTools.Assert(component.Networked == (reg.NetID != null)); - - if (!terminating && reg.NetID != null) + if (!terminating) { - if (!metadata.NetComponents.Remove(reg.NetID.Value)) - _sawmill.Error($"Entity {ToPrettyString(entityUid, metadata)} did not have {component.GetType().Name} in its networked component dictionary during component deletion."); - - if (component.NetSyncEnabled) + var reg = _componentFactory.GetRegistration(component); + DebugTools.Assert(component.Networked == (reg.NetID != null)); + if (reg.NetID != null) { - DirtyEntity(entityUid, metadata); - metadata.LastComponentRemoved = _gameTiming.CurTick; + if (!metadata.NetComponents.Remove(reg.NetID.Value)) + _sawmill.Error($"Entity {ToPrettyString(entityUid, metadata)} did not have {component.GetType().Name} in its networked component dictionary during component deletion."); + + if (component.NetSyncEnabled) + { + DirtyEntity(entityUid, metadata); + metadata.LastComponentRemoved = _gameTiming.CurTick; + } } } - _entTraitArray[reg.Idx.Value].Remove(entityUid); + _entTraitArray[idx.Value].Remove(entityUid); // TODO if terminating the entity, maybe defer this? // _entCompIndex.Remove(uid) gets called later on anyways. _entCompIndex.Remove(entityUid, component); - DebugTools.Assert(_netMan.IsClient // Client side prediction can set LastComponentRemoved to some future tick, || metadata.EntityLastModifiedTick >= metadata.LastComponentRemoved); } @@ -1407,7 +1428,7 @@ namespace Robust.Shared.GameObjects { DebugTools.Assert(component.NetSyncEnabled, $"Attempting to get component state for an un-synced component: {component.GetType()}"); var getState = new ComponentGetState(session, fromTick); - eventBus.RaiseComponentEvent(component, ref getState); + eventBus.RaiseComponentEvent(component.Owner, component, ref getState); return getState.State; } @@ -1415,7 +1436,7 @@ namespace Robust.Shared.GameObjects public bool CanGetComponentState(IEventBus eventBus, IComponent component, ICommonSession player) { var attempt = new ComponentGetStateAttemptEvent(player); - eventBus.RaiseComponentEvent(component, ref attempt); + eventBus.RaiseComponentEvent(component.Owner, component, ref attempt); return !attempt.Cancelled; } diff --git a/Robust.Shared/GameObjects/EntityManager.LifeCycle.cs b/Robust.Shared/GameObjects/EntityManager.LifeCycle.cs index 226be0279..811910964 100644 --- a/Robust.Shared/GameObjects/EntityManager.LifeCycle.cs +++ b/Robust.Shared/GameObjects/EntityManager.LifeCycle.cs @@ -14,7 +14,7 @@ public partial class EntityManager /// Increases the life stage from to , /// after raising a event. /// - internal void LifeAddToEntity(IComponent component, CompIdx type) + internal void LifeAddToEntity(EntityUid uid, IComponent component, CompIdx idx) { DebugTools.Assert(component.LifeStage == ComponentLifeStage.PreAdd); @@ -23,7 +23,7 @@ public partial class EntityManager component.CreationTick = CurrentTick; // networked components are assumed to be dirty when added to entities. See also: ClearTicks() component.LastModifiedTick = CurrentTick; - EventBus.RaiseComponentEvent(component, type, CompAddInstance); + EventBus.RaiseComponentEvent(uid, component, idx, CompAddInstance); component.LifeStage = ComponentLifeStage.Added; #pragma warning restore CS0618 // Type or member is obsolete } @@ -32,12 +32,12 @@ public partial class EntityManager /// Increases the life stage from to , /// calling . /// - internal void LifeInitialize(IComponent component, CompIdx type) + internal void LifeInitialize(EntityUid uid, IComponent component, CompIdx idx) { DebugTools.Assert(component.LifeStage == ComponentLifeStage.Added); component.LifeStage = ComponentLifeStage.Initializing; - EventBus.RaiseComponentEvent(component, type, CompInitInstance); + EventBus.RaiseComponentEvent(uid, component, idx, CompInitInstance); component.LifeStage = ComponentLifeStage.Initialized; } @@ -45,12 +45,12 @@ public partial class EntityManager /// Increases the life stage from to /// , calling . /// - internal void LifeStartup(IComponent component) + internal void LifeStartup(EntityUid uid, IComponent component, CompIdx idx) { DebugTools.Assert(component.LifeStage == ComponentLifeStage.Initialized); component.LifeStage = ComponentLifeStage.Starting; - EventBus.RaiseComponentEvent(component, CompStartupInstance); + EventBus.RaiseComponentEvent(uid, component, idx, CompStartupInstance); component.LifeStage = ComponentLifeStage.Running; } @@ -61,7 +61,7 @@ public partial class EntityManager /// /// Components are allowed to remove themselves in their own Startup function. /// - internal void LifeShutdown(IComponent component) + internal void LifeShutdown(EntityUid uid, IComponent component, CompIdx idx) { DebugTools.Assert(component.LifeStage is >= ComponentLifeStage.Initializing and < ComponentLifeStage.Stopping); @@ -73,7 +73,7 @@ public partial class EntityManager } component.LifeStage = ComponentLifeStage.Stopping; - EventBus.RaiseComponentEvent(component, CompShutdownInstance); + EventBus.RaiseComponentEvent(uid, component, idx, CompShutdownInstance); component.LifeStage = ComponentLifeStage.Stopped; } @@ -81,13 +81,13 @@ public partial class EntityManager /// Increases the life stage from to , /// calling . /// - internal void LifeRemoveFromEntity(IComponent component) + internal void LifeRemoveFromEntity(EntityUid uid, IComponent component, CompIdx idx) { // can be called at any time after PreAdd, including inside other life stage events. DebugTools.Assert(component.LifeStage != ComponentLifeStage.PreAdd); component.LifeStage = ComponentLifeStage.Removing; - EventBus.RaiseComponentEvent(component, CompRemoveInstance); + EventBus.RaiseComponentEvent(uid, component, idx, CompRemoveInstance); component.LifeStage = ComponentLifeStage.Deleted; } diff --git a/Robust.Shared/GameObjects/EntityManager.cs b/Robust.Shared/GameObjects/EntityManager.cs index 6146f94ab..79f5f7ab2 100644 --- a/Robust.Shared/GameObjects/EntityManager.cs +++ b/Robust.Shared/GameObjects/EntityManager.cs @@ -586,7 +586,7 @@ namespace Robust.Shared.GameObjects { try { - LifeShutdown(component); + LifeShutdown(uid, component, _componentFactory.GetIndex(component.GetType())); } catch (Exception e) { diff --git a/Robust.Shared/GameObjects/IEntityManager.Components.cs b/Robust.Shared/GameObjects/IEntityManager.Components.cs index 5fc1e6616..8e23583c2 100644 --- a/Robust.Shared/GameObjects/IEntityManager.Components.cs +++ b/Robust.Shared/GameObjects/IEntityManager.Components.cs @@ -100,7 +100,7 @@ namespace Robust.Shared.GameObjects /// /// The component reference type to remove. /// Entity UID to modify. - bool RemoveComponent(EntityUid uid, MetaDataComponent? meta = null); + bool RemoveComponent(EntityUid uid, MetaDataComponent? meta = null) where T : IComponent; /// /// Removes the component with a specified type. @@ -294,7 +294,7 @@ namespace Robust.Shared.GameObjects /// Entity UID to check. /// Component of the specified type (if exists). /// If the component existed in the entity. - bool TryGetComponent(EntityUid uid, [NotNullWhen(true)] out T? component) where T : IComponent?; + bool TryGetComponent(EntityUid uid, [NotNullWhen(true)] out T? component) where T : IComponent?; /// /// Returns the component of a specific type. diff --git a/Robust.UnitTesting/Server/GameObjects/Components/Container_Test.cs b/Robust.UnitTesting/Server/GameObjects/Components/Container_Test.cs index 434ec44fd..80191f52c 100644 --- a/Robust.UnitTesting/Server/GameObjects/Components/Container_Test.cs +++ b/Robust.UnitTesting/Server/GameObjects/Components/Container_Test.cs @@ -267,7 +267,7 @@ namespace Robust.UnitTesting.Server.GameObjects.Components var containerMan = entManager.GetComponent(entity); var getState = new ComponentGetState(); - entManager.EventBus.RaiseComponentEvent(containerMan, ref getState); + entManager.EventBus.RaiseComponentEvent(entity, containerMan, ref getState); var state = (ContainerManagerComponent.ContainerManagerComponentState)getState.State!; Assert.That(state.Containers, Has.Count.EqualTo(1)); diff --git a/Robust.UnitTesting/Shared/GameObjects/EntityEventBusTests.ComponentEvent.cs b/Robust.UnitTesting/Shared/GameObjects/EntityEventBusTests.ComponentEvent.cs index 594f13a55..acd2f0a3d 100644 --- a/Robust.UnitTesting/Shared/GameObjects/EntityEventBusTests.ComponentEvent.cs +++ b/Robust.UnitTesting/Shared/GameObjects/EntityEventBusTests.ComponentEvent.cs @@ -169,7 +169,7 @@ namespace Robust.UnitTesting.Shared.GameObjects entManMock.Raise(m => m.ComponentAdded += null, new AddedComponentEventArgs(new ComponentEventArgs(compInstance, entUid), reg)); // Raise - ((IEventBus)bus).RaiseComponentEvent(compInstance, new ComponentInit()); + ((IEventBus)bus).RaiseComponentEvent(entUid, compInstance, new ComponentInit()); // Assert Assert.That(calledCount, Is.EqualTo(1)); @@ -310,7 +310,7 @@ namespace Robust.UnitTesting.Shared.GameObjects handlerACount++; // add and then remove component B - bus.OnComponentRemoved(new RemovedComponentEventArgs(new ComponentEventArgs(instB, entUid), false, default!)); + bus.OnComponentRemoved(new RemovedComponentEventArgs(new ComponentEventArgs(instB, entUid), false, default!, CompIdx.Index())); bus.OnComponentAdded(new AddedComponentEventArgs(new ComponentEventArgs(instB, entUid), regB)); } @@ -321,7 +321,7 @@ namespace Robust.UnitTesting.Shared.GameObjects handlerBCount++; // add and then remove component A - bus.OnComponentRemoved(new RemovedComponentEventArgs(new ComponentEventArgs(instA, entUid), false, default!)); + bus.OnComponentRemoved(new RemovedComponentEventArgs(new ComponentEventArgs(instA, entUid), false, default!, CompIdx.Index())); bus.OnComponentAdded(new AddedComponentEventArgs(new ComponentEventArgs(instA, entUid), regA)); }