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.Interfaces.Network;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Timers;
|
using Robust.Shared.Timers;
|
||||||
|
using CancellationTokenSource = System.Threading.CancellationTokenSource;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects
|
namespace Content.Server.GameObjects
|
||||||
{
|
{
|
||||||
@@ -29,6 +30,7 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
private CollidableComponent collidableComponent;
|
private CollidableComponent collidableComponent;
|
||||||
private AppearanceComponent _appearance;
|
private AppearanceComponent _appearance;
|
||||||
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
|
|
||||||
private static readonly TimeSpan CloseTime = TimeSpan.FromSeconds(1.2f);
|
private static readonly TimeSpan CloseTime = TimeSpan.FromSeconds(1.2f);
|
||||||
private static readonly TimeSpan OpenTimeOne = TimeSpan.FromSeconds(0.3f);
|
private static readonly TimeSpan OpenTimeOne = TimeSpan.FromSeconds(0.3f);
|
||||||
@@ -41,10 +43,12 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
collidableComponent = Owner.GetComponent<CollidableComponent>();
|
collidableComponent = Owner.GetComponent<CollidableComponent>();
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
_appearance = Owner.GetComponent<AppearanceComponent>();
|
||||||
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
|
_cancellationTokenSource.Cancel();
|
||||||
collidableComponent = null;
|
collidableComponent = null;
|
||||||
_appearance = 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()
|
public virtual bool CanOpen()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -124,17 +134,17 @@ namespace Content.Server.GameObjects
|
|||||||
}
|
}
|
||||||
|
|
||||||
State = DoorState.Opening;
|
State = DoorState.Opening;
|
||||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Opening);
|
SetAppearance(DoorVisualState.Opening);
|
||||||
|
|
||||||
Timer.Spawn(OpenTimeOne, async () =>
|
Timer.Spawn(OpenTimeOne, async () =>
|
||||||
{
|
{
|
||||||
collidableComponent.IsHardCollidable = false;
|
collidableComponent.IsHardCollidable = false;
|
||||||
|
|
||||||
await Timer.Delay(OpenTimeTwo);
|
await Timer.Delay(OpenTimeTwo, _cancellationTokenSource.Token);
|
||||||
|
|
||||||
State = DoorState.Open;
|
State = DoorState.Open;
|
||||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Open);
|
SetAppearance(DoorVisualState.Open);
|
||||||
});
|
}, _cancellationTokenSource.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool CanClose()
|
public virtual bool CanClose()
|
||||||
@@ -173,23 +183,23 @@ namespace Content.Server.GameObjects
|
|||||||
State = DoorState.Closing;
|
State = DoorState.Closing;
|
||||||
collidableComponent.IsHardCollidable = true;
|
collidableComponent.IsHardCollidable = true;
|
||||||
OpenTimeCounter = 0;
|
OpenTimeCounter = 0;
|
||||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Closing);
|
SetAppearance(DoorVisualState.Closing);
|
||||||
|
|
||||||
Timer.Spawn(CloseTime, () =>
|
Timer.Spawn(CloseTime, () =>
|
||||||
{
|
{
|
||||||
State = DoorState.Closed;
|
State = DoorState.Closed;
|
||||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Closed);
|
SetAppearance(DoorVisualState.Closed);
|
||||||
});
|
}, _cancellationTokenSource.Token);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Deny()
|
public virtual void Deny()
|
||||||
{
|
{
|
||||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Deny);
|
SetAppearance(DoorVisualState.Deny);
|
||||||
Timer.Spawn(DenyTime, () =>
|
Timer.Spawn(DenyTime, () =>
|
||||||
{
|
{
|
||||||
_appearance.SetData(DoorVisuals.VisualState, DoorVisualState.Closed);
|
SetAppearance(DoorVisualState.Closed);
|
||||||
});
|
}, _cancellationTokenSource.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const float AUTO_CLOSE_DELAY = 5;
|
private const float AUTO_CLOSE_DELAY = 5;
|
||||||
|
|||||||
Reference in New Issue
Block a user