mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Move Component lifecycle methods to EntityManager (#4483)
This commit is contained in:
@@ -39,7 +39,7 @@ namespace Robust.Shared.Containers
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnRemove()
|
||||
protected internal override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
|
||||
|
||||
@@ -2,11 +2,8 @@ using System;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
@@ -36,7 +33,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public ComponentLifeStage LifeStage { get; private set; } = ComponentLifeStage.PreAdd;
|
||||
public ComponentLifeStage LifeStage { get; internal set; } = ComponentLifeStage.PreAdd;
|
||||
|
||||
/// <summary>
|
||||
/// If true, and if this is a networked component, then component data will only be sent to players if their
|
||||
@@ -51,93 +48,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// </summary>
|
||||
public virtual bool SessionSpecific => false;
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.PreAdd" /> to <see cref="ComponentLifeStage.Added" />,
|
||||
/// after raising a <see cref="ComponentAdd"/> event.
|
||||
/// </summary>
|
||||
internal void LifeAddToEntity(IEntityManager entManager, CompIdx type)
|
||||
{
|
||||
DebugTools.Assert(LifeStage == ComponentLifeStage.PreAdd);
|
||||
|
||||
LifeStage = ComponentLifeStage.Adding;
|
||||
CreationTick = entManager.CurrentTick;
|
||||
// networked components are assumed to be dirty when added to entities. See also: ClearTicks()
|
||||
LastModifiedTick = entManager.CurrentTick;
|
||||
entManager.EventBus.RaiseComponentEvent(this, type, CompAddInstance);
|
||||
LifeStage = ComponentLifeStage.Added;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.Added" /> to <see cref="ComponentLifeStage.Initialized" />,
|
||||
/// calling <see cref="Initialize" />.
|
||||
/// </summary>
|
||||
internal void LifeInitialize(IEntityManager entManager, CompIdx type)
|
||||
{
|
||||
DebugTools.Assert(LifeStage == ComponentLifeStage.Added);
|
||||
|
||||
LifeStage = ComponentLifeStage.Initializing;
|
||||
entManager.EventBus.RaiseComponentEvent(this, type, CompInitInstance);
|
||||
LifeStage = ComponentLifeStage.Initialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.Initialized" /> to
|
||||
/// <see cref="ComponentLifeStage.Running" />, calling <see cref="Startup" />.
|
||||
/// </summary>
|
||||
internal void LifeStartup(IEntityManager entManager)
|
||||
{
|
||||
DebugTools.Assert(LifeStage == ComponentLifeStage.Initialized);
|
||||
|
||||
LifeStage = ComponentLifeStage.Starting;
|
||||
entManager.EventBus.RaiseComponentEvent(this, CompStartupInstance);
|
||||
LifeStage = ComponentLifeStage.Running;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.Running" /> to <see cref="ComponentLifeStage.Stopped" />,
|
||||
/// calling <see cref="Shutdown" />.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Components are allowed to remove themselves in their own Startup function.
|
||||
/// </remarks>
|
||||
internal void LifeShutdown(IEntityManager entManager)
|
||||
{
|
||||
DebugTools.Assert(LifeStage is >= ComponentLifeStage.Initializing and < ComponentLifeStage.Stopping);
|
||||
|
||||
if (LifeStage <= ComponentLifeStage.Initialized)
|
||||
{
|
||||
// Component was never started, no shutdown logic necessary. Simply mark it as stopped.
|
||||
LifeStage = ComponentLifeStage.Stopped;
|
||||
return;
|
||||
}
|
||||
|
||||
LifeStage = ComponentLifeStage.Stopping;
|
||||
entManager.EventBus.RaiseComponentEvent(this, CompShutdownInstance);
|
||||
LifeStage = ComponentLifeStage.Stopped;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.Stopped" /> to <see cref="ComponentLifeStage.Deleted" />,
|
||||
/// calling <see cref="OnRemove" />.
|
||||
/// </summary>
|
||||
internal void LifeRemoveFromEntity(IEntityManager entManager)
|
||||
{
|
||||
// can be called at any time after PreAdd, including inside other life stage events.
|
||||
DebugTools.Assert(LifeStage != ComponentLifeStage.PreAdd);
|
||||
|
||||
LifeStage = ComponentLifeStage.Removing;
|
||||
entManager.EventBus.RaiseComponentEvent(this, CompRemoveInstance);
|
||||
|
||||
OnRemove();
|
||||
|
||||
#if DEBUG
|
||||
if (LifeStage != ComponentLifeStage.Deleted)
|
||||
{
|
||||
DebugTools.Assert($"Component {this.GetType().Name} did not call base {nameof(OnRemove)} in derived method.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public bool Initialized => LifeStage >= ComponentLifeStage.Initializing;
|
||||
@@ -152,24 +62,18 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public GameTick CreationTick { get; private set; }
|
||||
public GameTick CreationTick { get; internal set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public GameTick LastModifiedTick { get; internal set; }
|
||||
|
||||
private static readonly ComponentAdd CompAddInstance = new();
|
||||
private static readonly ComponentInit CompInitInstance = new();
|
||||
private static readonly ComponentStartup CompStartupInstance = new();
|
||||
private static readonly ComponentShutdown CompShutdownInstance = new();
|
||||
private static readonly ComponentRemove CompRemoveInstance = new();
|
||||
|
||||
/// <summary>
|
||||
/// Called when the component is removed from an entity.
|
||||
/// Shuts down the component.
|
||||
/// The component has already been marked as deleted in the component manager.
|
||||
/// </summary>
|
||||
protected virtual void OnRemove()
|
||||
protected internal virtual void OnRemove()
|
||||
{
|
||||
LifeStage = ComponentLifeStage.Deleted;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace Robust.Shared.GameObjects
|
||||
foreach (var comp in comps)
|
||||
{
|
||||
if (comp is { LifeStage: ComponentLifeStage.Added })
|
||||
comp.LifeInitialize(this, CompIdx.Index(comp.GetType()));
|
||||
LifeInitialize(comp, CompIdx.Index(comp.GetType()));
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
@@ -155,20 +155,20 @@ namespace Robust.Shared.GameObjects
|
||||
// Init transform first, we always have it.
|
||||
var transform = GetComponent<TransformComponent>(uid);
|
||||
if (transform.LifeStage == ComponentLifeStage.Initialized)
|
||||
transform.LifeStartup(this);
|
||||
LifeStartup(transform);
|
||||
|
||||
// Init physics second if it exists.
|
||||
if (TryGetComponent<PhysicsComponent>(uid, out var phys)
|
||||
&& phys.LifeStage == ComponentLifeStage.Initialized)
|
||||
{
|
||||
phys.LifeStartup(this);
|
||||
LifeStartup(phys);
|
||||
}
|
||||
|
||||
// Do rest of components.
|
||||
foreach (var comp in comps)
|
||||
{
|
||||
if (comp is { LifeStage: ComponentLifeStage.Initialized })
|
||||
comp.LifeStartup(this);
|
||||
LifeStartup(comp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,10 +216,10 @@ namespace Robust.Shared.GameObjects
|
||||
return;
|
||||
|
||||
if (!Comp.Initialized)
|
||||
Comp.LifeInitialize(_entMan, CompType);
|
||||
((EntityManager) _entMan).LifeInitialize(Comp, CompType);
|
||||
|
||||
if (metadata.EntityInitialized && !Comp.Running)
|
||||
Comp.LifeStartup(_entMan);
|
||||
((EntityManager) _entMan).LifeStartup(Comp);
|
||||
}
|
||||
|
||||
public static implicit operator T(CompInitializeHandle<T> handle)
|
||||
@@ -329,7 +329,7 @@ namespace Robust.Shared.GameObjects
|
||||
ComponentAdded?.Invoke(eventArgs);
|
||||
_eventBus.OnComponentAdded(eventArgs);
|
||||
|
||||
component.LifeAddToEntity(this, reg.Idx);
|
||||
LifeAddToEntity(component, reg.Idx);
|
||||
|
||||
if (skipInit)
|
||||
return;
|
||||
@@ -342,10 +342,10 @@ namespace Robust.Shared.GameObjects
|
||||
if (component.Networked)
|
||||
DirtyEntity(uid, metadata);
|
||||
|
||||
component.LifeInitialize(this, reg.Idx);
|
||||
LifeInitialize(component, reg.Idx);
|
||||
|
||||
if (metadata.EntityInitialized)
|
||||
component.LifeStartup(this);
|
||||
LifeStartup(component);
|
||||
|
||||
if (metadata.EntityLifeStage >= EntityLifeStage.MapInitialized)
|
||||
EventBus.RaiseComponentEvent(component, MapInitEventInstance);
|
||||
@@ -516,7 +516,7 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
|
||||
if (component.LifeStage >= ComponentLifeStage.Initialized && component.LifeStage <= ComponentLifeStage.Running)
|
||||
component.LifeShutdown(this);
|
||||
LifeShutdown(component);
|
||||
#if EXCEPTION_TOLERANCE
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -548,10 +548,10 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
|
||||
if (component.Running)
|
||||
component.LifeShutdown(this);
|
||||
LifeShutdown(component);
|
||||
|
||||
if (component.LifeStage != ComponentLifeStage.PreAdd)
|
||||
component.LifeRemoveFromEntity(this); // Sets delete
|
||||
LifeRemoveFromEntity(component); // Sets delete
|
||||
|
||||
#if EXCEPTION_TOLERANCE
|
||||
}
|
||||
@@ -582,11 +582,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()}");
|
||||
component.LifeShutdown(this);
|
||||
LifeShutdown(component);
|
||||
}
|
||||
|
||||
if (component.LifeStage != ComponentLifeStage.PreAdd)
|
||||
component.LifeRemoveFromEntity(this);
|
||||
LifeRemoveFromEntity(component);
|
||||
|
||||
#if EXCEPTION_TOLERANCE
|
||||
}
|
||||
|
||||
99
Robust.Shared/GameObjects/EntityManager.LifeCycle.cs
Normal file
99
Robust.Shared/GameObjects/EntityManager.LifeCycle.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Shared.GameObjects;
|
||||
|
||||
public partial class EntityManager
|
||||
{
|
||||
private static readonly ComponentAdd CompAddInstance = new();
|
||||
private static readonly ComponentInit CompInitInstance = new();
|
||||
private static readonly ComponentStartup CompStartupInstance = new();
|
||||
private static readonly ComponentShutdown CompShutdownInstance = new();
|
||||
private static readonly ComponentRemove CompRemoveInstance = new();
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.PreAdd" /> to <see cref="ComponentLifeStage.Added" />,
|
||||
/// after raising a <see cref="ComponentAdd"/> event.
|
||||
/// </summary>
|
||||
internal void LifeAddToEntity(Component component, CompIdx type)
|
||||
{
|
||||
DebugTools.Assert(component.LifeStage == ComponentLifeStage.PreAdd);
|
||||
|
||||
component.LifeStage = ComponentLifeStage.Adding;
|
||||
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);
|
||||
component.LifeStage = ComponentLifeStage.Added;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.Added" /> to <see cref="ComponentLifeStage.Initialized" />,
|
||||
/// calling <see cref="Initialize" />.
|
||||
/// </summary>
|
||||
internal void LifeInitialize(Component component, CompIdx type)
|
||||
{
|
||||
DebugTools.Assert(component.LifeStage == ComponentLifeStage.Added);
|
||||
|
||||
component.LifeStage = ComponentLifeStage.Initializing;
|
||||
EventBus.RaiseComponentEvent(component, type, CompInitInstance);
|
||||
component.LifeStage = ComponentLifeStage.Initialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.Initialized" /> to
|
||||
/// <see cref="ComponentLifeStage.Running" />, calling <see cref="Startup" />.
|
||||
/// </summary>
|
||||
internal void LifeStartup(Component component)
|
||||
{
|
||||
DebugTools.Assert(component.LifeStage == ComponentLifeStage.Initialized);
|
||||
|
||||
component.LifeStage = ComponentLifeStage.Starting;
|
||||
EventBus.RaiseComponentEvent(component, CompStartupInstance);
|
||||
component.LifeStage = ComponentLifeStage.Running;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.Running" /> to <see cref="ComponentLifeStage.Stopped" />,
|
||||
/// calling <see cref="Shutdown" />.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Components are allowed to remove themselves in their own Startup function.
|
||||
/// </remarks>
|
||||
internal void LifeShutdown(Component component)
|
||||
{
|
||||
DebugTools.Assert(component.LifeStage is >= ComponentLifeStage.Initializing and < ComponentLifeStage.Stopping);
|
||||
|
||||
if (component.LifeStage <= ComponentLifeStage.Initialized)
|
||||
{
|
||||
// Component was never started, no shutdown logic necessary. Simply mark it as stopped.
|
||||
component.LifeStage = ComponentLifeStage.Stopped;
|
||||
return;
|
||||
}
|
||||
|
||||
component.LifeStage = ComponentLifeStage.Stopping;
|
||||
EventBus.RaiseComponentEvent(component, CompShutdownInstance);
|
||||
component.LifeStage = ComponentLifeStage.Stopped;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.Stopped" /> to <see cref="ComponentLifeStage.Deleted" />,
|
||||
/// calling <see cref="Component.OnRemove" />.
|
||||
/// </summary>
|
||||
internal void LifeRemoveFromEntity(Component component)
|
||||
{
|
||||
// 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);
|
||||
|
||||
component.OnRemove();
|
||||
|
||||
#if DEBUG
|
||||
if (component.LifeStage != ComponentLifeStage.Deleted)
|
||||
{
|
||||
DebugTools.Assert($"Component {component.GetType().Name} did not call base {nameof(component.OnRemove)} in derived method.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -524,7 +524,7 @@ namespace Robust.Shared.GameObjects
|
||||
{
|
||||
try
|
||||
{
|
||||
component.LifeShutdown(this);
|
||||
LifeShutdown(component);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user