feat: consolidate legacy parity migration baseline
This commit is contained in:
@@ -178,8 +178,9 @@ public sealed partial class MainWindow
|
||||
{
|
||||
case LegacyOperatorPlayoutCommand.Prepare:
|
||||
var request = gateAPrepareRequest ??
|
||||
_controller.CreatePlayoutRequest(
|
||||
_compositionOptions!.Current.FadeDuration);
|
||||
await CreateFreshPagedPlayoutRequestAsync(
|
||||
workflow,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
result = await workflow.PrepareAsync(
|
||||
request.Playlist,
|
||||
request.SelectedIndexZeroBased,
|
||||
@@ -190,8 +191,9 @@ public sealed partial class MainWindow
|
||||
// candidate) to m_crow and ran ONAirMode + Play, even while another
|
||||
// row was already on air. Re-read the current selection on every F8;
|
||||
// a stale explicit PREPARE must never override a later row click.
|
||||
var takeInRequest = _controller.CreatePlayoutRequest(
|
||||
_compositionOptions!.Current.FadeDuration);
|
||||
var takeInRequest = await CreateFreshPagedPlayoutRequestAsync(
|
||||
workflow,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
result = await workflow.TakeSelectedAsync(
|
||||
takeInRequest.Playlist,
|
||||
takeInRequest.SelectedIndexZeroBased,
|
||||
@@ -280,6 +282,61 @@ public sealed partial class MainWindow
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<LegacyOperatorPlayoutRequest> CreateFreshPagedPlayoutRequestAsync(
|
||||
LegacyPlayoutWorkflow workflow,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var fadeDuration = _compositionOptions!.Current.FadeDuration;
|
||||
var request = _controller.CreatePlayoutRequest(fadeDuration);
|
||||
|
||||
// The first PREPARE/TAKE IN freezes the complete playlist. Resolve every
|
||||
// operator PageN row from a fresh read-only DB preflight before that snapshot
|
||||
// is handed to the workflow. A later F8 while PREPARED/PROGRAM reuses the
|
||||
// already-frozen 1/N values and must not query a second navigation contract.
|
||||
if (workflow.State.CurrentEntryId is not null)
|
||||
{
|
||||
return request;
|
||||
}
|
||||
|
||||
var pagedEntries = request.Playlist
|
||||
.Where(static entry => entry.PageNavigation?.PageSize.HasValue == true)
|
||||
.ToArray();
|
||||
if (pagedEntries.Length == 0)
|
||||
{
|
||||
return request;
|
||||
}
|
||||
|
||||
var plans = await workflow.PreflightPagePlansAsync(
|
||||
Array.AsReadOnly(pagedEntries),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
if (plans.Count != pagedEntries.Length)
|
||||
{
|
||||
throw new LegacySceneDataException(
|
||||
"The playlist page preflight did not return every PageN entry.");
|
||||
}
|
||||
|
||||
foreach (var plan in plans)
|
||||
{
|
||||
var entry = pagedEntries.SingleOrDefault(candidate =>
|
||||
string.Equals(candidate.EntryId, plan.EntryId, StringComparison.Ordinal));
|
||||
if (entry?.PageNavigation?.PageSize is not { } expectedPageSize ||
|
||||
plan.PageSize != (int)expectedPageSize ||
|
||||
plan.PageCount is < 1 or > ScenePaging.MaximumPageCount)
|
||||
{
|
||||
throw new LegacySceneDataException(
|
||||
"The playlist page preflight does not match the operator PageN row.");
|
||||
}
|
||||
|
||||
_controller.ReflectSuccessfulPlayout(
|
||||
plan.EntryId,
|
||||
pageIndexZeroBased: 0,
|
||||
pageCount: plan.PageCount,
|
||||
synchronizeOperatorSelection: false);
|
||||
}
|
||||
|
||||
return _controller.CreatePlayoutRequest(fadeDuration);
|
||||
}
|
||||
|
||||
private async Task<LegacyOperatorSnapshot> ExecuteGateAPrepareAsync(
|
||||
string capability,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -596,9 +653,7 @@ public sealed partial class MainWindow
|
||||
}
|
||||
|
||||
private static bool IsOperatorMutationIntent(LegacyUiIntent intent) => intent is
|
||||
LegacyCutPointerDownIntent or
|
||||
LegacyCutKeyDownIntent or
|
||||
LegacyClearCutSelectionIntent or
|
||||
LegacyCutPointerDownIntent { AllowAppend: true } or
|
||||
LegacyDropSelectedCutsIntent or
|
||||
LegacySetPlaylistEnabledIntent or
|
||||
LegacySetAllPlaylistEnabledIntent or
|
||||
@@ -948,6 +1003,7 @@ public sealed partial class MainWindow
|
||||
}
|
||||
|
||||
var intentGateEntered = false;
|
||||
var databaseGateEntered = false;
|
||||
var playoutGateEntered = false;
|
||||
try
|
||||
{
|
||||
@@ -958,6 +1014,9 @@ public sealed partial class MainWindow
|
||||
_intentBusy = true;
|
||||
QueueOperatorState();
|
||||
|
||||
await AcquirePriorityDatabaseActivityAsync(token).ConfigureAwait(false);
|
||||
databaseGateEntered = true;
|
||||
|
||||
await _playoutCommandGate.WaitAsync(token).ConfigureAwait(false);
|
||||
playoutGateEntered = true;
|
||||
Interlocked.Exchange(ref _playoutBusy, 1);
|
||||
@@ -1058,6 +1117,11 @@ public sealed partial class MainWindow
|
||||
_playoutCommandGate.Release();
|
||||
}
|
||||
|
||||
if (databaseGateEntered)
|
||||
{
|
||||
_databaseActivityGate.Release();
|
||||
}
|
||||
|
||||
if (intentGateEntered)
|
||||
{
|
||||
_intentBusy = false;
|
||||
|
||||
Reference in New Issue
Block a user