Skip to content

Commit

Permalink
Add bookmark/chapter actions (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yoooi0 committed Dec 11, 2022
1 parent 75b4353 commit 6b7a59f
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 13 deletions.
10 changes: 9 additions & 1 deletion MultiFunPlayer/Common/Script/Bookmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@
namespace MultiFunPlayer.Common;

[DebuggerDisplay("[{Name}: {Position}s]")]
public record Bookmark(string Name, double Position);
public record Bookmark(string Name, double Position);

public class BookmarkPositionComparer : IComparer<Bookmark>
{
public static BookmarkPositionComparer Default { get; } = new();

public int Compare(Bookmark x, Bookmark y)
=> Comparer<double>.Default.Compare(x.Position, y.Position);
}
25 changes: 24 additions & 1 deletion MultiFunPlayer/Common/Script/BookmarkCollection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;

namespace MultiFunPlayer.Common;

Expand All @@ -12,6 +12,29 @@ public class BookmarkCollection : IReadOnlyList<Bookmark>
public void Add(string name, TimeSpan position) => Add(name, position.TotalSeconds);
public void Add(string name, double position) => _items.Add(new Bookmark(name, position));

public bool TryFindByName(string name, out Bookmark bookmark)
{
bookmark = _items.Find(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
return bookmark != null;
}

public int SearchForIndexBefore(double position) => SearchForIndexAfter(position) - 1;
public int SearchForIndexAfter(double position)
{
if (_items.Count == 0 || position < _items[0].Position)
return 0;

if (position > _items[^1].Position)
return Count;

var bestIndex = _items.BinarySearch(new Bookmark(null, position), BookmarkPositionComparer.Default);
if (bestIndex >= 0)
return bestIndex;

bestIndex = ~bestIndex;
return bestIndex == Count ? Count : bestIndex;
}

#region IReadOnlyList
public Bookmark this[int index] => _items[index];
#endregion
Expand Down
10 changes: 9 additions & 1 deletion MultiFunPlayer/Common/Script/Chapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@
namespace MultiFunPlayer.Common;

[DebuggerDisplay("[{Name}: {StartPosition}s -> {EndPosition}s]")]
public record Chapter(string Name, double StartPosition, double EndPosition);
public record Chapter(string Name, double StartPosition, double EndPosition);

public class ChapterStartPositionComparer : IComparer<Chapter>
{
public static ChapterStartPositionComparer Default { get; } = new();

public int Compare(Chapter x, Chapter y)
=> Comparer<double>.Default.Compare(x.StartPosition, y.StartPosition);
}
35 changes: 26 additions & 9 deletions MultiFunPlayer/Common/Script/ChapterCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public bool Add(string name, double startPosition, double endPosition)
if (chapter.StartPosition >= startPosition && chapter.EndPosition <= endPosition)
return false;

var startIntersect = FindIntersecting(startPosition);
var endIntersect = FindIntersecting(endPosition);
_ = TryFindIntersecting(startPosition, out var startIntersect);
_ = TryFindIntersecting(endPosition, out var endIntersect);
if (startIntersect == endIntersect && startIntersect != null)
return false;

Expand All @@ -34,16 +34,33 @@ public bool Add(string name, double startPosition, double endPosition)
return true;
}

public Chapter FindIntersecting(double position)
public bool TryFindIntersecting(double position, out Chapter chapter)
{
if (_items.Count == 0)
return null;
chapter = _items.Find(x => position >= x.StartPosition && position <= x.EndPosition);
return chapter != null;
}

public bool TryFindByName(string name, out Chapter chapter)
{
chapter = _items.Find(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
return chapter != null;
}

public int SearchForIndexBefore(double position) => SearchForIndexAfter(position) - 1;
public int SearchForIndexAfter(double position)
{
if (_items.Count == 0 || position < _items[0].StartPosition)
return 0;

if (position > _items[^1].StartPosition)
return Count;

foreach(var chapter in _items)
if (position >= chapter.StartPosition && position <= chapter.EndPosition)
return chapter;
var bestIndex = _items.BinarySearch(new Chapter(null, position, position), ChapterStartPositionComparer.Default);
if (bestIndex >= 0)
return bestIndex;

return null;
bestIndex = ~bestIndex;
return bestIndex == Count ? Count : bestIndex;
}

#region IReadOnlyList
Expand Down
82 changes: 81 additions & 1 deletion MultiFunPlayer/UI/Controls/ViewModels/ScriptViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ void UpdateSettings(DeviceAxis axis, Action<AxisSettings> callback)
s.RegisterAction<double>("Media::Position::Time::Set",
s => s.WithLabel("Value").WithStringFormat("{}{0}s"), value => SeekMediaToTime(value));

s.RegisterAction<double>( "Media::Position::Percent::Offset",
s.RegisterAction<double>("Media::Position::Percent::Offset",
s => s.WithLabel("Value offset").WithStringFormat("{}{0}%"),
offset => SeekMediaToPercent(MediaPosition / MediaDuration + offset / 100));
s.RegisterAction<double>("Media::Position::Percent::Set",
Expand All @@ -1368,6 +1368,86 @@ void UpdateSettings(DeviceAxis axis, Action<AxisSettings> callback)
s => s.WithLabel("Script start auto-skip offset").WithStringFormat("{}{0}s"), offset => AutoSkipToScriptStartOffset = offset);
#endregion

#region Media::Bookmark
BookmarkCollection GetFirstBookmarks()
{
var (_, bookmarks) = AxisBookmarks.FirstOrDefault(x => x.Value != null);
return bookmarks;
}

s.RegisterAction<string>("Media::Bookmark::SeekToByName",
s => s.WithLabel("Bookmark name"), name =>
{
var bookmarks = GetFirstBookmarks();
if (bookmarks?.TryFindByName(name, out var bookmark) == true)
SeekMediaToTime(bookmark.Position);
});

s.RegisterAction<int>("Media::Bookmark::SeekToByIndex",
s => s.WithLabel("Bookmark index"), index =>
{
var bookmarks = GetFirstBookmarks();
if (bookmarks?.ValidateIndex(index) == true)
SeekMediaToTime(bookmarks[index].Position);
});

s.RegisterAction("Media::Bookmark::SeekToNext", () =>
{
var bookmarks = GetFirstBookmarks();
var index = bookmarks.SearchForIndexAfter(MediaPosition + 1.5);
if (bookmarks?.ValidateIndex(index) == true)
SeekMediaToTime(bookmarks[index].Position);
});

s.RegisterAction("Media::Bookmark::SeekToPrev", () =>
{
var bookmarks = GetFirstBookmarks();
var index = bookmarks.SearchForIndexBefore(MediaPosition - 1.5);
if (bookmarks?.ValidateIndex(index) == true)
SeekMediaToTime(bookmarks[index].Position);
});
#endregion

#region Media::Chapter
ChapterCollection GetFirstChapters()
{
var (_, chapters) = AxisChapters.FirstOrDefault(x => x.Value != null);
return chapters;
}

s.RegisterAction<string>("Media::Chapter::SeekToByName",
s => s.WithLabel("Chapter name"), name =>
{
var chapters = GetFirstChapters();
if (chapters?.TryFindByName(name, out var chapter) == true)
SeekMediaToTime(chapter.StartPosition);
});

s.RegisterAction<int>("Media::Chapter::SeekToByIndex",
s => s.WithLabel("Chapter index"), index =>
{
var chapters = GetFirstChapters();
if (chapters?.ValidateIndex(index) == true)
SeekMediaToTime(chapters[index].StartPosition);
});

s.RegisterAction("Media::Chapter::SeekToNext", () =>
{
var chapters = GetFirstChapters();
var index = chapters.SearchForIndexAfter(MediaPosition + 1.5);
if (chapters?.ValidateIndex(index) == true)
SeekMediaToTime(chapters[index].StartPosition);
});

s.RegisterAction("Media::Chapter::SeekToPrev", () =>
{
var chapters = GetFirstChapters();
var index = chapters.SearchForIndexBefore(MediaPosition - 1.5);
if (chapters?.ValidateIndex(index) == true)
SeekMediaToTime(chapters[index].StartPosition);
});
#endregion

#region Script::SkipGap
s.RegisterAction<DeviceAxis, double>("Script::SkipGap",
s => s.WithLabel("Target").WithItemsSource(DeviceAxis.All).WithDescription("Target axis script to check for gaps\nEmpty to check all scripts"),
Expand Down

0 comments on commit 6b7a59f

Please sign in to comment.