Restart schedule from bottom active item
This commit is contained in:
@@ -26,6 +26,7 @@ public sealed class ChannelScheduleEngine
|
||||
private TaskCompletionSource<bool>? _advanceSignal;
|
||||
private Guid? _lastPlaybackItemId;
|
||||
private Guid? _skipCurrentItemId;
|
||||
private Guid? _restartFromTopAfterItemId;
|
||||
private ChannelScheduleItem? _directPlaybackItem;
|
||||
private PreparedCutFrame? _preparedCutFrame;
|
||||
|
||||
@@ -77,6 +78,12 @@ public sealed class ChannelScheduleEngine
|
||||
{
|
||||
if (IsRunning)
|
||||
{
|
||||
if (GetNextPlayableItem() is null)
|
||||
{
|
||||
await RestartFromTopAsync().ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await AdvanceToNextAsync().ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
@@ -87,7 +94,10 @@ public sealed class ChannelScheduleEngine
|
||||
}
|
||||
|
||||
_lastPlaybackItemId = null;
|
||||
_skipCurrentItemId = null;
|
||||
_restartFromTopAfterItemId = null;
|
||||
ResetDataUnavailableItems();
|
||||
ClearStalePlaybackStatesBeforeStart();
|
||||
_playbackCts = new CancellationTokenSource();
|
||||
IsRunning = true;
|
||||
RefreshQueueMarkers();
|
||||
@@ -112,6 +122,7 @@ public sealed class ChannelScheduleEngine
|
||||
ClearPreparedFrame(resetState: true);
|
||||
_lastPlaybackItemId = null;
|
||||
_skipCurrentItemId = null;
|
||||
_restartFromTopAfterItemId = null;
|
||||
RefreshQueueMarkers();
|
||||
QueueChanged?.Invoke(this, EventArgs.Empty);
|
||||
return;
|
||||
@@ -135,6 +146,7 @@ public sealed class ChannelScheduleEngine
|
||||
|
||||
_lastPlaybackItemId = null;
|
||||
_skipCurrentItemId = null;
|
||||
_restartFromTopAfterItemId = null;
|
||||
ClearPreparedFrame(resetState: false);
|
||||
IsRunning = false;
|
||||
RefreshQueueMarkers();
|
||||
@@ -152,6 +164,8 @@ public sealed class ChannelScheduleEngine
|
||||
try
|
||||
{
|
||||
_lastPlaybackItemId = null;
|
||||
_skipCurrentItemId = null;
|
||||
_restartFromTopAfterItemId = null;
|
||||
ResetDataUnavailableItems();
|
||||
ClearPreparedFrame(resetState: true);
|
||||
RefreshQueueMarkers();
|
||||
@@ -260,6 +274,8 @@ public sealed class ChannelScheduleEngine
|
||||
public void Reset()
|
||||
{
|
||||
_lastPlaybackItemId = null;
|
||||
_skipCurrentItemId = null;
|
||||
_restartFromTopAfterItemId = null;
|
||||
ClearPreparedFrame(resetState: false);
|
||||
foreach (var item in Queue)
|
||||
{
|
||||
@@ -327,6 +343,37 @@ public sealed class ChannelScheduleEngine
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task RestartFromTopAsync()
|
||||
{
|
||||
if (!IsRunning)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
var activeItem = Queue.FirstOrDefault(item => item.State is ScheduleQueueItemState.OnAir or ScheduleQueueItemState.Sending);
|
||||
if (activeItem is not null)
|
||||
{
|
||||
_skipCurrentItemId = activeItem.Id;
|
||||
_restartFromTopAfterItemId = activeItem.Id;
|
||||
_lastPlaybackItemId = null;
|
||||
activeItem.State = ScheduleQueueItemState.Queued;
|
||||
activeItem.LastError = string.Empty;
|
||||
activeItem.CurrentRegionLabel = string.Empty;
|
||||
activeItem.ClearInternalNextPreview();
|
||||
activeItem.ClearPlaybackCountdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastPlaybackItemId = null;
|
||||
_restartFromTopAfterItemId = null;
|
||||
}
|
||||
|
||||
RefreshQueueMarkers();
|
||||
QueueChanged?.Invoke(this, EventArgs.Empty);
|
||||
_advanceSignal?.TrySetResult(true);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public bool Remove(ChannelScheduleItem? item)
|
||||
{
|
||||
if (item is null || !item.CanDelete)
|
||||
@@ -547,7 +594,7 @@ public sealed class ChannelScheduleEngine
|
||||
|
||||
if (regionTargets.Count == 0)
|
||||
{
|
||||
_lastPlaybackItemId = queueItem.Id;
|
||||
MarkLastPlaybackItem(queueItem);
|
||||
MarkDataUnavailable(queueItem, "선택한 지역 조건에 송출 가능한 데이터가 없습니다.");
|
||||
RefreshQueueMarkers();
|
||||
return;
|
||||
@@ -637,7 +684,7 @@ public sealed class ChannelScheduleEngine
|
||||
queueItem.CurrentRegionLabel = string.Empty;
|
||||
queueItem.ClearInternalNextPreview();
|
||||
queueItem.ClearPlaybackCountdown();
|
||||
_lastPlaybackItemId = queueItem.Id;
|
||||
MarkLastPlaybackItem(queueItem);
|
||||
if (playedAny)
|
||||
{
|
||||
queueItem.State = ScheduleQueueItemState.Queued;
|
||||
@@ -737,7 +784,7 @@ public sealed class ChannelScheduleEngine
|
||||
queueItem.CurrentRegionLabel = string.Empty;
|
||||
queueItem.ClearInternalNextPreview();
|
||||
queueItem.ClearPlaybackCountdown();
|
||||
_lastPlaybackItemId = queueItem.Id;
|
||||
MarkLastPlaybackItem(queueItem);
|
||||
if (playedAny)
|
||||
{
|
||||
queueItem.State = ScheduleQueueItemState.Queued;
|
||||
@@ -1770,6 +1817,36 @@ public sealed class ChannelScheduleEngine
|
||||
return item.State is ScheduleQueueItemState.Queued or ScheduleQueueItemState.Next or ScheduleQueueItemState.Completed;
|
||||
}
|
||||
|
||||
private void MarkLastPlaybackItem(ChannelScheduleItem queueItem)
|
||||
{
|
||||
if (_restartFromTopAfterItemId == queueItem.Id)
|
||||
{
|
||||
_lastPlaybackItemId = null;
|
||||
_restartFromTopAfterItemId = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_lastPlaybackItemId = queueItem.Id;
|
||||
}
|
||||
|
||||
private void ClearStalePlaybackStatesBeforeStart()
|
||||
{
|
||||
foreach (var item in Queue.Where(item => item.State is ScheduleQueueItemState.OnAir or ScheduleQueueItemState.Sending))
|
||||
{
|
||||
if (_preparedCutFrame?.Item.Id == item.Id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
item.State = ScheduleQueueItemState.Queued;
|
||||
item.LastError = string.Empty;
|
||||
item.CurrentRegionLabel = string.Empty;
|
||||
item.ClearRenderedPreview();
|
||||
item.ClearInternalNextPreview();
|
||||
item.ClearPlaybackCountdown();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetDataUnavailableItems()
|
||||
{
|
||||
foreach (var item in Queue.Where(item => item.State == ScheduleQueueItemState.DataUnavailable))
|
||||
|
||||
Reference in New Issue
Block a user