支持筛选录像

This commit is contained in:
2021-10-13 20:17:32 +02:00
parent 3f5070df77
commit b92d1d90ad
7 changed files with 205 additions and 43 deletions

View File

@@ -55,9 +55,15 @@ namespace AnotherReplayReader
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged<T>(T value, [CallerMemberName] string propertyName = "")
private void SetAndNotifyPropertyChanged<T>(ref T target, T newValue, [CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
var equals = Equals(target, newValue);
target = newValue;
if (!equals)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public string RA3Directory { get; }
@@ -68,14 +74,14 @@ namespace AnotherReplayReader
public string ReplayFolderPath
{
get { return _replayFolderPath; }
set { _replayFolderPath = value; NotifyPropertyChanged(_replayFolderPath); }
get => _replayFolderPath;
set => SetAndNotifyPropertyChanged(ref _replayFolderPath, value);
}
public string ReplayDetails
{
get { return _replayDetails; }
set { _replayDetails = value; NotifyPropertyChanged(_replayDetails); }
get => _replayDetails;
set => SetAndNotifyPropertyChanged(ref _replayDetails, value);
}
public bool ReplaySelected => _currentReplay != null;
@@ -89,8 +95,7 @@ namespace AnotherReplayReader
get => _currentReplay;
set
{
_currentReplay = value;
NotifyPropertyChanged(_currentReplay);
SetAndNotifyPropertyChanged(ref _currentReplay, value);
ReplayDetails = "";
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ReplayPlayable)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ReplaySelected)));
@@ -109,19 +114,18 @@ namespace AnotherReplayReader
public partial class MainWindow : Window
{
private readonly MainWindowProperties _properties = new MainWindowProperties();
private readonly List<Replay> _replayList = new List<Replay>();
private readonly Cache _cache = new Cache();
private readonly PlayerIdentity _playerIdentity;
private readonly BigMinimapCache _minimapCache;
private readonly MinimapReader _minimapReader;
private List<Replay> _replayList = new List<Replay>();
private List<PinyinReplayData> _pinyinList = new List<PinyinReplayData>();
private CancellationTokenSource _loadReplaysToken;
public MainWindow()
{
DataContext = _properties;
InitializeComponent();
var handling = new bool[1] { false };
Application.Current.Dispatcher.UnhandledException += (sender, eventArgs) =>
{
@@ -133,11 +137,11 @@ namespace AnotherReplayReader
Dispatcher.Invoke(() => MessageBox.Show($"错误:\r\n{eventArgs.Exception}"));
};
Closing += (sender, eventArgs) => _cache.Save();
_playerIdentity = new PlayerIdentity(_cache);
_minimapCache = new BigMinimapCache(_cache, _properties.RA3Directory);
_minimapReader = new MinimapReader(_minimapCache, _properties.RA3Directory, _properties.CustomMapsDirectory, _properties.ModsDirectory);
InitializeComponent();
Closing += (sender, eventArgs) => _cache.Save();
LoadReplays();
Task.Run(() => AutoSaveReplays(Dispatcher, _properties.RA3ReplayFolderPath));
@@ -295,8 +299,13 @@ namespace AnotherReplayReader
{
_image.Source = null;
}
_dataGrid?.Items.Clear();
if (_dataGrid != null)
{
_dataGrid.ItemsSource = Array.Empty<Replay>();
_dataGrid.Items.Refresh();
}
_replayList.Clear();
_pinyinList.Clear();
if (!Directory.Exists(path))
{
@@ -304,9 +313,10 @@ namespace AnotherReplayReader
return;
}
var newList = await Task.Run(() =>
var (newList, newPinyinList) = await Task.Run(() =>
{
var list = new List<Replay>();
var pinyinList = new List<PinyinReplayData>();
foreach (var replayPath in Directory.EnumerateFiles(path, "*.RA3Replay"))
{
if (cancelToken.IsCancellationRequested)
@@ -315,7 +325,9 @@ namespace AnotherReplayReader
}
try
{
list.Add(new Replay(replayPath));
var replay = new Replay(replayPath);
list.Add(replay);
pinyinList.Add(replay.ToPinyin(_playerIdentity));
}
catch (Exception exception)
{
@@ -324,21 +336,22 @@ namespace AnotherReplayReader
}
_ = Dispatcher.Invoke(() => _properties.ReplayDetails = string.Format(loadingString, _replayList.Count));
}
return list;
return (list, pinyinList);
});
_replayList.AddRange(newList);
_replayList = newList;
_pinyinList = newPinyinList;
DisplayReplays(string.Empty, nextSelected);
}
private void DisplayReplays(string message = null, string nextSelected = null)
private void DisplayReplays(string message = null, string nextSelected = null, Replay[] filtered = null)
{
var filtered = _replayList;
Dispatcher.Invoke(() =>
{
filtered = filtered ?? _replayList.ToArray();
_properties.CurrentReplay = null;
_dataGrid.Items.Clear();
filtered.ForEach(x => _dataGrid.Items.Add(x));
_dataGrid.ItemsSource = filtered;
_dataGrid.Items.Refresh();
_properties.ReplayDetails = message;
if (nextSelected != null)
@@ -410,7 +423,7 @@ namespace AnotherReplayReader
break;
}
var factionName = ModData.GetFaction(replay.Mod, player.FactionID).Name;
var realName = replay.Type == ReplayType.Lan ? _playerIdentity.QueryRealName(player.PlayerIP) : string.Empty;
var realName = replay.Type == ReplayType.Lan ? _playerIdentity.FormatRealName(player.PlayerIP) : string.Empty;
_properties.ReplayDetails += $"{player.PlayerName + realName}{factionName}\n";
}
@@ -522,9 +535,39 @@ namespace AnotherReplayReader
LoadReplays();
}
private void ReplayFilterBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
private async void ReplayFilterBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
try
{
var pinyins = _replayFilterBox.Text.Split(',', ' ', '')
.Select(x => x.ToPinyin())
.Where(x => !string.IsNullOrEmpty(x))
.ToArray();
if (!pinyins.Any())
{
DisplayReplays();
return;
}
var tokenSource = _loadReplaysToken;
var token = tokenSource.Token;
var list = _pinyinList.ToArray();
var result = await Task.Run(() =>
{
var query = from replay in list.AsParallel()
where pinyins.Any(pinyin => replay.MatchPinyin(pinyin))
select replay.Replay;
return query.ToArray();
});
if (token.IsCancellationRequested || _loadReplaysToken != tokenSource)
{
return;
}
DisplayReplays(null, null, result);
}
catch (Exception ex)
{
Debug.Instance.DebugMessage += $"Exception when filtering replays: {ex}";
}
}
}
}