Artifact analyzer now pauses on power-loss (#22974)

* Artifact analyzer now pauses on power-loss

Instead of just cancelling the current scan, the artifact analyzer
will now pause in case of power-loss.

Scanning will automatically resume when power returns.

* Improve artifact scanning pausing

This builds upon the latest improvements in artifact scanning
regarding UI update.
This commit is contained in:
Guillaume E
2023-12-30 18:49:24 +01:00
committed by GitHub
parent 3d955677c5
commit 4fe93cf456
5 changed files with 89 additions and 9 deletions

View File

@@ -23,6 +23,9 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow
// For rendering the progress bar, updated from BUI state
private TimeSpan? _startTime;
private TimeSpan? _totalTime;
private TimeSpan? _accumulatedRunTime;
private bool _paused;
public AnalysisConsoleMenu()
{
@@ -39,10 +42,15 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow
{
base.FrameUpdate(args);
if (_startTime is not { } start || _totalTime is not { } total)
if (_startTime is not { } start || _totalTime is not { } total || _accumulatedRunTime is not { } accumulated)
return;
var remaining = start + total - _timing.CurTime;
var remaining = total - accumulated;
if (!_paused)
{
// If the analyzer is running, its remaining time is further discounted by the time it's been running for.
remaining += start - _timing.CurTime;
}
var secsText = Math.Max((int) remaining.TotalSeconds, 0);
ProgressLabel.Text = Loc.GetString("analysis-console-progress-text",
@@ -89,7 +97,14 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow
if (state.Scanning)
{
message.AddMarkup(Loc.GetString("analysis-console-info-scanner"));
if (state.Paused)
{
message.AddMarkup(Loc.GetString("analysis-console-info-scanner-paused"));
}
else
{
message.AddMarkup(Loc.GetString("analysis-console-info-scanner"));
}
Information.SetMessage(message);
UpdateArtifactIcon(null); //set it to blank
return;
@@ -121,6 +136,8 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow
_startTime = state.StartTime;
_totalTime = state.TotalTime;
_accumulatedRunTime = state.AccumulatedRunTime;
_paused = state.Paused;
}
}

View File

@@ -10,11 +10,24 @@ namespace Content.Server.Xenoarchaeology.Equipment.Components;
public sealed partial class ActiveArtifactAnalyzerComponent : Component
{
/// <summary>
/// When did the scanning start?
/// When did the scanning start or last resume?
/// </summary>
[DataField("startTime", customTypeSerializer: typeof(TimespanSerializer))]
public TimeSpan StartTime;
/// <summary>
/// When pausing, this will store the duration the scan has already been running for.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan AccumulatedRunTime;
/// <summary>
/// Is analysis paused?
/// It could be when the Artifact Analyzer has no power, for example.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public bool AnalysisPaused = false;
/// <summary>
/// What is being scanned?
/// </summary>

View File

@@ -79,7 +79,10 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
var query = EntityQueryEnumerator<ActiveArtifactAnalyzerComponent, ArtifactAnalyzerComponent>();
while (query.MoveNext(out var uid, out var active, out var scan))
{
if (_timing.CurTime - active.StartTime < scan.AnalysisDuration * scan.AnalysisDurationMulitplier)
if (active.AnalysisPaused)
continue;
if (_timing.CurTime - active.StartTime < scan.AnalysisDuration * scan.AnalysisDurationMulitplier - active.AccumulatedRunTime)
continue;
FinishScan(uid, scan, active);
@@ -209,9 +212,11 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
var serverConnected = TryComp<ResearchClientComponent>(uid, out var client) && client.ConnectedToServer;
var scanning = TryComp<ActiveArtifactAnalyzerComponent>(component.AnalyzerEntity, out var active);
var paused = active != null ? active.AnalysisPaused : false;
var state = new AnalysisConsoleScanUpdateState(GetNetEntity(artifact), analyzerConnected, serverConnected,
canScan, canPrint, msg, scanning, active?.StartTime, totalTime, points);
canScan, canPrint, msg, scanning, paused, active?.StartTime, active?.AccumulatedRunTime, totalTime, points);
var bui = _ui.GetUi(uid, ArtifactAnalzyerUiKey.Key);
_ui.SetUiState(bui, state);
@@ -248,8 +253,12 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
var activeComp = EnsureComp<ActiveArtifactAnalyzerComponent>(component.AnalyzerEntity.Value);
activeComp.StartTime = _timing.CurTime;
activeComp.AccumulatedRunTime = TimeSpan.Zero;
activeComp.Artifact = ent.Value;
if (TryComp<ApcPowerReceiverComponent>(component.AnalyzerEntity.Value, out var powa))
activeComp.AnalysisPaused = !powa.Powered;
var activeArtifact = EnsureComp<ActiveScannedArtifactComponent>(ent.Value);
activeArtifact.Scanner = component.AnalyzerEntity.Value;
UpdateUserInterface(uid, component);
@@ -415,6 +424,33 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
UpdateUserInterface(component.Console.Value);
}
[PublicAPI]
public void PauseScan(EntityUid uid, ArtifactAnalyzerComponent? component = null, ActiveArtifactAnalyzerComponent? active = null)
{
if (!Resolve(uid, ref component, ref active) || active.AnalysisPaused)
return;
active.AnalysisPaused = true;
// As we pause, we store what was already completed.
active.AccumulatedRunTime = (_timing.CurTime - active.StartTime) + active.AccumulatedRunTime;
if (Exists(component.Console))
UpdateUserInterface(component.Console.Value);
}
[PublicAPI]
public void ResumeScan(EntityUid uid, ArtifactAnalyzerComponent? component = null, ActiveArtifactAnalyzerComponent? active = null)
{
if (!Resolve(uid, ref component, ref active) || !active.AnalysisPaused)
return;
active.StartTime = _timing.CurTime;
active.AnalysisPaused = false;
if (Exists(component.Console))
UpdateUserInterface(component.Console.Value);
}
private void OnRefreshParts(EntityUid uid, ArtifactAnalyzerComponent component, RefreshPartsEvent args)
{
var analysisRating = args.PartRatings[component.MachinePartAnalysisDuration];
@@ -462,10 +498,16 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
_ambientSound.SetAmbience(uid, false);
}
private void OnPowerChanged(EntityUid uid, ActiveArtifactAnalyzerComponent component, ref PowerChangedEvent args)
private void OnPowerChanged(EntityUid uid, ActiveArtifactAnalyzerComponent active, ref PowerChangedEvent args)
{
if (!args.Powered)
CancelScan(component.Artifact);
{
PauseScan(uid, null, active);
}
else
{
ResumeScan(uid, null, active);
}
}
}

View File

@@ -46,14 +46,18 @@ public sealed class AnalysisConsoleScanUpdateState : BoundUserInterfaceState
public bool Scanning;
public bool Paused;
public TimeSpan? StartTime;
public TimeSpan? AccumulatedRunTime;
public TimeSpan? TotalTime;
public int PointAmount;
public AnalysisConsoleScanUpdateState(NetEntity? artifact, bool analyzerConnected, bool serverConnected, bool canScan, bool canPrint,
FormattedMessage? scanReport, bool scanning, TimeSpan? startTime, TimeSpan? totalTime, int pointAmount)
FormattedMessage? scanReport, bool scanning, bool paused, TimeSpan? startTime, TimeSpan? accumulatedRunTime, TimeSpan? totalTime, int pointAmount)
{
Artifact = artifact;
AnalyzerConnected = analyzerConnected;
@@ -64,7 +68,10 @@ public sealed class AnalysisConsoleScanUpdateState : BoundUserInterfaceState
ScanReport = scanReport;
Scanning = scanning;
Paused = paused;
StartTime = startTime;
AccumulatedRunTime = accumulatedRunTime;
TotalTime = totalTime;
PointAmount = pointAmount;

View File

@@ -21,6 +21,7 @@ analysis-console-info-edges = EDGES: {$edges}
analysis-console-info-value = UNEXTRACTED_VALUE: {$value}
analysis-console-info-scanner = Scanning...
analysis-console-info-scanner-paused = Paused.
analysis-console-progress-text = {$seconds ->
[one] T-{$seconds} second
*[other] T-{$seconds} seconds