BizHawk/BizHawk.Client.Common/movie/tasproj/TasMovieMarker.cs

270 lines
6.5 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
namespace BizHawk.Client.Common
{
/// <summary>
/// Represents a TasMovie Marker
/// A marker is a tagged frame with a message
/// </summary>
public class TasMovieMarker
{
public TasMovieMarker(int frame, string message = "")
{
Frame = frame;
Message = message;
}
/// <summary>
/// Parses a Marker from a line of text
/// </summary>
public TasMovieMarker(string line)
{
var split = line.Split('\t');
Frame = int.Parse(split[0]);
Message = split[1];
}
public virtual int Frame { get; private set; }
public virtual string Message { get; set; }
public override string ToString()
{
return Frame.ToString() + '\t' + Message;
}
public override int GetHashCode()
{
return this.Frame.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
else if (obj is TasMovieMarker)
{
return this.Frame == (obj as TasMovieMarker).Frame;
}
else
{
return false;
}
}
public static bool operator ==(TasMovieMarker marker, int frame)
{
return marker.Frame == frame;
}
public static bool operator !=(TasMovieMarker marker, int frame)
{
return marker.Frame != frame;
}
}
public class TasMovieMarkerList : List<TasMovieMarker>
{
private readonly TasMovie _movie;
public TasMovieMarkerList(TasMovie movie)
{
_movie = movie;
}
public TasMovieMarkerList DeepClone()
{
TasMovieMarkerList ret = new TasMovieMarkerList(_movie);
for (int i = 0; i < this.Count; i++)
ret.Add(new TasMovieMarker(this[i].Frame, this[i].Message));
return ret;
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
private void OnListChanged(NotifyCollectionChangedAction action)
{
if (CollectionChanged != null)
{
//TODO Allow different types
CollectionChanged.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
public override string ToString()
{
2014-07-16 02:17:19 +00:00
var sb = new StringBuilder();
foreach (var marker in this)
{
sb.AppendLine(marker.ToString());
}
return sb.ToString();
}
public new void Add(TasMovieMarker item)
{
var existingItem = this.FirstOrDefault(m => m.Frame == item.Frame);
if (existingItem != null)
{
if (existingItem.Message != item.Message)
{
_movie.ChangeLog.AddMarkerChange(item, item.Frame, existingItem.Message);
existingItem.Message = item.Message;
OnListChanged(NotifyCollectionChangedAction.Replace);
}
}
else
{
_movie.ChangeLog.AddMarkerChange(item);
base.Add(item);
this.Sort((m1, m2) => m1.Frame.CompareTo(m2.Frame));
OnListChanged(NotifyCollectionChangedAction.Add);
}
}
public void Add(int frame, string message)
{
Add(new TasMovieMarker(frame, message));
}
public new void AddRange(IEnumerable<TasMovieMarker> collection)
{
bool endBatch = _movie.ChangeLog.BeginNewBatch("Add Markers", true);
foreach (TasMovieMarker m in collection)
{
Add(m);
}
if (endBatch)
_movie.ChangeLog.EndBatch();
}
public new void Insert(int index, TasMovieMarker item)
{
_movie.ChangeLog.AddMarkerChange(item);
base.Insert(index, item);
this.Sort((m1, m2) => m1.Frame.CompareTo(m2.Frame));
OnListChanged(NotifyCollectionChangedAction.Add);
}
public new void InsertRange(int index, IEnumerable<TasMovieMarker> collection)
{
bool endBatch = _movie.ChangeLog.BeginNewBatch("Add Markers", true);
foreach (TasMovieMarker m in collection)
_movie.ChangeLog.AddMarkerChange(m);
if (endBatch)
_movie.ChangeLog.EndBatch();
base.InsertRange(index, collection);
this.Sort((m1, m2) => m1.Frame.CompareTo(m2.Frame));
OnListChanged(NotifyCollectionChangedAction.Add);
}
public new void Remove(TasMovieMarker item)
{
2015-03-22 16:55:34 +00:00
if (item == null) // TODO: Don't do this.
return;
_movie.ChangeLog.AddMarkerChange(null, item.Frame, item.Message);
base.Remove(item);
OnListChanged(NotifyCollectionChangedAction.Remove);
}
public new int RemoveAll(Predicate<TasMovieMarker> match)
{
bool endBatch = _movie.ChangeLog.BeginNewBatch("Remove All Markers", true);
foreach (TasMovieMarker m in this)
{
if (match.Invoke(m))
_movie.ChangeLog.AddMarkerChange(null, m.Frame, m.Message);
}
if (endBatch)
_movie.ChangeLog.EndBatch();
int removeCount = base.RemoveAll(match);
if (removeCount > 0)
{
OnListChanged(NotifyCollectionChangedAction.Remove);
}
return removeCount;
}
2014-07-13 14:13:20 +00:00
public void Move(int fromFrame, int toFrame)
{
TasMovieMarker m = Get(fromFrame);
2015-03-22 16:55:34 +00:00
if (m == null) // TODO: Don't do this.
return;
_movie.ChangeLog.AddMarkerChange(m, m.Frame);
Insert(0, new TasMovieMarker(toFrame, m.Message));
Remove(m);
}
/// <summary>
/// Deletes all markers at or below the given start frame.
/// </summary>
/// <param name="startFrame">The first frame for markers to be deleted.</param>
/// <returns>Number of markers deleted.</returns>
public int TruncateAt(int startFrame)
{
int deletedCount = 0;
bool endBatch = _movie.ChangeLog.BeginNewBatch("Truncate Markers", true);
for (int i = Count - 1; i > -1; i--)
{
if (this[i].Frame >= startFrame)
{
_movie.ChangeLog.AddMarkerChange(null, this[i].Frame, this[i].Message);
RemoveAt(i);
deletedCount++;
}
}
if (endBatch)
_movie.ChangeLog.EndBatch();
if (deletedCount > 0)
{
OnListChanged(NotifyCollectionChangedAction.Remove);
}
return deletedCount;
}
2014-07-13 14:13:20 +00:00
public TasMovieMarker Previous(int currentFrame)
2014-07-17 19:00:28 +00:00
{
return this
.Where(m => m.Frame < currentFrame)
.OrderBy(m => m.Frame)
.LastOrDefault();
}
public TasMovieMarker PreviousOrCurrent(int currentFrame)
2014-07-13 14:13:20 +00:00
{
return this
.Where(m => m.Frame <= currentFrame)
2014-07-13 14:13:20 +00:00
.OrderBy(m => m.Frame)
.LastOrDefault();
2014-07-13 14:13:20 +00:00
}
public TasMovieMarker Next(int currentFrame)
{
return this
.Where(m => m.Frame > currentFrame)
.OrderBy(m => m.Frame)
.FirstOrDefault();
2014-07-13 14:13:20 +00:00
}
2014-07-16 00:10:37 +00:00
public bool IsMarker(int frame)
{
return this.Any(m => m == frame);
}
public TasMovieMarker Get(int frame)
{
return this.FirstOrDefault(m => m == frame);
}
}
}