Fix crash on restart when a Airlock is opening/closing (#481)
* Fix crash when _appearance is null Added a function to error check and set _appearance.SetData. Added cancellation token which should stop the Timer, but doesn't seem to right now. * Fix missing CancellationToken causing a crash This delay would delay _appearance.SetData until after _apppearance was set to null when the component was removed causing a null reference exception.
This commit is contained in:
committed by
Pieter-Jan Briers
parent
4265fac7b8
commit
adaf0ade52
@@ -8,6 +8,7 @@ using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timers;
|
||||
using CancellationTokenSource = System.Threading.CancellationTokenSource;
|
||||
|
||||
namespace Content.Server.GameObjects
|
||||
{
|
||||
@@ -29,6 +30,7 @@ namespace Content.Server.GameObjects
|
||||
|
||||
private CollidableComponent collidableComponent;
|
||||
private AppearanceComponent _appearance;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
private static readonly TimeSpan CloseTime = TimeSpan.FromSeconds(1.2f);
|
||||
private static readonly TimeSpan OpenTimeOne = TimeSpan.FromSeconds(0.3f);
|
||||
@@ -41,10 +43,12 @@ namespace Content.Server.GameObjects
|
||||
|
||||
collidableComponent = Owner.GetComponent<CollidableComponent>();
|
||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
collidableComponent = null;
|
||||
_appearance = null;
|
||||
|
||||
@@ -91,6 +95,12 @@ namespace Content.Server.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
private void SetAppearance(DoorVisualState state)
|
||||
{
|
||||
if (_appearance != null || Owner.TryGetComponent(out _appearance))
|
||||
_appearance.SetData(DoorVisuals.VisualState, state);
|
||||
}
|
||||
|
||||
public virtual bool CanOpen()
|
||||
{
|
||||
return true;
|
||||
@@ -124,17 +134,17 @@ namespace Content.Server.GameObjects
|
||||
}
|
||||
|
||||
State = DoorState.Opening;
|
||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Opening);
|
||||
SetAppearance(DoorVisualState.Opening);
|
||||
|
||||
Timer.Spawn(OpenTimeOne, async () =>
|
||||
{
|
||||
collidableComponent.IsHardCollidable = false;
|
||||
|
||||
await Timer.Delay(OpenTimeTwo);
|
||||
await Timer.Delay(OpenTimeTwo, _cancellationTokenSource.Token);
|
||||
|
||||
State = DoorState.Open;
|
||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Open);
|
||||
});
|
||||
SetAppearance(DoorVisualState.Open);
|
||||
}, _cancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
public virtual bool CanClose()
|
||||
@@ -173,23 +183,23 @@ namespace Content.Server.GameObjects
|
||||
State = DoorState.Closing;
|
||||
collidableComponent.IsHardCollidable = true;
|
||||
OpenTimeCounter = 0;
|
||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Closing);
|
||||
SetAppearance(DoorVisualState.Closing);
|
||||
|
||||
Timer.Spawn(CloseTime, () =>
|
||||
{
|
||||
State = DoorState.Closed;
|
||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Closed);
|
||||
});
|
||||
SetAppearance(DoorVisualState.Closed);
|
||||
}, _cancellationTokenSource.Token);
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Deny()
|
||||
{
|
||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Deny);
|
||||
SetAppearance(DoorVisualState.Deny);
|
||||
Timer.Spawn(DenyTime, () =>
|
||||
{
|
||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Closed);
|
||||
});
|
||||
SetAppearance(DoorVisualState.Closed);
|
||||
}, _cancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
private const float AUTO_CLOSE_DELAY = 5;
|
||||
|
||||
Reference in New Issue
Block a user