mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Moved slideshow functions to seperate class
This commit is contained in:
parent
8fdeb64196
commit
e94754945c
@ -14,16 +14,18 @@ using System.Windows.Media.Imaging;
|
||||
using System.Windows.Threading;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.NexusApi;
|
||||
using Wabbajack.UI;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
public enum TaskMode { INSTALLING, BUILDING }
|
||||
internal class AppState : ViewModel, IDataErrorInfo
|
||||
{
|
||||
private const int MAX_CACHE_SIZE = 10;
|
||||
private const bool USE_SYNC_CACHING = false;
|
||||
public const bool GcCollect = true;
|
||||
|
||||
private bool installing = false;
|
||||
private SlideShow _slideShow;
|
||||
|
||||
public bool installing = false;
|
||||
|
||||
private string _mo2Folder;
|
||||
|
||||
@ -33,7 +35,7 @@ namespace Wabbajack
|
||||
|
||||
public volatile bool Dirty;
|
||||
|
||||
private readonly Dispatcher dispatcher;
|
||||
public readonly Dispatcher dispatcher;
|
||||
|
||||
public AppState(Dispatcher d, TaskMode mode)
|
||||
{
|
||||
@ -42,7 +44,7 @@ namespace Wabbajack
|
||||
_noneImage = UIUtils.BitmapImageFromResource("Wabbajack.UI.none.jpg");
|
||||
_nextIcon = UIUtils.BitmapImageFromResource("Wabbajack.UI.Icons.next.png");
|
||||
|
||||
SetupSlideshow();
|
||||
_slideShow = new SlideShow(this, true);
|
||||
|
||||
if (Assembly.GetEntryAssembly().Location.ToLower().Contains("\\downloads\\"))
|
||||
{
|
||||
@ -69,17 +71,6 @@ namespace Wabbajack
|
||||
slideshowThread.Start();
|
||||
}
|
||||
|
||||
private void SetupSlideshow()
|
||||
{
|
||||
var files = NexusApiClient.CachedSlideShow;
|
||||
if (files.Any())
|
||||
{
|
||||
SlideShowElements = files.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public Random _random = new Random();
|
||||
public List<SlideShowItem> SlideShowElements = new List<SlideShowItem>();
|
||||
private DateTime _lastSlideShowUpdate = new DateTime();
|
||||
|
||||
public ObservableCollection<string> Log { get; } = new ObservableCollection<string>();
|
||||
@ -182,7 +173,7 @@ namespace Wabbajack
|
||||
{
|
||||
get
|
||||
{
|
||||
return new LambdaCommand(() => true, UpdateSlideShowItem);
|
||||
return new LambdaCommand(() => true, _slideShow.UpdateSlideShowItem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +249,7 @@ namespace Wabbajack
|
||||
}
|
||||
|
||||
private readonly BitmapImage _wabbajackLogo = null;
|
||||
private readonly BitmapImage _noneImage = null;
|
||||
public readonly BitmapImage _noneImage = null;
|
||||
private bool _originalImage = true;
|
||||
private BitmapImage _splashScreenImage = null;
|
||||
public BitmapImage SplashScreenImage
|
||||
@ -285,8 +276,7 @@ namespace Wabbajack
|
||||
public string SplashScreenSummary { get => _SplashScreenSummary; set => this.RaiseAndSetIfChanged(ref _SplashScreenSummary, value); }
|
||||
private bool _splashShowNSFW = true;
|
||||
public bool SplashShowNSFW { get => _splashShowNSFW; set => this.RaiseAndSetIfChanged(ref _splashShowNSFW, value); }
|
||||
private Thread slideshowThread = null;
|
||||
private int slideshowSleepTime = 1000;
|
||||
private readonly Thread slideshowThread = null;
|
||||
private bool _enableSlideShow = true;
|
||||
public bool EnableSlideShow
|
||||
{
|
||||
@ -294,16 +284,14 @@ namespace Wabbajack
|
||||
set
|
||||
{
|
||||
RaiseAndSetIfChanged(ref _enableSlideShow, value);
|
||||
if(slideshowThread.IsAlive)
|
||||
if (!slideshowThread.IsAlive) return;
|
||||
if (!_enableSlideShow)
|
||||
{
|
||||
if (!_enableSlideShow)
|
||||
{
|
||||
ApplyModlistProperties();
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateSlideShowItem();
|
||||
}
|
||||
ApplyModlistProperties();
|
||||
}
|
||||
else
|
||||
{
|
||||
_slideShow.UpdateSlideShowItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -363,176 +351,14 @@ namespace Wabbajack
|
||||
Dirty = false;
|
||||
}
|
||||
|
||||
if (slidesQueue != null && slidesQueue.Any())
|
||||
if (_slideShow.SlidesQueue.Any())
|
||||
{
|
||||
if (DateTime.Now - _lastSlideShowUpdate > TimeSpan.FromSeconds(10))
|
||||
{
|
||||
UpdateSlideShowItem();
|
||||
_slideShow.UpdateSlideShowItem();
|
||||
}
|
||||
}
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
private void UpdateSlideShowItem()
|
||||
{
|
||||
if (EnableSlideShow && slideshowThread != null && installing)
|
||||
{
|
||||
// max cached files achieved
|
||||
if (_cachedSlides.Count >= MAX_CACHE_SIZE)
|
||||
{
|
||||
do
|
||||
{
|
||||
var idx = _random.Next(0, SlideShowElements.Count);
|
||||
var randomElement = SlideShowElements[idx];
|
||||
while (!_cachedSlides.ContainsKey(randomElement.ModID) || slidesQueue.Contains(randomElement))
|
||||
{
|
||||
idx = _random.Next(0, SlideShowElements.Count);
|
||||
randomElement = SlideShowElements[idx];
|
||||
}
|
||||
|
||||
if (_cachedSlides.ContainsKey(randomElement.ModID))
|
||||
{
|
||||
var bitmap = new BitmapImage();
|
||||
_cachedSlides.TryGetValue(randomElement.ModID, out bitmap);
|
||||
bitmap = null;
|
||||
_cachedSlides.Remove(randomElement.ModID);
|
||||
//hmmm
|
||||
//GC.Collect();
|
||||
}
|
||||
} while (_cachedSlides.Count >= MAX_CACHE_SIZE);
|
||||
}
|
||||
|
||||
SlideShowItem element = slidesQueue.Peek();
|
||||
if (!element.Adult || (element.Adult && SplashShowNSFW))
|
||||
{
|
||||
SplashScreenImage = _noneImage;
|
||||
if (element.ImageURL != null)
|
||||
{
|
||||
|
||||
dispatcher.Invoke(() =>
|
||||
{
|
||||
if (_cachedSlides.ContainsKey(element.ModID))
|
||||
{
|
||||
var bitmap = new BitmapImage();
|
||||
_cachedSlides.TryGetValue(element.ModID, out bitmap);
|
||||
SplashScreenImage = bitmap;
|
||||
}
|
||||
});
|
||||
}
|
||||
_originalImage = false;
|
||||
SplashScreenModName = element.ModName;
|
||||
SplashScreenAuthorName = element.AuthorName;
|
||||
SplashScreenSummary = element.ModSummary;
|
||||
_nexusSiteURL = element.ModURL;
|
||||
}
|
||||
|
||||
_lastSlideShowUpdate = DateTime.Now;
|
||||
|
||||
slidesQueue.Dequeue();
|
||||
QueueRandomSlide(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, BitmapImage> _cachedSlides;
|
||||
private Queue<SlideShowItem> slidesQueue;
|
||||
private SlideShowItem lastSlide;
|
||||
/// <summary>
|
||||
/// Caches a slide
|
||||
/// </summary>
|
||||
/// <param name="url">The url</param>
|
||||
/// <param name="dest">The destination</param>
|
||||
private void CacheSlide(string id, string url)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
if (USE_SYNC_CACHING)
|
||||
{
|
||||
dispatcher.Invoke(() =>
|
||||
{
|
||||
using (var stream = new HttpClient().GetStreamSync(url))
|
||||
stream.CopyTo(ms);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var stream = new HttpClient().GetStreamAsync(url))
|
||||
{
|
||||
stream.Wait();
|
||||
stream.Result.CopyTo(ms);
|
||||
}
|
||||
}
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
dispatcher.Invoke(() =>
|
||||
{
|
||||
var image = new BitmapImage();
|
||||
image.BeginInit();
|
||||
image.CacheOption = BitmapCacheOption.OnLoad;
|
||||
image.StreamSource = ms;
|
||||
image.EndInit();
|
||||
image.Freeze();
|
||||
|
||||
_cachedSlides.Add(id, image);
|
||||
});
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Queues a random slide
|
||||
/// </summary>
|
||||
/// <param name="init">Only used if called from the Preloadfunction</param>
|
||||
/// <param name="checkLast">If to not queue the same thing again</param>
|
||||
/// <returns></returns>
|
||||
private bool QueueRandomSlide(bool init, bool checkLast)
|
||||
{
|
||||
var result = false;
|
||||
var idx = _random.Next(0, SlideShowElements.Count);
|
||||
var element = SlideShowElements[idx];
|
||||
if (checkLast)
|
||||
{
|
||||
while(element == lastSlide && (!element.Adult || (element.Adult && SplashShowNSFW)))
|
||||
{
|
||||
idx = _random.Next(0, SlideShowElements.Count);
|
||||
element = SlideShowElements[idx];
|
||||
}
|
||||
}
|
||||
|
||||
if(element.ImageURL == null)
|
||||
{
|
||||
if(!init)
|
||||
slidesQueue.Enqueue(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_cachedSlides.ContainsKey(element.ModID))
|
||||
{
|
||||
CacheSlide(element.ModID, element.ImageURL);
|
||||
slidesQueue.Enqueue(element);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!init)
|
||||
slidesQueue.Enqueue(element);
|
||||
}
|
||||
lastSlide = element;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// Caches 3 random images and puts them in the queue
|
||||
/// </summary>
|
||||
private void PreloadSlideshow()
|
||||
{
|
||||
_cachedSlides = new Dictionary<string, BitmapImage>();
|
||||
slidesQueue = new Queue<SlideShowItem>();
|
||||
|
||||
var turns = 0;
|
||||
for(var i = 0; i < SlideShowElements.Count; i++)
|
||||
{
|
||||
if (turns >= 3)
|
||||
break;
|
||||
|
||||
if (QueueRandomSlide(true, false))
|
||||
turns++;
|
||||
Thread.Sleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -596,6 +422,7 @@ namespace Wabbajack
|
||||
|
||||
_mo2Folder = mo2folder;
|
||||
}
|
||||
|
||||
internal void ConfigureForInstall(string source, ModList modlist)
|
||||
{
|
||||
|
||||
@ -608,19 +435,13 @@ namespace Wabbajack
|
||||
|
||||
ApplyModlistProperties();
|
||||
|
||||
SlideShowElements = modlist.Archives.OfType<NexusMod>().Select(m => new SlideShowItem
|
||||
{
|
||||
ModName = NexusApiUtils.FixupSummary(m.ModName),
|
||||
AuthorName = NexusApiUtils.FixupSummary(m.Author),
|
||||
ModSummary = NexusApiUtils.FixupSummary(m.Summary),
|
||||
ImageURL = m.SlideShowPic,
|
||||
ModURL = m.NexusURL,
|
||||
Adult = m.Adult,
|
||||
ModID = m.ModID
|
||||
}).ToList();
|
||||
_slideShow.SlideShowElements = modlist.Archives.OfType<NexusMod>().Select(m =>
|
||||
new Slide(NexusApiUtils.FixupSummary(m.ModName),m.ModID,
|
||||
NexusApiUtils.FixupSummary(m.Summary), NexusApiUtils.FixupSummary(m.Author),
|
||||
m.Adult,m.NexusURL,m.SlideShowPic)).ToList();
|
||||
|
||||
|
||||
PreloadSlideshow();
|
||||
_slideShow.PreloadSlideShow();
|
||||
}
|
||||
|
||||
private void ExecuteBegin()
|
||||
|
@ -46,17 +46,6 @@ namespace Wabbajack.NexusApi
|
||||
public bool contains_adult_content;
|
||||
}
|
||||
|
||||
public class SlideShowItem
|
||||
{
|
||||
public string ImageURL;
|
||||
public string ModName;
|
||||
public string ModSummary;
|
||||
public string AuthorName;
|
||||
public string ModURL;
|
||||
public bool Adult;
|
||||
public string ModID;
|
||||
}
|
||||
|
||||
public class EndorsementResponse
|
||||
{
|
||||
public string message;
|
||||
|
@ -258,11 +258,11 @@ namespace Wabbajack.NexusApi
|
||||
}
|
||||
|
||||
|
||||
public static IEnumerable<SlideShowItem> CachedSlideShow
|
||||
public static IEnumerable<UI.Slide> CachedSlideShow
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Directory.Exists(Consts.NexusCacheDirectory)) return new SlideShowItem[] { };
|
||||
if (!Directory.Exists(Consts.NexusCacheDirectory)) return new UI.Slide[] { };
|
||||
|
||||
return Directory.EnumerateFiles(Consts.NexusCacheDirectory)
|
||||
.Where(f => f.EndsWith(".json"))
|
||||
@ -280,15 +280,7 @@ namespace Wabbajack.NexusApi
|
||||
})
|
||||
.Where(m => m != null)
|
||||
.Where(m => m._internal_version == CACHED_VERSION_NUMBER && m.picture_url != null)
|
||||
.Select(m => new SlideShowItem
|
||||
{
|
||||
ImageURL = m.picture_url,
|
||||
ModName = FixupSummary(m.name),
|
||||
AuthorName = FixupSummary(m.author),
|
||||
ModURL = GetModURL(m.game_name, m.mod_id),
|
||||
ModSummary = FixupSummary(m.summary),
|
||||
Adult = m.contains_adult_content
|
||||
});
|
||||
.Select(m => new UI.Slide(m.name,m.mod_id,m.summary,m.author,m.contains_adult_content,GetModURL(m.game_name,m.mod_id),m.picture_url));
|
||||
}
|
||||
}
|
||||
|
||||
|
200
Wabbajack/UI/SlideShow.cs
Normal file
200
Wabbajack/UI/SlideShow.cs
Normal file
@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.NexusApi;
|
||||
|
||||
namespace Wabbajack.UI
|
||||
{
|
||||
public class Slide
|
||||
{
|
||||
public Slide(string modName, string modID, string modDescription, string modAuthor, bool isNSFW, string modUrl, string imageURL)
|
||||
{
|
||||
ModName = modName;
|
||||
ModDescription = modDescription;
|
||||
ModAuthor = modAuthor;
|
||||
IsNSFW = isNSFW;
|
||||
ModURL = modUrl;
|
||||
ModID = modID;
|
||||
ImageURL = imageURL;
|
||||
}
|
||||
|
||||
public string ModName { get; }
|
||||
public string ModDescription { get; }
|
||||
public string ModAuthor { get; }
|
||||
public bool IsNSFW { get; }
|
||||
public string ModURL { get; }
|
||||
public string ModID { get; }
|
||||
public BitmapImage Image { get; set; }
|
||||
public string ImageURL { get; }
|
||||
|
||||
}
|
||||
|
||||
internal class SlideShow
|
||||
{
|
||||
private readonly Random _random;
|
||||
private Slide _lastSlide;
|
||||
private const bool UseSync = false;
|
||||
private const int MaxCacheSize = 10;
|
||||
private readonly AppState _appState;
|
||||
|
||||
public SlideShow(AppState appState, bool checkCache)
|
||||
{
|
||||
SlideShowElements = new List<Slide>();
|
||||
CachedSlides = new Dictionary<string, Slide>();
|
||||
SlidesQueue = new Queue<Slide>();
|
||||
_random = new Random();
|
||||
_appState = appState;
|
||||
|
||||
if (!checkCache) return;
|
||||
IEnumerable<Slide> files = NexusApiClient.CachedSlideShow;
|
||||
IEnumerable<Slide> enumerable = files.ToList();
|
||||
if (enumerable.Any())
|
||||
{
|
||||
SlideShowElements = enumerable.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public void PreloadSlideShow()
|
||||
{
|
||||
var turns = 0;
|
||||
for (var i = 0; i < SlideShowElements.Count; i++)
|
||||
{
|
||||
if (turns >= 3)
|
||||
break;
|
||||
|
||||
if (QueueRandomSlide(true, false))
|
||||
turns++;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateSlideShowItem()
|
||||
{
|
||||
if (!_appState.EnableSlideShow || !_appState.installing || SlidesQueue.Count==0) return;
|
||||
var slide = SlidesQueue.Peek();
|
||||
|
||||
while (CachedSlides.Count >= MaxCacheSize)
|
||||
{
|
||||
var idx = _random.Next(0, SlideShowElements.Count);
|
||||
var randomSlide = SlideShowElements[idx];
|
||||
while (CachedSlides.ContainsKey(randomSlide.ModID) || SlidesQueue.Contains(randomSlide))
|
||||
{
|
||||
idx = _random.Next(0, SlideShowElements.Count);
|
||||
randomSlide = SlideShowElements[idx];
|
||||
}
|
||||
|
||||
if (!CachedSlides.ContainsKey(randomSlide.ModID)) continue;
|
||||
CachedSlides.Remove(randomSlide.ModID);
|
||||
if(AppState.GcCollect)
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
if (!slide.IsNSFW || (slide.IsNSFW && ShowNSFW))
|
||||
{
|
||||
_appState.SplashScreenImage = _appState._noneImage;
|
||||
if (slide.ImageURL != null && slide.Image != null)
|
||||
{
|
||||
_appState.dispatcher.Invoke(() =>
|
||||
{
|
||||
if (!CachedSlides.ContainsKey(slide.ModID)) return;
|
||||
_appState.SplashScreenImage = slide.Image;
|
||||
});
|
||||
}
|
||||
|
||||
_appState.SplashScreenModName = slide.ModName;
|
||||
_appState.SplashScreenAuthorName = slide.ModAuthor;
|
||||
_appState.SplashScreenSummary = slide.ModDescription;
|
||||
_appState._nexusSiteURL = slide.ModURL;
|
||||
}
|
||||
|
||||
SlidesQueue.Dequeue();
|
||||
QueueRandomSlide(false, true);
|
||||
}
|
||||
|
||||
private void CacheImage(Slide slide)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
if (UseSync)
|
||||
{
|
||||
_appState.dispatcher.Invoke(() =>
|
||||
{
|
||||
using (var stream = new HttpClient().GetStreamSync(slide.ImageURL))
|
||||
stream.CopyTo(ms);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
using (Task<Stream> stream = new HttpClient().GetStreamAsync(slide.ImageURL))
|
||||
{
|
||||
stream.Wait();
|
||||
stream.Result.CopyTo(ms);
|
||||
}
|
||||
}
|
||||
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
_appState.dispatcher.Invoke(() =>
|
||||
{
|
||||
var image = new BitmapImage();
|
||||
image.BeginInit();
|
||||
image.CacheOption = BitmapCacheOption.OnLoad;
|
||||
image.StreamSource = ms;
|
||||
image.EndInit();
|
||||
image.Freeze();
|
||||
|
||||
slide.Image = image;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private bool QueueRandomSlide(bool init, bool checkLast)
|
||||
{
|
||||
var result = false;
|
||||
var idx = _random.Next(0, SlideShowElements.Count);
|
||||
var element = SlideShowElements[idx];
|
||||
|
||||
if (checkLast)
|
||||
{
|
||||
while (element == _lastSlide && (!element.IsNSFW || (element.IsNSFW && ShowNSFW)))
|
||||
{
|
||||
idx = _random.Next(0, SlideShowElements.Count);
|
||||
element = SlideShowElements[idx];
|
||||
}
|
||||
}
|
||||
|
||||
if (element.ImageURL == null)
|
||||
{
|
||||
if (!init) SlidesQueue.Enqueue(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CachedSlides.ContainsKey(element.ModID))
|
||||
{
|
||||
CacheImage(element);
|
||||
CachedSlides.Add(element.ModID, element);
|
||||
SlidesQueue.Enqueue(element);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!init) SlidesQueue.Enqueue(element);
|
||||
}
|
||||
|
||||
_lastSlide = element;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool ShowNSFW { get; set; }
|
||||
public List<Slide> SlideShowElements { get; set; }
|
||||
|
||||
public Dictionary<string, Slide> CachedSlides { get; }
|
||||
|
||||
public Queue<Slide> SlidesQueue { get; }
|
||||
}
|
||||
}
|
@ -197,6 +197,7 @@
|
||||
<Compile Include="ReportBuilder.cs" />
|
||||
<Compile Include="Themes\LeftMarginMultiplierConverter.cs" />
|
||||
<Compile Include="Themes\TreeViewItemExtensions.cs" />
|
||||
<Compile Include="UI\SlideShow.cs" />
|
||||
<Compile Include="UI\UIUtils.cs" />
|
||||
<Compile Include="Updater\CheckForUpdates.cs" />
|
||||
<Compile Include="Validation\DTOs.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user