Added VideoPlayerWidget.LoadAndPlayAsync method

Previous commits removed the async loading of videos, which can be a problem for videos played in the radar widget mid-game because it can cause a lag spike. This loads the video on a separate thread and runs it on the main thread whenever it is loaded, not blocking the main thread meanwhile and allowing the game to continue while the video loads.
Also add back cancelling of already playing video and add a check to not try to run onComplete if it is null.
This commit is contained in:
penev92
2023-02-02 22:54:20 +02:00
committed by abcdefg30
parent c3fcbf77ed
commit 2c51e791ad
2 changed files with 56 additions and 17 deletions

View File

@@ -62,22 +62,7 @@ namespace OpenRA.Mods.Common.Scripting
public static void PlayFMVInRadar(string videoFileName, Action onComplete)
{
var player = Ui.Root.Get<VideoPlayerWidget>("PLAYER");
try
{
player.LoadAndPlay(videoFileName);
}
catch (FileNotFoundException)
{
onComplete();
return;
}
player.PlayThen(() =>
{
onComplete();
player.CloseVideo();
});
player.LoadAndPlayAsync(videoFileName, onComplete);
}
}
}

View File

@@ -10,6 +10,8 @@
#endregion
using System;
using System.IO;
using System.Threading.Tasks;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Video;
@@ -50,11 +52,56 @@ namespace OpenRA.Mods.Common.Widgets
if (filename == cachedVideoFileName)
return;
cachedVideoFileName = filename;
var stream = Game.ModData.DefaultFileSystem.Open(filename);
var video = VideoLoader.GetVideo(stream, true, Game.ModData.VideoLoaders);
Play(video);
}
/// <summary>
/// Tries to load a video from the specified file and play it. Does nothing if the file name matches the already loaded video.
/// </summary>
/// <param name="filename">Name of the file, including the extension.</param>
/// <param name="after">Action to perform after the video ends.</param>
public void LoadAndPlayAsync(string filename, Action after)
{
if (filename == cachedVideoFileName)
return;
cachedVideoFileName = filename;
if (!stopped)
CloseVideo();
Task.Run(() =>
{
try
{
var stream = Game.ModData.DefaultFileSystem.Open(filename);
var video = VideoLoader.GetVideo(stream, true, Game.ModData.VideoLoaders);
// Safeguard against race conditions with two videos being loaded at the same time - prefer to play only the last one.
if (filename != cachedVideoFileName)
{
after();
return;
}
Game.RunAfterTick(() =>
{
Play(video);
PlayThen(() =>
{
after();
CloseVideo();
});
});
}
catch (FileNotFoundException)
{
after();
}
});
}
/// <summary>
@@ -239,7 +286,14 @@ namespace OpenRA.Mods.Common.Widgets
Game.Sound.StopVideo();
video.Reset();
videoSprite.Sheet.GetTexture().SetData(video.CurrentFrameData, textureSize, textureSize);
Game.RunAfterTick(onComplete);
Game.RunAfterTick(() =>
{
if (onComplete != null)
{
onComplete();
onComplete = null;
}
});
}
public void CloseVideo()